mirror of
https://github.com/prometheus/node_exporter.git
synced 2025-01-01 00:47:30 -08:00
Merge pull request #363 from mdlayher/update-procfs
Update github.com/prometheus/procfs to latest revision
This commit is contained in:
commit
f09b9def25
|
@ -26,6 +26,7 @@ The following individuals have contributed code to this repository
|
||||||
* Jonas Große Sundrup <cherti@letopolis.de>
|
* Jonas Große Sundrup <cherti@letopolis.de>
|
||||||
* Julius Volz <julius.volz@gmail.com>
|
* Julius Volz <julius.volz@gmail.com>
|
||||||
* Ken Herner <ken@modulus.io>
|
* Ken Herner <ken@modulus.io>
|
||||||
|
* Matt Layher <mdlayher@gmail.com>
|
||||||
* Matthias Rampke <matthias@rampke.de>
|
* Matthias Rampke <matthias@rampke.de>
|
||||||
* Siavash Safi <siavash.safi@gmail.com>
|
* Siavash Safi <siavash.safi@gmail.com>
|
||||||
* Stephen Shirley <kormat@gmail.com>
|
* Stephen Shirley <kormat@gmail.com>
|
||||||
|
|
1
vendor/github.com/prometheus/procfs/AUTHORS.md
generated
vendored
1
vendor/github.com/prometheus/procfs/AUTHORS.md
generated
vendored
|
@ -14,6 +14,7 @@ The following individuals have contributed code to this repository
|
||||||
* Ji-Hoon, Seol <jihoon.seol@gmail.com>
|
* Ji-Hoon, Seol <jihoon.seol@gmail.com>
|
||||||
* Jonas Große Sundrup <cherti@letopolis.de>
|
* Jonas Große Sundrup <cherti@letopolis.de>
|
||||||
* Julius Volz <julius.volz@gmail.com>
|
* Julius Volz <julius.volz@gmail.com>
|
||||||
|
* Matt Layher <mdlayher@gmail.com>
|
||||||
* Matthias Rampke <mr@soundcloud.com>
|
* Matthias Rampke <mr@soundcloud.com>
|
||||||
* Nicky Gerritsen <nicky@streamone.nl>
|
* Nicky Gerritsen <nicky@streamone.nl>
|
||||||
* Rémi Audebert <contact@halfr.net>
|
* Rémi Audebert <contact@halfr.net>
|
||||||
|
|
552
vendor/github.com/prometheus/procfs/mountstats.go
generated
vendored
Normal file
552
vendor/github.com/prometheus/procfs/mountstats.go
generated
vendored
Normal file
|
@ -0,0 +1,552 @@
|
||||||
|
package procfs
|
||||||
|
|
||||||
|
// While implementing parsing of /proc/[pid]/mountstats, this blog was used
|
||||||
|
// heavily as a reference:
|
||||||
|
// https://utcc.utoronto.ca/~cks/space/blog/linux/NFSMountstatsIndex
|
||||||
|
//
|
||||||
|
// Special thanks to Chris Siebenmann for all of his posts explaining the
|
||||||
|
// various statistics available for NFS.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants shared between multiple functions.
|
||||||
|
const (
|
||||||
|
deviceEntryLen = 8
|
||||||
|
|
||||||
|
fieldBytesLen = 8
|
||||||
|
fieldEventsLen = 27
|
||||||
|
|
||||||
|
statVersion10 = "1.0"
|
||||||
|
statVersion11 = "1.1"
|
||||||
|
|
||||||
|
fieldTransport10Len = 10
|
||||||
|
fieldTransport11Len = 13
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Mount is a device mount parsed from /proc/[pid]/mountstats.
|
||||||
|
type Mount struct {
|
||||||
|
// Name of the device.
|
||||||
|
Device string
|
||||||
|
// The mount point of the device.
|
||||||
|
Mount string
|
||||||
|
// The filesystem type used by the device.
|
||||||
|
Type string
|
||||||
|
// If available additional statistics related to this Mount.
|
||||||
|
// Use a type assertion to determine if additional statistics are available.
|
||||||
|
Stats MountStats
|
||||||
|
}
|
||||||
|
|
||||||
|
// A MountStats is a type which contains detailed statistics for a specific
|
||||||
|
// type of Mount.
|
||||||
|
type MountStats interface {
|
||||||
|
mountStats()
|
||||||
|
}
|
||||||
|
|
||||||
|
// A MountStatsNFS is a MountStats implementation for NFSv3 and v4 mounts.
|
||||||
|
type MountStatsNFS struct {
|
||||||
|
// The version of statistics provided.
|
||||||
|
StatVersion string
|
||||||
|
// The age of the NFS mount.
|
||||||
|
Age time.Duration
|
||||||
|
// Statistics related to byte counters for various operations.
|
||||||
|
Bytes NFSBytesStats
|
||||||
|
// Statistics related to various NFS event occurrences.
|
||||||
|
Events NFSEventsStats
|
||||||
|
// Statistics broken down by filesystem operation.
|
||||||
|
Operations []NFSOperationStats
|
||||||
|
// Statistics about the NFS RPC transport.
|
||||||
|
Transport NFSTransportStats
|
||||||
|
}
|
||||||
|
|
||||||
|
// mountStats implements MountStats.
|
||||||
|
func (m MountStatsNFS) mountStats() {}
|
||||||
|
|
||||||
|
// A NFSBytesStats contains statistics about the number of bytes read and written
|
||||||
|
// by an NFS client to and from an NFS server.
|
||||||
|
type NFSBytesStats struct {
|
||||||
|
// Number of bytes read using the read() syscall.
|
||||||
|
Read int
|
||||||
|
// Number of bytes written using the write() syscall.
|
||||||
|
Write int
|
||||||
|
// Number of bytes read using the read() syscall in O_DIRECT mode.
|
||||||
|
DirectRead int
|
||||||
|
// Number of bytes written using the write() syscall in O_DIRECT mode.
|
||||||
|
DirectWrite int
|
||||||
|
// Number of bytes read from the NFS server, in total.
|
||||||
|
ReadTotal int
|
||||||
|
// Number of bytes written to the NFS server, in total.
|
||||||
|
WriteTotal int
|
||||||
|
// Number of pages read directly via mmap()'d files.
|
||||||
|
ReadPages int
|
||||||
|
// Number of pages written directly via mmap()'d files.
|
||||||
|
WritePages int
|
||||||
|
}
|
||||||
|
|
||||||
|
// A NFSEventsStats contains statistics about NFS event occurrences.
|
||||||
|
type NFSEventsStats struct {
|
||||||
|
// Number of times cached inode attributes are re-validated from the server.
|
||||||
|
InodeRevalidate int
|
||||||
|
// Number of times cached dentry nodes are re-validated from the server.
|
||||||
|
DnodeRevalidate int
|
||||||
|
// Number of times an inode cache is cleared.
|
||||||
|
DataInvalidate int
|
||||||
|
// Number of times cached inode attributes are invalidated.
|
||||||
|
AttributeInvalidate int
|
||||||
|
// Number of times files or directories have been open()'d.
|
||||||
|
VFSOpen int
|
||||||
|
// Number of times a directory lookup has occurred.
|
||||||
|
VFSLookup int
|
||||||
|
// Number of times permissions have been checked.
|
||||||
|
VFSAccess int
|
||||||
|
// Number of updates (and potential writes) to pages.
|
||||||
|
VFSUpdatePage int
|
||||||
|
// Number of pages read directly via mmap()'d files.
|
||||||
|
VFSReadPage int
|
||||||
|
// Number of times a group of pages have been read.
|
||||||
|
VFSReadPages int
|
||||||
|
// Number of pages written directly via mmap()'d files.
|
||||||
|
VFSWritePage int
|
||||||
|
// Number of times a group of pages have been written.
|
||||||
|
VFSWritePages int
|
||||||
|
// Number of times directory entries have been read with getdents().
|
||||||
|
VFSGetdents int
|
||||||
|
// Number of times attributes have been set on inodes.
|
||||||
|
VFSSetattr int
|
||||||
|
// Number of pending writes that have been forcefully flushed to the server.
|
||||||
|
VFSFlush int
|
||||||
|
// Number of times fsync() has been called on directories and files.
|
||||||
|
VFSFsync int
|
||||||
|
// Number of times locking has been attemped on a file.
|
||||||
|
VFSLock int
|
||||||
|
// Number of times files have been closed and released.
|
||||||
|
VFSFileRelease int
|
||||||
|
// Unknown. Possibly unused.
|
||||||
|
CongestionWait int
|
||||||
|
// Number of times files have been truncated.
|
||||||
|
Truncation int
|
||||||
|
// Number of times a file has been grown due to writes beyond its existing end.
|
||||||
|
WriteExtension int
|
||||||
|
// Number of times a file was removed while still open by another process.
|
||||||
|
SillyRename int
|
||||||
|
// Number of times the NFS server gave less data than expected while reading.
|
||||||
|
ShortRead int
|
||||||
|
// Number of times the NFS server wrote less data than expected while writing.
|
||||||
|
ShortWrite int
|
||||||
|
// Number of times the NFS server indicated EJUKEBOX; retrieving data from
|
||||||
|
// offline storage.
|
||||||
|
JukeboxDelay int
|
||||||
|
// Number of NFS v4.1+ pNFS reads.
|
||||||
|
PNFSRead int
|
||||||
|
// Number of NFS v4.1+ pNFS writes.
|
||||||
|
PNFSWrite int
|
||||||
|
}
|
||||||
|
|
||||||
|
// A NFSOperationStats contains statistics for a single operation.
|
||||||
|
type NFSOperationStats struct {
|
||||||
|
// The name of the operation.
|
||||||
|
Operation string
|
||||||
|
// Number of requests performed for this operation.
|
||||||
|
Requests int
|
||||||
|
// Number of times an actual RPC request has been transmitted for this operation.
|
||||||
|
Transmissions int
|
||||||
|
// Number of times a request has had a major timeout.
|
||||||
|
MajorTimeouts int
|
||||||
|
// Number of bytes sent for this operation, including RPC headers and payload.
|
||||||
|
BytesSent int
|
||||||
|
// Number of bytes received for this operation, including RPC headers and payload.
|
||||||
|
BytesReceived int
|
||||||
|
// Duration all requests spent queued for transmission before they were sent.
|
||||||
|
CumulativeQueueTime time.Duration
|
||||||
|
// Duration it took to get a reply back after the request was transmitted.
|
||||||
|
CumulativeTotalResponseTime time.Duration
|
||||||
|
// Duration from when a request was enqueued to when it was completely handled.
|
||||||
|
CumulativeTotalRequestTime time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
// A NFSTransportStats contains statistics for the NFS mount RPC requests and
|
||||||
|
// responses.
|
||||||
|
type NFSTransportStats struct {
|
||||||
|
// The local port used for the NFS mount.
|
||||||
|
Port int
|
||||||
|
// Number of times the client has had to establish a connection from scratch
|
||||||
|
// to the NFS server.
|
||||||
|
Bind int
|
||||||
|
// Number of times the client has made a TCP connection to the NFS server.
|
||||||
|
Connect int
|
||||||
|
// Duration (in jiffies, a kernel internal unit of time) the NFS mount has
|
||||||
|
// spent waiting for connections to the server to be established.
|
||||||
|
ConnectIdleTime int
|
||||||
|
// Duration since the NFS mount last saw any RPC traffic.
|
||||||
|
IdleTime time.Duration
|
||||||
|
// Number of RPC requests for this mount sent to the NFS server.
|
||||||
|
Sends int
|
||||||
|
// Number of RPC responses for this mount received from the NFS server.
|
||||||
|
Receives int
|
||||||
|
// Number of times the NFS server sent a response with a transaction ID
|
||||||
|
// unknown to this client.
|
||||||
|
BadTransactionIDs int
|
||||||
|
// A running counter, incremented on each request as the current difference
|
||||||
|
// ebetween sends and receives.
|
||||||
|
CumulativeActiveRequests int
|
||||||
|
// A running counter, incremented on each request by the current backlog
|
||||||
|
// queue size.
|
||||||
|
CumulativeBacklog int
|
||||||
|
|
||||||
|
// Stats below only available with stat version 1.1.
|
||||||
|
|
||||||
|
// Maximum number of simultaneously active RPC requests ever used.
|
||||||
|
MaximumRPCSlotsUsed int
|
||||||
|
// A running counter, incremented on each request as the current size of the
|
||||||
|
// sending queue.
|
||||||
|
CumulativeSendingQueue int
|
||||||
|
// A running counter, incremented on each request as the current size of the
|
||||||
|
// pending queue.
|
||||||
|
CumulativePendingQueue int
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseMountStats parses a /proc/[pid]/mountstats file and returns a slice
|
||||||
|
// of Mount structures containing detailed information about each mount.
|
||||||
|
// If available, statistics for each mount are parsed as well.
|
||||||
|
func parseMountStats(r io.Reader) ([]*Mount, error) {
|
||||||
|
const (
|
||||||
|
device = "device"
|
||||||
|
statVersionPrefix = "statvers="
|
||||||
|
|
||||||
|
nfs3Type = "nfs"
|
||||||
|
nfs4Type = "nfs4"
|
||||||
|
)
|
||||||
|
|
||||||
|
var mounts []*Mount
|
||||||
|
|
||||||
|
s := bufio.NewScanner(r)
|
||||||
|
for s.Scan() {
|
||||||
|
// Only look for device entries in this function
|
||||||
|
ss := strings.Fields(string(s.Bytes()))
|
||||||
|
if len(ss) == 0 || ss[0] != device {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
m, err := parseMount(ss)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Does this mount also possess statistics information?
|
||||||
|
if len(ss) > deviceEntryLen {
|
||||||
|
// Only NFSv3 and v4 are supported for parsing statistics
|
||||||
|
if m.Type != nfs3Type && m.Type != nfs4Type {
|
||||||
|
return nil, fmt.Errorf("cannot parse MountStats for fstype %q", m.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
statVersion := strings.TrimPrefix(ss[8], statVersionPrefix)
|
||||||
|
|
||||||
|
stats, err := parseMountStatsNFS(s, statVersion)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
m.Stats = stats
|
||||||
|
}
|
||||||
|
|
||||||
|
mounts = append(mounts, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
return mounts, s.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseMount parses an entry in /proc/[pid]/mountstats in the format:
|
||||||
|
// device [device] mounted on [mount] with fstype [type]
|
||||||
|
func parseMount(ss []string) (*Mount, error) {
|
||||||
|
if len(ss) < deviceEntryLen {
|
||||||
|
return nil, fmt.Errorf("invalid device entry: %v", ss)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for specific words appearing at specific indices to ensure
|
||||||
|
// the format is consistent with what we expect
|
||||||
|
format := []struct {
|
||||||
|
i int
|
||||||
|
s string
|
||||||
|
}{
|
||||||
|
{i: 0, s: "device"},
|
||||||
|
{i: 2, s: "mounted"},
|
||||||
|
{i: 3, s: "on"},
|
||||||
|
{i: 5, s: "with"},
|
||||||
|
{i: 6, s: "fstype"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range format {
|
||||||
|
if ss[f.i] != f.s {
|
||||||
|
return nil, fmt.Errorf("invalid device entry: %v", ss)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Mount{
|
||||||
|
Device: ss[1],
|
||||||
|
Mount: ss[4],
|
||||||
|
Type: ss[7],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseMountStatsNFS parses a MountStatsNFS by scanning additional information
|
||||||
|
// related to NFS statistics.
|
||||||
|
func parseMountStatsNFS(s *bufio.Scanner, statVersion string) (*MountStatsNFS, error) {
|
||||||
|
// Field indicators for parsing specific types of data
|
||||||
|
const (
|
||||||
|
fieldAge = "age:"
|
||||||
|
fieldBytes = "bytes:"
|
||||||
|
fieldEvents = "events:"
|
||||||
|
fieldPerOpStats = "per-op"
|
||||||
|
fieldTransport = "xprt:"
|
||||||
|
)
|
||||||
|
|
||||||
|
stats := &MountStatsNFS{
|
||||||
|
StatVersion: statVersion,
|
||||||
|
}
|
||||||
|
|
||||||
|
for s.Scan() {
|
||||||
|
ss := strings.Fields(string(s.Bytes()))
|
||||||
|
if len(ss) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if len(ss) < 2 {
|
||||||
|
return nil, fmt.Errorf("not enough information for NFS stats: %v", ss)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ss[0] {
|
||||||
|
case fieldAge:
|
||||||
|
// Age integer is in seconds
|
||||||
|
d, err := time.ParseDuration(ss[1] + "s")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
stats.Age = d
|
||||||
|
case fieldBytes:
|
||||||
|
bstats, err := parseNFSBytesStats(ss[1:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
stats.Bytes = *bstats
|
||||||
|
case fieldEvents:
|
||||||
|
estats, err := parseNFSEventsStats(ss[1:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
stats.Events = *estats
|
||||||
|
case fieldTransport:
|
||||||
|
if len(ss) < 3 {
|
||||||
|
return nil, fmt.Errorf("not enough information for NFS transport stats: %v", ss)
|
||||||
|
}
|
||||||
|
|
||||||
|
tstats, err := parseNFSTransportStats(ss[2:], statVersion)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
stats.Transport = *tstats
|
||||||
|
}
|
||||||
|
|
||||||
|
// When encountering "per-operation statistics", we must break this
|
||||||
|
// loop and parse them seperately to ensure we can terminate parsing
|
||||||
|
// before reaching another device entry; hence why this 'if' statement
|
||||||
|
// is not just another switch case
|
||||||
|
if ss[0] == fieldPerOpStats {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// NFS per-operation stats appear last before the next device entry
|
||||||
|
perOpStats, err := parseNFSOperationStats(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
stats.Operations = perOpStats
|
||||||
|
|
||||||
|
return stats, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseNFSBytesStats parses a NFSBytesStats line using an input set of
|
||||||
|
// integer fields.
|
||||||
|
func parseNFSBytesStats(ss []string) (*NFSBytesStats, error) {
|
||||||
|
if len(ss) != fieldBytesLen {
|
||||||
|
return nil, fmt.Errorf("invalid NFS bytes stats: %v", ss)
|
||||||
|
}
|
||||||
|
|
||||||
|
ns := make([]int, 0, fieldBytesLen)
|
||||||
|
for _, s := range ss {
|
||||||
|
n, err := strconv.Atoi(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ns = append(ns, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &NFSBytesStats{
|
||||||
|
Read: ns[0],
|
||||||
|
Write: ns[1],
|
||||||
|
DirectRead: ns[2],
|
||||||
|
DirectWrite: ns[3],
|
||||||
|
ReadTotal: ns[4],
|
||||||
|
WriteTotal: ns[5],
|
||||||
|
ReadPages: ns[6],
|
||||||
|
WritePages: ns[7],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseNFSEventsStats parses a NFSEventsStats line using an input set of
|
||||||
|
// integer fields.
|
||||||
|
func parseNFSEventsStats(ss []string) (*NFSEventsStats, error) {
|
||||||
|
if len(ss) != fieldEventsLen {
|
||||||
|
return nil, fmt.Errorf("invalid NFS events stats: %v", ss)
|
||||||
|
}
|
||||||
|
|
||||||
|
ns := make([]int, 0, fieldEventsLen)
|
||||||
|
for _, s := range ss {
|
||||||
|
n, err := strconv.Atoi(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ns = append(ns, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &NFSEventsStats{
|
||||||
|
InodeRevalidate: ns[0],
|
||||||
|
DnodeRevalidate: ns[1],
|
||||||
|
DataInvalidate: ns[2],
|
||||||
|
AttributeInvalidate: ns[3],
|
||||||
|
VFSOpen: ns[4],
|
||||||
|
VFSLookup: ns[5],
|
||||||
|
VFSAccess: ns[6],
|
||||||
|
VFSUpdatePage: ns[7],
|
||||||
|
VFSReadPage: ns[8],
|
||||||
|
VFSReadPages: ns[9],
|
||||||
|
VFSWritePage: ns[10],
|
||||||
|
VFSWritePages: ns[11],
|
||||||
|
VFSGetdents: ns[12],
|
||||||
|
VFSSetattr: ns[13],
|
||||||
|
VFSFlush: ns[14],
|
||||||
|
VFSFsync: ns[15],
|
||||||
|
VFSLock: ns[16],
|
||||||
|
VFSFileRelease: ns[17],
|
||||||
|
CongestionWait: ns[18],
|
||||||
|
Truncation: ns[19],
|
||||||
|
WriteExtension: ns[20],
|
||||||
|
SillyRename: ns[21],
|
||||||
|
ShortRead: ns[22],
|
||||||
|
ShortWrite: ns[23],
|
||||||
|
JukeboxDelay: ns[24],
|
||||||
|
PNFSRead: ns[25],
|
||||||
|
PNFSWrite: ns[26],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseNFSOperationStats parses a slice of NFSOperationStats by scanning
|
||||||
|
// additional information about per-operation statistics until an empty
|
||||||
|
// line is reached.
|
||||||
|
func parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) {
|
||||||
|
const (
|
||||||
|
// Number of expected fields in each per-operation statistics set
|
||||||
|
numFields = 9
|
||||||
|
)
|
||||||
|
|
||||||
|
var ops []NFSOperationStats
|
||||||
|
|
||||||
|
for s.Scan() {
|
||||||
|
ss := strings.Fields(string(s.Bytes()))
|
||||||
|
if len(ss) == 0 {
|
||||||
|
// Must break when reading a blank line after per-operation stats to
|
||||||
|
// enable top-level function to parse the next device entry
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ss) != numFields {
|
||||||
|
return nil, fmt.Errorf("invalid NFS per-operations stats: %v", ss)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip string operation name for integers
|
||||||
|
ns := make([]int, 0, numFields-1)
|
||||||
|
for _, st := range ss[1:] {
|
||||||
|
n, err := strconv.Atoi(st)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ns = append(ns, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
ops = append(ops, NFSOperationStats{
|
||||||
|
Operation: strings.TrimSuffix(ss[0], ":"),
|
||||||
|
Requests: ns[0],
|
||||||
|
Transmissions: ns[1],
|
||||||
|
MajorTimeouts: ns[2],
|
||||||
|
BytesSent: ns[3],
|
||||||
|
BytesReceived: ns[4],
|
||||||
|
CumulativeQueueTime: time.Duration(ns[5]) * time.Millisecond,
|
||||||
|
CumulativeTotalResponseTime: time.Duration(ns[6]) * time.Millisecond,
|
||||||
|
CumulativeTotalRequestTime: time.Duration(ns[7]) * time.Millisecond,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return ops, s.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseNFSTransportStats parses a NFSTransportStats line using an input set of
|
||||||
|
// integer fields matched to a specific stats version.
|
||||||
|
func parseNFSTransportStats(ss []string, statVersion string) (*NFSTransportStats, error) {
|
||||||
|
switch statVersion {
|
||||||
|
case statVersion10:
|
||||||
|
if len(ss) != fieldTransport10Len {
|
||||||
|
return nil, fmt.Errorf("invalid NFS transport stats 1.0 statement: %v", ss)
|
||||||
|
}
|
||||||
|
case statVersion11:
|
||||||
|
if len(ss) != fieldTransport11Len {
|
||||||
|
return nil, fmt.Errorf("invalid NFS transport stats 1.1 statement: %v", ss)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unrecognized NFS transport stats version: %q", statVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate enough for v1.1 stats since zero value for v1.1 stats will be okay
|
||||||
|
// in a v1.0 response
|
||||||
|
ns := make([]int, 0, fieldTransport11Len)
|
||||||
|
for _, s := range ss {
|
||||||
|
n, err := strconv.Atoi(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ns = append(ns, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &NFSTransportStats{
|
||||||
|
Port: ns[0],
|
||||||
|
Bind: ns[1],
|
||||||
|
Connect: ns[2],
|
||||||
|
ConnectIdleTime: ns[3],
|
||||||
|
IdleTime: time.Duration(ns[4]) * time.Second,
|
||||||
|
Sends: ns[5],
|
||||||
|
Receives: ns[6],
|
||||||
|
BadTransactionIDs: ns[7],
|
||||||
|
CumulativeActiveRequests: ns[8],
|
||||||
|
CumulativeBacklog: ns[9],
|
||||||
|
MaximumRPCSlotsUsed: ns[10],
|
||||||
|
CumulativeSendingQueue: ns[11],
|
||||||
|
CumulativePendingQueue: ns[12],
|
||||||
|
}, nil
|
||||||
|
}
|
16
vendor/github.com/prometheus/procfs/proc.go
generated
vendored
16
vendor/github.com/prometheus/procfs/proc.go
generated
vendored
|
@ -41,7 +41,7 @@ func NewProc(pid int) (Proc, error) {
|
||||||
return fs.NewProc(pid)
|
return fs.NewProc(pid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AllProcs returns a list of all currently avaible processes under /proc.
|
// AllProcs returns a list of all currently available processes under /proc.
|
||||||
func AllProcs() (Procs, error) {
|
func AllProcs() (Procs, error) {
|
||||||
fs, err := NewFS(DefaultMountPoint)
|
fs, err := NewFS(DefaultMountPoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -71,7 +71,7 @@ func (fs FS) NewProc(pid int) (Proc, error) {
|
||||||
return Proc{PID: pid, fs: fs}, nil
|
return Proc{PID: pid, fs: fs}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AllProcs returns a list of all currently avaible processes.
|
// AllProcs returns a list of all currently available processes.
|
||||||
func (fs FS) AllProcs() (Procs, error) {
|
func (fs FS) AllProcs() (Procs, error) {
|
||||||
d, err := os.Open(fs.Path())
|
d, err := os.Open(fs.Path())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -192,6 +192,18 @@ func (p Proc) FileDescriptorsLen() (int, error) {
|
||||||
return len(fds), nil
|
return len(fds), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MountStats retrieves statistics and configuration for mount points in a
|
||||||
|
// process's namespace.
|
||||||
|
func (p Proc) MountStats() ([]*Mount, error) {
|
||||||
|
f, err := os.Open(p.path("mountstats"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
return parseMountStats(f)
|
||||||
|
}
|
||||||
|
|
||||||
func (p Proc) fileDescriptors() ([]string, error) {
|
func (p Proc) fileDescriptors() ([]string, error) {
|
||||||
d, err := os.Open(p.path("fd"))
|
d, err := os.Open(p.path("fd"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
2
vendor/github.com/prometheus/procfs/proc_limits.go
generated
vendored
2
vendor/github.com/prometheus/procfs/proc_limits.go
generated
vendored
|
@ -87,7 +87,7 @@ func (p Proc) NewLimits() (ProcLimits, error) {
|
||||||
case "Max cpu time":
|
case "Max cpu time":
|
||||||
l.CPUTime, err = parseInt(fields[1])
|
l.CPUTime, err = parseInt(fields[1])
|
||||||
case "Max file size":
|
case "Max file size":
|
||||||
l.FileLocks, err = parseInt(fields[1])
|
l.FileSize, err = parseInt(fields[1])
|
||||||
case "Max data size":
|
case "Max data size":
|
||||||
l.DataSize, err = parseInt(fields[1])
|
l.DataSize, err = parseInt(fields[1])
|
||||||
case "Max stack size":
|
case "Max stack size":
|
||||||
|
|
5
vendor/vendor.json
vendored
5
vendor/vendor.json
vendored
|
@ -80,9 +80,10 @@
|
||||||
"revisionTime": "2016-05-03T22:05:32Z"
|
"revisionTime": "2016-05-03T22:05:32Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"checksumSHA1": "L+p4t3KrLDAKJnrreOz2BZIt9Mg=",
|
||||||
"path": "github.com/prometheus/procfs",
|
"path": "github.com/prometheus/procfs",
|
||||||
"revision": "406e5b7bfd8201a36e2bb5f7bdae0b03380c2ce8",
|
"revision": "fcdb11ccb4389efb1b210b7ffb623ab71c5fdd60",
|
||||||
"revisionTime": "2015-10-29T15:50:50-04:00"
|
"revisionTime": "2016-12-06T22:21:41Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "github.com/soundcloud/go-runit/runit",
|
"path": "github.com/soundcloud/go-runit/runit",
|
||||||
|
|
Loading…
Reference in a new issue