mirror of
https://github.com/nshttpd/mikrotik-exporter.git
synced 2024-11-25 11:46:36 +01:00
News features and improvements (#8)
* added config file implementation, refactoring * add gitignore * improved test * preperations for more metrics * added resource metrics * added first bgp metrics * added asn as label for bgp metrics * added prefix and message counts to bgp metrics * simplified * Update README.md * added yaml dependency * fixed go routine call * added timeout * clean up * added TLS support * set default api port for TLS * added routes metric * added missing log information
This commit is contained in:
parent
c37abb638f
commit
f2866a3a2f
22
.gitignore
vendored
Normal file
22
.gitignore
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Binaries for programs and plugins
|
||||||
|
*.exe
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Test binary, build with `go test -c`
|
||||||
|
*.test
|
||||||
|
|
||||||
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
|
*.out
|
||||||
|
|
||||||
|
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
|
||||||
|
.glide/
|
||||||
|
|
||||||
|
# IDE specific files
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
.vscode
|
||||||
|
debug
|
||||||
|
|
||||||
|
mikrotik-exporter
|
54
Gopkg.lock
generated
54
Gopkg.lock
generated
@ -8,10 +8,10 @@
|
|||||||
revision = "4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9"
|
revision = "4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
|
||||||
name = "github.com/golang/protobuf"
|
name = "github.com/golang/protobuf"
|
||||||
packages = ["proto"]
|
packages = ["proto"]
|
||||||
revision = "1e59b77b52bf8e4b449a57e6f79f21226d571845"
|
revision = "925541529c1fa6821df4e44ce2723319eb2be768"
|
||||||
|
version = "v1.0.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/matttproud/golang_protobuf_extensions"
|
name = "github.com/matttproud/golang_protobuf_extensions"
|
||||||
@ -21,7 +21,10 @@
|
|||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/prometheus/client_golang"
|
name = "github.com/prometheus/client_golang"
|
||||||
packages = ["prometheus","prometheus/promhttp"]
|
packages = [
|
||||||
|
"prometheus",
|
||||||
|
"prometheus/promhttp"
|
||||||
|
]
|
||||||
revision = "c5b7fccd204277076155f10851dad72b76a49317"
|
revision = "c5b7fccd204277076155f10851dad72b76a49317"
|
||||||
version = "v0.8.0"
|
version = "v0.8.0"
|
||||||
|
|
||||||
@ -34,41 +37,64 @@
|
|||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/prometheus/common"
|
name = "github.com/prometheus/common"
|
||||||
packages = ["expfmt","internal/bitbucket.org/ww/goautoneg","model","version"]
|
packages = [
|
||||||
revision = "2e54d0b93cba2fd133edc32211dcc32c06ef72ca"
|
"expfmt",
|
||||||
|
"internal/bitbucket.org/ww/goautoneg",
|
||||||
|
"model",
|
||||||
|
"version"
|
||||||
|
]
|
||||||
|
revision = "e4aa40a9169a88835b849a6efb71e05dc04b88f0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/prometheus/procfs"
|
name = "github.com/prometheus/procfs"
|
||||||
packages = [".","xfs"]
|
packages = [
|
||||||
revision = "a6e9df898b1336106c743392c48ee0b71f5c4efa"
|
".",
|
||||||
|
"internal/util",
|
||||||
|
"nfs",
|
||||||
|
"xfs"
|
||||||
|
]
|
||||||
|
revision = "54d17b57dd7d4a3aa092476596b3f8a933bde349"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/sirupsen/logrus"
|
name = "github.com/sirupsen/logrus"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "89742aefa4b206dcf400792f3bd35b542998eb3b"
|
revision = "c155da19408a8799da419ed3eeb0cb5db0ad5dbc"
|
||||||
|
version = "v1.0.5"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "golang.org/x/crypto"
|
name = "golang.org/x/crypto"
|
||||||
packages = ["ssh/terminal"]
|
packages = ["ssh/terminal"]
|
||||||
revision = "94eea52f7b742c7cbe0b03b22f0c4c8631ece122"
|
revision = "c3a3ad6d03f7a915c0f7e194b7152974bb73d287"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "golang.org/x/sys"
|
name = "golang.org/x/sys"
|
||||||
packages = ["unix","windows"]
|
packages = [
|
||||||
revision = "13fcbd661c8ececa8807a29b48407d674b1d8ed8"
|
"unix",
|
||||||
|
"windows"
|
||||||
|
]
|
||||||
|
revision = "d8e400bc7db4870d786864138af681469693d18c"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "v2"
|
branch = "v2"
|
||||||
name = "gopkg.in/routeros.v2"
|
name = "gopkg.in/routeros.v2"
|
||||||
packages = [".","proto"]
|
packages = [
|
||||||
revision = "ffdb88bba0376a797b733f2279f539340926617f"
|
".",
|
||||||
|
"proto"
|
||||||
|
]
|
||||||
|
revision = "2dc19c12445caefdc2d128f7331dcc83284211ef"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "gopkg.in/yaml.v2"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "7f97868eec74b32b0982dd158a51a446d1da7eb5"
|
||||||
|
version = "v2.1.1"
|
||||||
|
|
||||||
[solve-meta]
|
[solve-meta]
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
analyzer-version = 1
|
analyzer-version = 1
|
||||||
inputs-digest = "a22b2a88c709e97dfa267610f7b2209353fbc37627effb3cfc9864a1f0892f09"
|
inputs-digest = "ff563df52a1af77a9de6d6c3bd29b66cac02221b5d9357d63f32e8503399d301"
|
||||||
solver-name = "gps-cdcl"
|
solver-name = "gps-cdcl"
|
||||||
solver-version = 1
|
solver-version = 1
|
||||||
|
21
README.md
21
README.md
@ -35,6 +35,25 @@ where `address` is the address of your router. `device` is the label name for th
|
|||||||
in the metrics output to prometheus. The `user` and `password` are the ones you
|
in the metrics output to prometheus. The `user` and `password` are the ones you
|
||||||
created for the exporter to use to access the API.
|
created for the exporter to use to access the API.
|
||||||
|
|
||||||
|
#### Config File
|
||||||
|
|
||||||
|
`./mikrotik-exporter -config-file config.yml`
|
||||||
|
|
||||||
|
where `config-file` is the path to a config file in YAML format.
|
||||||
|
|
||||||
|
###### example config
|
||||||
|
```
|
||||||
|
devices:
|
||||||
|
- name: my_router
|
||||||
|
address: 10.10.0.1
|
||||||
|
user: prometheus
|
||||||
|
password: changeme
|
||||||
|
- name: my_second_router
|
||||||
|
address: 10.10.0.2
|
||||||
|
user: prometheus2
|
||||||
|
password: password_to_second_router
|
||||||
|
```
|
||||||
|
|
||||||
###### example output
|
###### example output
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -47,4 +66,4 @@ mikrotik_interface_tx_byte{address="10.10.0.1",interface="ether7",name="my_route
|
|||||||
mikrotik_interface_tx_byte{address="10.10.0.1",interface="ether8",name="my_router"} 1.86405031e+08
|
mikrotik_interface_tx_byte{address="10.10.0.1",interface="ether8",name="my_router"} 1.86405031e+08
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
112
collector/bgp_collector.go
Normal file
112
collector/bgp_collector.go
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
package collector
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/nshttpd/mikrotik-exporter/config"
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
routeros "gopkg.in/routeros.v2"
|
||||||
|
"gopkg.in/routeros.v2/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
bgpabelNames = []string{"name", "address", "session", "asn"}
|
||||||
|
bgpProps = []string{"name", "remote-as", "state", "prefix-count", "updates-sent", "updates-received", "withdrawn-sent", "withdrawn-received"}
|
||||||
|
bgpDescriptions map[string]*prometheus.Desc
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
bgpDescriptions = make(map[string]*prometheus.Desc)
|
||||||
|
bgpDescriptions["state"] = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(namespace, "bgp", "up"),
|
||||||
|
"BGP session is established (up = 1)",
|
||||||
|
bgpabelNames,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
for _, p := range bgpProps[3:] {
|
||||||
|
bgpDescriptions[p] = descriptionForPropertyName("bgp", p, bgpabelNames)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type bgpCollector struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *bgpCollector) describe(ch chan<- *prometheus.Desc) {
|
||||||
|
for _, d := range bgpDescriptions {
|
||||||
|
ch <- d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *bgpCollector) collect(ch chan<- prometheus.Metric, device *config.Device, client *routeros.Client) error {
|
||||||
|
stats, err := c.fetch(client, device)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, re := range stats {
|
||||||
|
c.collectForStat(re, device, ch)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *bgpCollector) fetch(client *routeros.Client, device *config.Device) ([]*proto.Sentence, error) {
|
||||||
|
reply, err := client.Run("/routing/bgp/peer/print", "=.proplist="+strings.Join(bgpProps, ","))
|
||||||
|
if err != nil {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"device": device.Name,
|
||||||
|
"error": err,
|
||||||
|
}).Error("error fetching bgp metrics")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return reply.Re, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *bgpCollector) collectForStat(re *proto.Sentence, device *config.Device, ch chan<- prometheus.Metric) {
|
||||||
|
var session, asn string
|
||||||
|
for _, p := range bgpProps {
|
||||||
|
if p == "name" {
|
||||||
|
session = re.Map[p]
|
||||||
|
} else if p == "remote-as" {
|
||||||
|
asn = re.Map[p]
|
||||||
|
} else {
|
||||||
|
c.collectMetricForProperty(p, session, asn, device, re, ch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *bgpCollector) collectMetricForProperty(property, session, asn string, device *config.Device, re *proto.Sentence, ch chan<- prometheus.Metric) {
|
||||||
|
desc := bgpDescriptions[property]
|
||||||
|
v, err := c.parseValueForProperty(property, re.Map[property])
|
||||||
|
if err != nil {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"device": device.Name,
|
||||||
|
"session": session,
|
||||||
|
"property": property,
|
||||||
|
"value": re.Map[property],
|
||||||
|
"error": err,
|
||||||
|
}).Error("error parsing bgp metric value")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, v, device.Name, device.Address, session, asn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *bgpCollector) parseValueForProperty(property, value string) (float64, error) {
|
||||||
|
if property == "state" {
|
||||||
|
if value == "established" {
|
||||||
|
return 1, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if value == "" {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return strconv.ParseFloat(value, 64)
|
||||||
|
}
|
@ -1,14 +1,24 @@
|
|||||||
package collector
|
package collector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/nshttpd/mikrotik-exporter/config"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
routeros "gopkg.in/routeros.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const namespace = "mikrotik"
|
const (
|
||||||
|
namespace = "mikrotik"
|
||||||
|
apiPort = ":8728"
|
||||||
|
apiPortTLS = ":8729"
|
||||||
|
|
||||||
|
// DefaultTimeout defines the default timeout when connecting to a router
|
||||||
|
DefaultTimeout = 5 * time.Second
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
scrapeDurationDesc = prometheus.NewDesc(
|
scrapeDurationDesc = prometheus.NewDesc(
|
||||||
@ -25,54 +35,140 @@ var (
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
type deviceCollector struct {
|
type collector struct {
|
||||||
Devices []Device
|
devices []config.Device
|
||||||
|
collectors []metricCollector
|
||||||
|
timeout time.Duration
|
||||||
|
enableTLS bool
|
||||||
|
insecureTLS bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDeviceCollector(cfg Config) (*deviceCollector, error) {
|
// WithBGP enables BGP routing metrics
|
||||||
devices := make([]Device, len(cfg.Devices))
|
func WithBGP() Option {
|
||||||
|
return func(c *collector) {
|
||||||
|
c.collectors = append(c.collectors, &bgpCollector{})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithRoutes enables routing table metrics
|
||||||
|
func WithRoutes() Option {
|
||||||
|
return func(c *collector) {
|
||||||
|
c.collectors = append(c.collectors, &routesCollector{})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithTimeout sets timeout for connecting to router
|
||||||
|
func WithTimeout(d time.Duration) Option {
|
||||||
|
return func(c *collector) {
|
||||||
|
c.timeout = d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithTLS enables TLS
|
||||||
|
func WithTLS(insecure bool) Option {
|
||||||
|
return func(c *collector) {
|
||||||
|
c.enableTLS = true
|
||||||
|
c.insecureTLS = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Option applies options to collector
|
||||||
|
type Option func(*collector)
|
||||||
|
|
||||||
|
// NewCollector creates a collector instance
|
||||||
|
func NewCollector(cfg *config.Config, opts ...Option) (prometheus.Collector, error) {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"numDevices": len(cfg.Devices),
|
"numDevices": len(cfg.Devices),
|
||||||
}).Info("setting up collector for devices")
|
}).Info("setting up collector for devices")
|
||||||
|
|
||||||
copy(devices, cfg.Devices)
|
c := &collector{
|
||||||
|
devices: cfg.Devices,
|
||||||
|
timeout: DefaultTimeout,
|
||||||
|
collectors: []metricCollector{
|
||||||
|
&interfaceCollector{},
|
||||||
|
&resourceCollector{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
return &deviceCollector{Devices: devices}, nil
|
for _, o := range opts {
|
||||||
|
o(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Describe implements the prometheus.Collector interface.
|
// Describe implements the prometheus.Collector interface.
|
||||||
func (d deviceCollector) Describe(ch chan<- *prometheus.Desc) {
|
func (c *collector) Describe(ch chan<- *prometheus.Desc) {
|
||||||
ch <- scrapeDurationDesc
|
ch <- scrapeDurationDesc
|
||||||
ch <- scrapeSuccessDesc
|
ch <- scrapeSuccessDesc
|
||||||
|
|
||||||
|
for _, co := range c.collectors {
|
||||||
|
co.describe(ch)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect implements the prometheus.Collector interface.
|
// Collect implements the prometheus.Collector interface.
|
||||||
func (d deviceCollector) Collect(ch chan<- prometheus.Metric) {
|
func (c *collector) Collect(ch chan<- prometheus.Metric) {
|
||||||
wg := sync.WaitGroup{}
|
wg := sync.WaitGroup{}
|
||||||
wg.Add(len(d.Devices))
|
wg.Add(len(c.devices))
|
||||||
for _, device := range d.Devices {
|
|
||||||
go func(d Device) {
|
for _, dev := range c.devices {
|
||||||
execute(d, ch)
|
go func(d config.Device) {
|
||||||
|
c.collectForDevice(d, ch)
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}(device)
|
}(dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
func execute(d Device, ch chan<- prometheus.Metric) {
|
func (c *collector) collectForDevice(d config.Device, ch chan<- prometheus.Metric) {
|
||||||
begin := time.Now()
|
begin := time.Now()
|
||||||
err := d.Update(ch)
|
|
||||||
|
err := c.connectAndCollect(&d, ch)
|
||||||
|
|
||||||
duration := time.Since(begin)
|
duration := time.Since(begin)
|
||||||
var success float64
|
var success float64
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("ERROR: %s collector failed after %fs: %s", d.name, duration.Seconds(), err)
|
log.Errorf("ERROR: %s collector failed after %fs: %s", d.Name, duration.Seconds(), err)
|
||||||
success = 0
|
success = 0
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("OK: %s collector succeeded after %fs.", d.name, duration.Seconds())
|
log.Debugf("OK: %s collector succeeded after %fs.", d.Name, duration.Seconds())
|
||||||
success = 1
|
success = 1
|
||||||
}
|
}
|
||||||
ch <- prometheus.MustNewConstMetric(scrapeDurationDesc, prometheus.GaugeValue, duration.Seconds(), d.name)
|
|
||||||
ch <- prometheus.MustNewConstMetric(scrapeSuccessDesc, prometheus.GaugeValue, success, d.name)
|
ch <- prometheus.MustNewConstMetric(scrapeDurationDesc, prometheus.GaugeValue, duration.Seconds(), d.Name)
|
||||||
|
ch <- prometheus.MustNewConstMetric(scrapeSuccessDesc, prometheus.GaugeValue, success, d.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *collector) connectAndCollect(d *config.Device, ch chan<- prometheus.Metric) error {
|
||||||
|
cl, err := c.connect(d)
|
||||||
|
if err != nil {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"device": d.Name,
|
||||||
|
"error": err,
|
||||||
|
}).Error("error dialing device")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer cl.Close()
|
||||||
|
|
||||||
|
for _, co := range c.collectors {
|
||||||
|
err = co.collect(ch, d, cl)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *collector) connect(d *config.Device) (*routeros.Client, error) {
|
||||||
|
if !c.enableTLS {
|
||||||
|
return routeros.DialTimeout(d.Address+apiPort, d.User, d.Password, c.timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
tls := &tls.Config{
|
||||||
|
InsecureSkipVerify: c.insecureTLS,
|
||||||
|
}
|
||||||
|
return routeros.DialTLSTimeout(d.Address+apiPortTLS, d.User, d.Password, tls, c.timeout)
|
||||||
}
|
}
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
package collector
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
Devices []Device
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Config) FromFlags(device, address, user, password *string) error {
|
|
||||||
if *device == "" || *address == "" || *user == "" || *password == "" {
|
|
||||||
return fmt.Errorf("missing required param for single device configuration")
|
|
||||||
}
|
|
||||||
|
|
||||||
d := &Device{
|
|
||||||
address: *address,
|
|
||||||
name: *device,
|
|
||||||
user: *user,
|
|
||||||
password: *password,
|
|
||||||
iDesc: map[string]*prometheus.Desc{},
|
|
||||||
rDesc: map[string]*prometheus.Desc{},
|
|
||||||
}
|
|
||||||
|
|
||||||
*c = Config{
|
|
||||||
Devices: []Device{*d},
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
|
|
||||||
}
|
|
@ -1,108 +0,0 @@
|
|||||||
package collector
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"gopkg.in/routeros.v2"
|
|
||||||
"gopkg.in/routeros.v2/proto"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
apiPort = ":8728"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
interfaceLabelNames = []string{"name", "address", "interface"}
|
|
||||||
InterfaceProps = []string{"name", "rx-byte", "tx-byte", "rx-packet", "tx-packet", "rx-error", "tx-error", "rx-drop", "tx-drop"}
|
|
||||||
resourceLabelNames = []string{"name", "address"}
|
|
||||||
ResourceProps = []string{"free-memory", "total-memory", "cpu-load", "free-hdd-space", "total-hdd-space"}
|
|
||||||
)
|
|
||||||
|
|
||||||
type Device struct {
|
|
||||||
address string
|
|
||||||
name string
|
|
||||||
user string
|
|
||||||
password string
|
|
||||||
iDesc map[string]*prometheus.Desc // interface level descriptions for device
|
|
||||||
rDesc map[string]*prometheus.Desc // resource level descriptions for device
|
|
||||||
}
|
|
||||||
|
|
||||||
func metricStringCleanup(in string) string {
|
|
||||||
return strings.Replace(in, "-", "_", -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) fetchInterfaceMetrics() ([]*proto.Sentence, error) {
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"device": d.name,
|
|
||||||
}).Debug("fetching interface metrics")
|
|
||||||
|
|
||||||
// grab a connection to the device
|
|
||||||
c, err := routeros.Dial(d.address+apiPort, d.user, d.password)
|
|
||||||
if err != nil {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"device": d.name,
|
|
||||||
"error": err,
|
|
||||||
}).Error("error dialing device")
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
reply, err := c.Run("/interface/print", "?disabled=false",
|
|
||||||
"?running=true", "=.proplist="+strings.Join(InterfaceProps, ","))
|
|
||||||
if err != nil {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"device": d.name,
|
|
||||||
"error": err,
|
|
||||||
}).Error("error fetching interface metrics")
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return reply.Re, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) Update(ch chan<- prometheus.Metric) error {
|
|
||||||
|
|
||||||
stats, err := d.fetchInterfaceMetrics()
|
|
||||||
// if there is no error, deal with the response
|
|
||||||
if err == nil {
|
|
||||||
for _, re := range stats {
|
|
||||||
var intf string
|
|
||||||
for _, p := range InterfaceProps {
|
|
||||||
if p == "name" {
|
|
||||||
intf = re.Map[p]
|
|
||||||
} else {
|
|
||||||
desc, ok := d.iDesc[p]
|
|
||||||
if !ok {
|
|
||||||
desc = prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, "interface", metricStringCleanup(p)),
|
|
||||||
fmt.Sprintf("interface property statistic %s", p),
|
|
||||||
interfaceLabelNames,
|
|
||||||
nil,
|
|
||||||
)
|
|
||||||
d.iDesc[p] = desc
|
|
||||||
}
|
|
||||||
v, err := strconv.ParseFloat(re.Map[p], 64)
|
|
||||||
if err == nil {
|
|
||||||
ch <- prometheus.MustNewConstMetric(desc, prometheus.CounterValue, v, d.name, d.address, intf)
|
|
||||||
} else {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"device": d.name,
|
|
||||||
"interface": intf,
|
|
||||||
"property": p,
|
|
||||||
"value": re.Map[p],
|
|
||||||
"error": err,
|
|
||||||
}).Error("error parsing interface metric value")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
20
collector/helper.go
Normal file
20
collector/helper.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package collector
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func metricStringCleanup(in string) string {
|
||||||
|
return strings.Replace(in, "-", "_", -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func descriptionForPropertyName(prefix, property string, labelNames []string) *prometheus.Desc {
|
||||||
|
return prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(namespace, prefix, metricStringCleanup(property)),
|
||||||
|
property,
|
||||||
|
labelNames,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
}
|
89
collector/interface_collector.go
Normal file
89
collector/interface_collector.go
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
package collector
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/nshttpd/mikrotik-exporter/config"
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"gopkg.in/routeros.v2"
|
||||||
|
"gopkg.in/routeros.v2/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
interfaceLabelNames = []string{"name", "address", "interface"}
|
||||||
|
interfaceProps = []string{"name", "rx-byte", "tx-byte", "rx-packet", "tx-packet", "rx-error", "tx-error", "rx-drop", "tx-drop"}
|
||||||
|
interfaceDescriptions map[string]*prometheus.Desc
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
interfaceDescriptions = make(map[string]*prometheus.Desc)
|
||||||
|
for _, p := range interfaceProps[1:] {
|
||||||
|
interfaceDescriptions[p] = descriptionForPropertyName("interface", p, interfaceLabelNames)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type interfaceCollector struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *interfaceCollector) describe(ch chan<- *prometheus.Desc) {
|
||||||
|
for _, d := range interfaceDescriptions {
|
||||||
|
ch <- d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *interfaceCollector) collect(ch chan<- prometheus.Metric, device *config.Device, client *routeros.Client) error {
|
||||||
|
stats, err := c.fetch(client, device)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, re := range stats {
|
||||||
|
c.collectForStat(re, device, ch)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *interfaceCollector) fetch(client *routeros.Client, device *config.Device) ([]*proto.Sentence, error) {
|
||||||
|
reply, err := client.Run("/interface/print", "?disabled=false",
|
||||||
|
"?running=true", "=.proplist="+strings.Join(interfaceProps, ","))
|
||||||
|
if err != nil {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"device": device.Name,
|
||||||
|
"error": err,
|
||||||
|
}).Error("error fetching interface metrics")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return reply.Re, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *interfaceCollector) collectForStat(re *proto.Sentence, device *config.Device, ch chan<- prometheus.Metric) {
|
||||||
|
var iface string
|
||||||
|
for _, p := range interfaceProps {
|
||||||
|
if p == "name" {
|
||||||
|
iface = re.Map[p]
|
||||||
|
} else {
|
||||||
|
c.collectMetricForProperty(p, iface, device, re, ch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *interfaceCollector) collectMetricForProperty(property, iface string, device *config.Device, re *proto.Sentence, ch chan<- prometheus.Metric) {
|
||||||
|
desc := interfaceDescriptions[property]
|
||||||
|
v, err := strconv.ParseFloat(re.Map[property], 64)
|
||||||
|
if err != nil {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"device": device.Name,
|
||||||
|
"interface": iface,
|
||||||
|
"property": property,
|
||||||
|
"value": re.Map[property],
|
||||||
|
"error": err,
|
||||||
|
}).Error("error parsing interface metric value")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(desc, prometheus.CounterValue, v, device.Name, device.Address, iface)
|
||||||
|
}
|
12
collector/metric_collector.go
Normal file
12
collector/metric_collector.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package collector
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/nshttpd/mikrotik-exporter/config"
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
routeros "gopkg.in/routeros.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type metricCollector interface {
|
||||||
|
describe(ch chan<- *prometheus.Desc)
|
||||||
|
collect(ch chan<- prometheus.Metric, device *config.Device, client *routeros.Client) error
|
||||||
|
}
|
@ -1,86 +0,0 @@
|
|||||||
package collector
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
||||||
)
|
|
||||||
|
|
||||||
type PromMetrics struct {
|
|
||||||
InterfaceMetrics map[string]*prometheus.CounterVec
|
|
||||||
ResourceMetrics map[string]*prometheus.GaugeVec
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PromMetrics) makeLabels(name, address string) prometheus.Labels {
|
|
||||||
labels := make(prometheus.Labels)
|
|
||||||
labels["name"] = metricStringCleanup(name)
|
|
||||||
labels["address"] = metricStringCleanup(address)
|
|
||||||
return labels
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PromMetrics) makeInterfaceLabels(name, address, intf string) prometheus.Labels {
|
|
||||||
l := p.makeLabels(name, address)
|
|
||||||
l["interface"] = intf
|
|
||||||
return l
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PromMetrics) SetupPrometheus() (http.Handler, error) {
|
|
||||||
|
|
||||||
p.InterfaceMetrics = make(map[string]*prometheus.CounterVec)
|
|
||||||
p.ResourceMetrics = make(map[string]*prometheus.GaugeVec)
|
|
||||||
|
|
||||||
for _, v := range InterfaceProps {
|
|
||||||
n := metricStringCleanup(v)
|
|
||||||
c := prometheus.NewCounterVec(prometheus.CounterOpts{
|
|
||||||
Namespace: namespace,
|
|
||||||
Subsystem: "interface",
|
|
||||||
Name: n,
|
|
||||||
Help: fmt.Sprintf("Interface %s counter", v),
|
|
||||||
}, interfaceLabelNames)
|
|
||||||
|
|
||||||
if err := prometheus.Register(c); err != nil {
|
|
||||||
//l.Errorw("error creating interface counter vector",
|
|
||||||
// "property", v,
|
|
||||||
// "error", err,
|
|
||||||
//)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
p.InterfaceMetrics[v] = c
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range ResourceProps {
|
|
||||||
n := metricStringCleanup(v)
|
|
||||||
c := prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
|
||||||
Namespace: namespace,
|
|
||||||
Subsystem: "resource",
|
|
||||||
Name: n,
|
|
||||||
Help: fmt.Sprintf("Resource %s counter", v),
|
|
||||||
}, resourceLabelNames)
|
|
||||||
|
|
||||||
if err := prometheus.Register(c); err != nil {
|
|
||||||
//l.Errorw("error creating resource counter vec",
|
|
||||||
// "property", v,
|
|
||||||
// "error", err,
|
|
||||||
//)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
p.ResourceMetrics[v] = c
|
|
||||||
}
|
|
||||||
|
|
||||||
return promhttp.Handler(), nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PromMetrics) IncrementInterface(prop, name, address, intf string, cnt float64) {
|
|
||||||
l := p.makeInterfaceLabels(name, address, intf)
|
|
||||||
p.InterfaceMetrics[prop].With(l).Add(cnt)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PromMetrics) UpdateResource(res, name, address string, v float64) {
|
|
||||||
l := p.makeLabels(name, address)
|
|
||||||
p.ResourceMetrics[res].With(l).Set(v)
|
|
||||||
}
|
|
82
collector/resource_collector.go
Normal file
82
collector/resource_collector.go
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
package collector
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/nshttpd/mikrotik-exporter/config"
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"gopkg.in/routeros.v2"
|
||||||
|
"gopkg.in/routeros.v2/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
resourceLabelNames = []string{"name", "address"}
|
||||||
|
resourceProps = []string{"free-memory", "total-memory", "cpu-load", "free-hdd-space", "total-hdd-space"}
|
||||||
|
resourceDescriptions map[string]*prometheus.Desc
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
resourceDescriptions = make(map[string]*prometheus.Desc)
|
||||||
|
for _, p := range resourceProps {
|
||||||
|
resourceDescriptions[p] = descriptionForPropertyName("system", p, resourceLabelNames)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type resourceCollector struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *resourceCollector) describe(ch chan<- *prometheus.Desc) {
|
||||||
|
for _, d := range resourceDescriptions {
|
||||||
|
ch <- d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *resourceCollector) collect(ch chan<- prometheus.Metric, device *config.Device, client *routeros.Client) error {
|
||||||
|
stats, err := c.fetch(client, device)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, re := range stats {
|
||||||
|
c.collectForStat(re, device, ch)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *resourceCollector) fetch(client *routeros.Client, device *config.Device) ([]*proto.Sentence, error) {
|
||||||
|
reply, err := client.Run("/system/resource/print", "=.proplist="+strings.Join(resourceProps, ","))
|
||||||
|
if err != nil {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"device": device.Name,
|
||||||
|
"error": err,
|
||||||
|
}).Error("error fetching system resource metrics")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return reply.Re, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *resourceCollector) collectForStat(re *proto.Sentence, device *config.Device, ch chan<- prometheus.Metric) {
|
||||||
|
for _, p := range resourceProps {
|
||||||
|
c.collectMetricForProperty(p, device, re, ch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *resourceCollector) collectMetricForProperty(property string, device *config.Device, re *proto.Sentence, ch chan<- prometheus.Metric) {
|
||||||
|
v, err := strconv.ParseFloat(re.Map[property], 64)
|
||||||
|
if err != nil {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"device": device.Name,
|
||||||
|
"property": property,
|
||||||
|
"value": re.Map[property],
|
||||||
|
"error": err,
|
||||||
|
}).Error("error parsing system resource metric value")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
desc := resourceDescriptions[property]
|
||||||
|
ch <- prometheus.MustNewConstMetric(desc, prometheus.CounterValue, v, device.Name, device.Address)
|
||||||
|
}
|
110
collector/routes_collector.go
Normal file
110
collector/routes_collector.go
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
package collector
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/nshttpd/mikrotik-exporter/config"
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"gopkg.in/routeros.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
const routesPrefiix = "routes"
|
||||||
|
|
||||||
|
var (
|
||||||
|
routesProtocols = []string{"bgp", "static", "ospf", "dynamic", "connect"}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
routesTotalDesc *prometheus.Desc
|
||||||
|
routesProtocolDesc *prometheus.Desc
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
l := []string{"name", "address", "ip_version"}
|
||||||
|
routesTotalDesc = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(namespace, routesPrefiix, "total_count"),
|
||||||
|
"number of routes in RIB",
|
||||||
|
l,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
routesProtocolDesc = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(namespace, routesPrefiix, "protocol_count"),
|
||||||
|
"number of routes per protocol in RIB",
|
||||||
|
append(l, "protocol"),
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
type routesCollector struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *routesCollector) describe(ch chan<- *prometheus.Desc) {
|
||||||
|
ch <- routesTotalDesc
|
||||||
|
ch <- routesProtocolDesc
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *routesCollector) collect(ch chan<- prometheus.Metric, device *config.Device, client *routeros.Client) error {
|
||||||
|
c.colllectForIPVersion(client, device, ch, "4", "ip")
|
||||||
|
c.colllectForIPVersion(client, device, ch, "6", "ipv6")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *routesCollector) colllectForIPVersion(client *routeros.Client, device *config.Device, ch chan<- prometheus.Metric, ipVersion, topic string) {
|
||||||
|
c.colllectCount(client, device, ch, ipVersion, topic)
|
||||||
|
|
||||||
|
for _, p := range routesProtocols {
|
||||||
|
c.colllectCountProtcol(client, device, ch, ipVersion, topic, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *routesCollector) colllectCount(client *routeros.Client, device *config.Device, ch chan<- prometheus.Metric, ipVersion, topic string) {
|
||||||
|
reply, err := client.Run(fmt.Sprintf("/%s/route/print", topic), "?disabled=false", "=count-only=")
|
||||||
|
if err != nil {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"ip_version": ipVersion,
|
||||||
|
"device": device.Name,
|
||||||
|
"error": err,
|
||||||
|
}).Error("error fetching routes metrics")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
v, err := strconv.ParseFloat(reply.Done.Map["ret"], 32)
|
||||||
|
if err != nil {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"ip_version": ipVersion,
|
||||||
|
"device": device.Name,
|
||||||
|
"error": err,
|
||||||
|
}).Error("error parsing routes metrics")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(routesTotalDesc, prometheus.GaugeValue, v, device.Name, device.Address, ipVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *routesCollector) colllectCountProtcol(client *routeros.Client, device *config.Device, ch chan<- prometheus.Metric, ipVersion, topic, protocol string) {
|
||||||
|
reply, err := client.Run(fmt.Sprintf("/%s/route/print", topic), "?disabled=false", fmt.Sprintf("?%s", protocol), "=count-only=")
|
||||||
|
if err != nil {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"ip_version": ipVersion,
|
||||||
|
"protocol": protocol,
|
||||||
|
"device": device.Name,
|
||||||
|
"error": err,
|
||||||
|
}).Error("error fetching routes metrics")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
v, err := strconv.ParseFloat(reply.Done.Map["ret"], 32)
|
||||||
|
if err != nil {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"ip_version": ipVersion,
|
||||||
|
"protocol": protocol,
|
||||||
|
"device": device.Name,
|
||||||
|
"error": err,
|
||||||
|
}).Error("error parsing routes metrics")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(routesProtocolDesc, prometheus.GaugeValue, v, device.Name, device.Address, ipVersion, protocol)
|
||||||
|
}
|
34
config/config.go
Normal file
34
config/config.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
|
yaml "gopkg.in/yaml.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
Devices []Device `yaml:"devices"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Device struct {
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
Address string `yaml:"address"`
|
||||||
|
User string `yaml:"user"`
|
||||||
|
Password string `yaml:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func Load(r io.Reader) (*Config, error) {
|
||||||
|
b, err := ioutil.ReadAll(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
c := &Config{}
|
||||||
|
err = yaml.Unmarshal(b, c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, nil
|
||||||
|
}
|
49
config/config_test.go
Normal file
49
config/config_test.go
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestShouldParse(t *testing.T) {
|
||||||
|
b := loadTestFile(t)
|
||||||
|
c, err := Load(bytes.NewReader(b))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("could not parse: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(c.Devices) != 2 {
|
||||||
|
t.Fatalf("expected 2 devices, got %v", len(c.Devices))
|
||||||
|
}
|
||||||
|
|
||||||
|
assertConfig("test1", "192.168.1.1", "foo", "bar", c.Devices[0], t)
|
||||||
|
assertConfig("test2", "192.168.2.1", "test", "123", c.Devices[1], t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadTestFile(t *testing.T) []byte {
|
||||||
|
b, err := ioutil.ReadFile("test/config.test.yml")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("could not load config: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertConfig(name, address, user, password string, c Device, t *testing.T) {
|
||||||
|
if c.Name != name {
|
||||||
|
t.Fatalf("expected name %s, got %s", name, c.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Address != address {
|
||||||
|
t.Fatalf("expected address %s, got %s", address, c.Address)
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.User != user {
|
||||||
|
t.Fatalf("expected user %s, got %s", user, c.User)
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Password != password {
|
||||||
|
t.Fatalf("expected password %s, got %s", password, c.Password)
|
||||||
|
}
|
||||||
|
}
|
11
config/test/config.test.yml
Normal file
11
config/test/config.test.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
devices:
|
||||||
|
- name: test1
|
||||||
|
address: 192.168.1.1
|
||||||
|
user: foo
|
||||||
|
password: bar
|
||||||
|
- name: test2
|
||||||
|
address: 192.168.2.1
|
||||||
|
user: test
|
||||||
|
password: 123
|
158
main.go
158
main.go
@ -1,13 +1,17 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"flag"
|
"flag"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/nshttpd/mikrotik-exporter/collector"
|
"github.com/nshttpd/mikrotik-exporter/collector"
|
||||||
|
"github.com/nshttpd/mikrotik-exporter/config"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
"github.com/prometheus/common/version"
|
"github.com/prometheus/common/version"
|
||||||
@ -20,20 +24,105 @@ var (
|
|||||||
address = flag.String("address", "", "address of the device to monitor")
|
address = flag.String("address", "", "address of the device to monitor")
|
||||||
user = flag.String("user", "", "user for authentication with single device")
|
user = flag.String("user", "", "user for authentication with single device")
|
||||||
password = flag.String("password", "", "password for authentication for single device")
|
password = flag.String("password", "", "password for authentication for single device")
|
||||||
cfgFile = flag.String("config", "", "config file for multiple devices")
|
|
||||||
logLevel = flag.String("log-level", "info", "log level")
|
logLevel = flag.String("log-level", "info", "log level")
|
||||||
logFormat = flag.String("log-format", "json", "logformat text or json (default json)")
|
logFormat = flag.String("log-format", "json", "logformat text or json (default json)")
|
||||||
port = flag.String("port", ":9090", "port number to listen on")
|
port = flag.String("port", ":9090", "port number to listen on")
|
||||||
metricsPath = flag.String("path", "/metrics", "path to answer requests on")
|
metricsPath = flag.String("path", "/metrics", "path to answer requests on")
|
||||||
cfg collector.Config
|
configFile = flag.String("config-file", "", "config file to load")
|
||||||
|
withBgp = flag.Bool("with-bgp", false, "retrieves BGP routing infrormation")
|
||||||
|
withRoutes = flag.Bool("with-routes", false, "retrieves routing table information")
|
||||||
|
timeout = flag.Duration("timeout", collector.DefaultTimeout*time.Second, "timeout when connecting to routers")
|
||||||
|
tls = flag.Bool("tls", false, "use tls to connect to routers")
|
||||||
|
insecure = flag.Bool("insecure", false, "skips verification of server certificate when using TLS (not recommended)")
|
||||||
|
cfg *config.Config
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
prometheus.MustRegister(version.NewCollector("mikrotik_exporter"))
|
prometheus.MustRegister(version.NewCollector("mikrotik_exporter"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
configureLog()
|
||||||
|
|
||||||
|
c, err := loadConfig()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Could not load config: %v", err)
|
||||||
|
os.Exit(3)
|
||||||
|
}
|
||||||
|
cfg = c
|
||||||
|
|
||||||
|
startServer()
|
||||||
|
}
|
||||||
|
|
||||||
|
func configureLog() {
|
||||||
|
ll, err := log.ParseLevel(*logLevel)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.SetLevel(ll)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadConfig() (*config.Config, error) {
|
||||||
|
if *configFile != "" {
|
||||||
|
return loadConfigFromFile()
|
||||||
|
}
|
||||||
|
|
||||||
|
return loadConfigFromFlags()
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadConfigFromFile() (*config.Config, error) {
|
||||||
|
b, err := ioutil.ReadFile(*configFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return config.Load(bytes.NewReader(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadConfigFromFlags() (*config.Config, error) {
|
||||||
|
if *device == "" || *address == "" || *user == "" || *password == "" {
|
||||||
|
return nil, fmt.Errorf("missing required param for single device configuration")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &config.Config{
|
||||||
|
Devices: []config.Device{
|
||||||
|
config.Device{
|
||||||
|
Name: *device,
|
||||||
|
Address: *address,
|
||||||
|
User: *user,
|
||||||
|
Password: *password,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func startServer() {
|
||||||
|
http.HandleFunc(*metricsPath, prometheus.InstrumentHandlerFunc("prometheus", handler))
|
||||||
|
|
||||||
|
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Write([]byte("ok"))
|
||||||
|
})
|
||||||
|
|
||||||
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Write([]byte(`<html>
|
||||||
|
<head><title>Mikrotik Exporter</title></head>
|
||||||
|
<body>
|
||||||
|
<h1>Mikrotik Exporter</h1>
|
||||||
|
<p><a href="` + *metricsPath + `">Metrics</a></p>
|
||||||
|
</body>
|
||||||
|
</html>`))
|
||||||
|
})
|
||||||
|
|
||||||
|
log.Info("Listening on", *port)
|
||||||
|
log.Fatal(http.ListenAndServe(*port, nil))
|
||||||
|
}
|
||||||
|
|
||||||
func handler(w http.ResponseWriter, r *http.Request) {
|
func handler(w http.ResponseWriter, r *http.Request) {
|
||||||
nc, err := collector.NewDeviceCollector(cfg)
|
opts := collectorOptions()
|
||||||
|
nc, err := collector.NewCollector(cfg, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnln("Couldn't create", err)
|
log.Warnln("Couldn't create", err)
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
@ -50,12 +139,8 @@ func handler(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
gatherers := prometheus.Gatherers{
|
|
||||||
prometheus.DefaultGatherer,
|
|
||||||
registry,
|
|
||||||
}
|
|
||||||
// Delegate http serving to Prometheus client library, which will call collector.Collect.
|
// Delegate http serving to Prometheus client library, which will call collector.Collect.
|
||||||
h := promhttp.HandlerFor(gatherers,
|
h := promhttp.HandlerFor(registry,
|
||||||
promhttp.HandlerOpts{
|
promhttp.HandlerOpts{
|
||||||
ErrorLog: log.New(),
|
ErrorLog: log.New(),
|
||||||
ErrorHandling: promhttp.ContinueOnError,
|
ErrorHandling: promhttp.ContinueOnError,
|
||||||
@ -63,51 +148,24 @@ func handler(w http.ResponseWriter, r *http.Request) {
|
|||||||
h.ServeHTTP(w, r)
|
h.ServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func collectorOptions() []collector.Option {
|
||||||
flag.Parse()
|
opts := []collector.Option{}
|
||||||
|
|
||||||
// override default log level of info
|
if *withBgp {
|
||||||
var ll log.Level
|
opts = append(opts, collector.WithBGP())
|
||||||
var err error
|
|
||||||
ll = log.InfoLevel
|
|
||||||
if *logLevel != "info" {
|
|
||||||
ll, err = log.ParseLevel(*logLevel)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.SetLevel(ll)
|
|
||||||
|
|
||||||
if *cfgFile == "" {
|
|
||||||
if err := cfg.FromFlags(device, address, user, password); err != nil {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"error": err,
|
|
||||||
}).Error("could not create configuration")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.Info("config file not supported yet")
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
http.HandleFunc(*metricsPath, prometheus.InstrumentHandlerFunc("prometheus", handler))
|
if *withRoutes {
|
||||||
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
|
opts = append(opts, collector.WithRoutes())
|
||||||
w.Write([]byte("ok"))
|
|
||||||
})
|
|
||||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Write([]byte(`<html>
|
|
||||||
<head><title>Mikrotik Exporter</title></head>
|
|
||||||
<body>
|
|
||||||
<h1>Mikrotik Exporter</h1>
|
|
||||||
<p><a href="` + *metricsPath + `">Metrics</a></p>
|
|
||||||
</body>
|
|
||||||
</html>`))
|
|
||||||
})
|
|
||||||
|
|
||||||
log.Info("Listening on", *port)
|
|
||||||
err = http.ListenAndServe(*port, nil)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if *timeout != collector.DefaultTimeout {
|
||||||
|
opts = append(opts, collector.WithTimeout(*timeout))
|
||||||
|
}
|
||||||
|
|
||||||
|
if *tls {
|
||||||
|
opts = append(opts, collector.WithTLS(*insecure))
|
||||||
|
}
|
||||||
|
|
||||||
|
return opts
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/beorn7/perks/.gitignore
generated
vendored
Normal file
2
vendor/github.com/beorn7/perks/.gitignore
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*.test
|
||||||
|
*.prof
|
16
vendor/github.com/golang/protobuf/.gitignore
generated
vendored
Normal file
16
vendor/github.com/golang/protobuf/.gitignore
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
.DS_Store
|
||||||
|
*.[568ao]
|
||||||
|
*.ao
|
||||||
|
*.so
|
||||||
|
*.pyc
|
||||||
|
._*
|
||||||
|
.nfs.*
|
||||||
|
[568a].out
|
||||||
|
*~
|
||||||
|
*.orig
|
||||||
|
core
|
||||||
|
_obj
|
||||||
|
_test
|
||||||
|
_testmain.go
|
||||||
|
protoc-gen-go/testdata/multi/*.pb.go
|
||||||
|
_conformance/_conformance
|
3
vendor/github.com/golang/protobuf/jsonpb/jsonpb.go
generated
vendored
3
vendor/github.com/golang/protobuf/jsonpb/jsonpb.go
generated
vendored
@ -193,7 +193,8 @@ func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent, typeU
|
|||||||
// "Generated output always contains 3, 6, or 9 fractional digits,
|
// "Generated output always contains 3, 6, or 9 fractional digits,
|
||||||
// depending on required precision."
|
// depending on required precision."
|
||||||
s, ns := s.Field(0).Int(), s.Field(1).Int()
|
s, ns := s.Field(0).Int(), s.Field(1).Int()
|
||||||
x := fmt.Sprintf("%d.%09d", s, ns)
|
d := time.Duration(s)*time.Second + time.Duration(ns)*time.Nanosecond
|
||||||
|
x := fmt.Sprintf("%.9f", d.Seconds())
|
||||||
x = strings.TrimSuffix(x, "000")
|
x = strings.TrimSuffix(x, "000")
|
||||||
x = strings.TrimSuffix(x, "000")
|
x = strings.TrimSuffix(x, "000")
|
||||||
out.write(`"`)
|
out.write(`"`)
|
||||||
|
1
vendor/github.com/golang/protobuf/jsonpb/jsonpb_test.go
generated
vendored
1
vendor/github.com/golang/protobuf/jsonpb/jsonpb_test.go
generated
vendored
@ -407,7 +407,6 @@ var marshalingTests = []struct {
|
|||||||
{"Any with WKT", marshaler, anyWellKnown, anyWellKnownJSON},
|
{"Any with WKT", marshaler, anyWellKnown, anyWellKnownJSON},
|
||||||
{"Any with WKT and indent", marshalerAllOptions, anyWellKnown, anyWellKnownPrettyJSON},
|
{"Any with WKT and indent", marshalerAllOptions, anyWellKnown, anyWellKnownPrettyJSON},
|
||||||
{"Duration", marshaler, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 3}}, `{"dur":"3.000s"}`},
|
{"Duration", marshaler, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 3}}, `{"dur":"3.000s"}`},
|
||||||
{"Duration", marshaler, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 100000000, Nanos: 1}}, `{"dur":"100000000.000000001s"}`},
|
|
||||||
{"Struct", marshaler, &pb.KnownTypes{St: &stpb.Struct{
|
{"Struct", marshaler, &pb.KnownTypes{St: &stpb.Struct{
|
||||||
Fields: map[string]*stpb.Value{
|
Fields: map[string]*stpb.Value{
|
||||||
"one": {Kind: &stpb.Value_StringValue{"loneliest number"}},
|
"one": {Kind: &stpb.Value_StringValue{"loneliest number"}},
|
||||||
|
151
vendor/github.com/golang/protobuf/proto/discard.go
generated
vendored
Normal file
151
vendor/github.com/golang/protobuf/proto/discard.go
generated
vendored
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
//
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// https://github.com/golang/protobuf
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DiscardUnknown recursively discards all unknown fields from this message
|
||||||
|
// and all embedded messages.
|
||||||
|
//
|
||||||
|
// When unmarshaling a message with unrecognized fields, the tags and values
|
||||||
|
// of such fields are preserved in the Message. This allows a later call to
|
||||||
|
// marshal to be able to produce a message that continues to have those
|
||||||
|
// unrecognized fields. To avoid this, DiscardUnknown is used to
|
||||||
|
// explicitly clear the unknown fields after unmarshaling.
|
||||||
|
//
|
||||||
|
// For proto2 messages, the unknown fields of message extensions are only
|
||||||
|
// discarded from messages that have been accessed via GetExtension.
|
||||||
|
func DiscardUnknown(m Message) {
|
||||||
|
discardLegacy(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func discardLegacy(m Message) {
|
||||||
|
v := reflect.ValueOf(m)
|
||||||
|
if v.Kind() != reflect.Ptr || v.IsNil() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
v = v.Elem()
|
||||||
|
if v.Kind() != reflect.Struct {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t := v.Type()
|
||||||
|
|
||||||
|
for i := 0; i < v.NumField(); i++ {
|
||||||
|
f := t.Field(i)
|
||||||
|
if strings.HasPrefix(f.Name, "XXX_") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
vf := v.Field(i)
|
||||||
|
tf := f.Type
|
||||||
|
|
||||||
|
// Unwrap tf to get its most basic type.
|
||||||
|
var isPointer, isSlice bool
|
||||||
|
if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {
|
||||||
|
isSlice = true
|
||||||
|
tf = tf.Elem()
|
||||||
|
}
|
||||||
|
if tf.Kind() == reflect.Ptr {
|
||||||
|
isPointer = true
|
||||||
|
tf = tf.Elem()
|
||||||
|
}
|
||||||
|
if isPointer && isSlice && tf.Kind() != reflect.Struct {
|
||||||
|
panic(fmt.Sprintf("%T.%s cannot be a slice of pointers to primitive types", m, f.Name))
|
||||||
|
}
|
||||||
|
|
||||||
|
switch tf.Kind() {
|
||||||
|
case reflect.Struct:
|
||||||
|
switch {
|
||||||
|
case !isPointer:
|
||||||
|
panic(fmt.Sprintf("%T.%s cannot be a direct struct value", m, f.Name))
|
||||||
|
case isSlice: // E.g., []*pb.T
|
||||||
|
for j := 0; j < vf.Len(); j++ {
|
||||||
|
discardLegacy(vf.Index(j).Interface().(Message))
|
||||||
|
}
|
||||||
|
default: // E.g., *pb.T
|
||||||
|
discardLegacy(vf.Interface().(Message))
|
||||||
|
}
|
||||||
|
case reflect.Map:
|
||||||
|
switch {
|
||||||
|
case isPointer || isSlice:
|
||||||
|
panic(fmt.Sprintf("%T.%s cannot be a pointer to a map or a slice of map values", m, f.Name))
|
||||||
|
default: // E.g., map[K]V
|
||||||
|
tv := vf.Type().Elem()
|
||||||
|
if tv.Kind() == reflect.Ptr && tv.Implements(protoMessageType) { // Proto struct (e.g., *T)
|
||||||
|
for _, key := range vf.MapKeys() {
|
||||||
|
val := vf.MapIndex(key)
|
||||||
|
discardLegacy(val.Interface().(Message))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case reflect.Interface:
|
||||||
|
// Must be oneof field.
|
||||||
|
switch {
|
||||||
|
case isPointer || isSlice:
|
||||||
|
panic(fmt.Sprintf("%T.%s cannot be a pointer to a interface or a slice of interface values", m, f.Name))
|
||||||
|
default: // E.g., test_proto.isCommunique_Union interface
|
||||||
|
if !vf.IsNil() && f.Tag.Get("protobuf_oneof") != "" {
|
||||||
|
vf = vf.Elem() // E.g., *test_proto.Communique_Msg
|
||||||
|
if !vf.IsNil() {
|
||||||
|
vf = vf.Elem() // E.g., test_proto.Communique_Msg
|
||||||
|
vf = vf.Field(0) // E.g., Proto struct (e.g., *T) or primitive value
|
||||||
|
if vf.Kind() == reflect.Ptr {
|
||||||
|
discardLegacy(vf.Interface().(Message))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if vf := v.FieldByName("XXX_unrecognized"); vf.IsValid() {
|
||||||
|
if vf.Type() != reflect.TypeOf([]byte{}) {
|
||||||
|
panic("expected XXX_unrecognized to be of type []byte")
|
||||||
|
}
|
||||||
|
vf.Set(reflect.ValueOf([]byte(nil)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// For proto2 messages, only discard unknown fields in message extensions
|
||||||
|
// that have been accessed via GetExtension.
|
||||||
|
if em, ok := extendable(m); ok {
|
||||||
|
// Ignore lock since discardLegacy is not concurrency safe.
|
||||||
|
emm, _ := em.extensionsRead()
|
||||||
|
for _, mx := range emm {
|
||||||
|
if m, ok := mx.value.(Message); ok {
|
||||||
|
discardLegacy(m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
vendor/github.com/prometheus/client_golang/.gitignore
generated
vendored
Normal file
26
vendor/github.com/prometheus/client_golang/.gitignore
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Folders
|
||||||
|
_obj
|
||||||
|
_test
|
||||||
|
|
||||||
|
# Architecture specific extensions/prefixes
|
||||||
|
*.[568vq]
|
||||||
|
[568vq].out
|
||||||
|
|
||||||
|
*.cgo1.go
|
||||||
|
*.cgo2.c
|
||||||
|
_cgo_defun.c
|
||||||
|
_cgo_gotypes.go
|
||||||
|
_cgo_export.*
|
||||||
|
|
||||||
|
_testmain.go
|
||||||
|
|
||||||
|
*.exe
|
||||||
|
|
||||||
|
*~
|
||||||
|
*#
|
||||||
|
.build
|
1
vendor/github.com/prometheus/client_golang/prometheus/.gitignore
generated
vendored
Normal file
1
vendor/github.com/prometheus/client_golang/prometheus/.gitignore
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
command-line-arguments.test
|
1
vendor/github.com/prometheus/client_model/.gitignore
generated
vendored
Normal file
1
vendor/github.com/prometheus/client_model/.gitignore
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
target/
|
5
vendor/github.com/prometheus/client_model/ruby/.gitignore
generated
vendored
Normal file
5
vendor/github.com/prometheus/client_model/ruby/.gitignore
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
*.gem
|
||||||
|
.bundle
|
||||||
|
Gemfile.lock
|
||||||
|
pkg
|
||||||
|
vendor/bundle
|
10
vendor/github.com/prometheus/common/config/http_config.go
generated
vendored
10
vendor/github.com/prometheus/common/config/http_config.go
generated
vendored
@ -22,7 +22,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
yaml "gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BasicAuth contains basic HTTP authentication credentials.
|
// BasicAuth contains basic HTTP authentication credentials.
|
||||||
@ -79,7 +79,9 @@ type HTTPClientConfig struct {
|
|||||||
XXX map[string]interface{} `yaml:",inline"`
|
XXX map[string]interface{} `yaml:",inline"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTTPClientConfig) validate() error {
|
// Validate validates the HTTPClientConfig to check only one of BearerToken,
|
||||||
|
// BasicAuth and BearerTokenFile is configured.
|
||||||
|
func (c *HTTPClientConfig) Validate() error {
|
||||||
if len(c.BearerToken) > 0 && len(c.BearerTokenFile) > 0 {
|
if len(c.BearerToken) > 0 && len(c.BearerTokenFile) > 0 {
|
||||||
return fmt.Errorf("at most one of bearer_token & bearer_token_file must be configured")
|
return fmt.Errorf("at most one of bearer_token & bearer_token_file must be configured")
|
||||||
}
|
}
|
||||||
@ -96,9 +98,9 @@ func (c *HTTPClientConfig) UnmarshalYAML(unmarshal func(interface{}) error) erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = c.validate()
|
err = c.Validate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.validate()
|
return c.Validate()
|
||||||
}
|
}
|
||||||
return checkOverflow(c.XXX, "http_client_config")
|
return checkOverflow(c.XXX, "http_client_config")
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/prometheus/common/config/http_config_test.go
generated
vendored
2
vendor/github.com/prometheus/common/config/http_config_test.go
generated
vendored
@ -114,7 +114,7 @@ func TestValidateHTTPConfig(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Error loading HTTP client config: %v", err)
|
t.Errorf("Error loading HTTP client config: %v", err)
|
||||||
}
|
}
|
||||||
err = cfg.validate()
|
err = cfg.Validate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error validating %s: %s", "testdata/http.conf.good.yml", err)
|
t.Fatalf("Error validating %s: %s", "testdata/http.conf.good.yml", err)
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/prometheus/common/expfmt/expfmt.go
generated
vendored
2
vendor/github.com/prometheus/common/expfmt/expfmt.go
generated
vendored
@ -26,7 +26,7 @@ const (
|
|||||||
|
|
||||||
// The Content-Type values for the different wire protocols.
|
// The Content-Type values for the different wire protocols.
|
||||||
FmtUnknown Format = `<unknown>`
|
FmtUnknown Format = `<unknown>`
|
||||||
FmtText Format = `text/plain; version=` + TextVersion
|
FmtText Format = `text/plain; version=` + TextVersion + `; charset=utf-8`
|
||||||
FmtProtoDelim Format = ProtoFmt + ` encoding=delimited`
|
FmtProtoDelim Format = ProtoFmt + ` encoding=delimited`
|
||||||
FmtProtoText Format = ProtoFmt + ` encoding=text`
|
FmtProtoText Format = ProtoFmt + ` encoding=text`
|
||||||
FmtProtoCompact Format = ProtoFmt + ` encoding=compact-text`
|
FmtProtoCompact Format = ProtoFmt + ` encoding=compact-text`
|
||||||
|
27
vendor/github.com/prometheus/common/route/route.go
generated
vendored
27
vendor/github.com/prometheus/common/route/route.go
generated
vendored
@ -19,11 +19,12 @@ func WithParam(ctx context.Context, p, v string) context.Context {
|
|||||||
return context.WithValue(ctx, param(p), v)
|
return context.WithValue(ctx, param(p), v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Router wraps httprouter.Router and adds support for prefixed sub-routers
|
// Router wraps httprouter.Router and adds support for prefixed sub-routers,
|
||||||
// and per-request context injections.
|
// per-request context injections and instrumentation.
|
||||||
type Router struct {
|
type Router struct {
|
||||||
rtr *httprouter.Router
|
rtr *httprouter.Router
|
||||||
prefix string
|
prefix string
|
||||||
|
instrh func(handlerName string, handler http.HandlerFunc) http.HandlerFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new Router.
|
// New returns a new Router.
|
||||||
@ -33,13 +34,18 @@ func New() *Router {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithInstrumentation returns a router with instrumentation support.
|
||||||
|
func (r *Router) WithInstrumentation(instrh func(handlerName string, handler http.HandlerFunc) http.HandlerFunc) *Router {
|
||||||
|
return &Router{rtr: r.rtr, prefix: r.prefix, instrh: instrh}
|
||||||
|
}
|
||||||
|
|
||||||
// WithPrefix returns a router that prefixes all registered routes with prefix.
|
// WithPrefix returns a router that prefixes all registered routes with prefix.
|
||||||
func (r *Router) WithPrefix(prefix string) *Router {
|
func (r *Router) WithPrefix(prefix string) *Router {
|
||||||
return &Router{rtr: r.rtr, prefix: r.prefix + prefix}
|
return &Router{rtr: r.rtr, prefix: r.prefix + prefix, instrh: r.instrh}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle turns a HandlerFunc into an httprouter.Handle.
|
// handle turns a HandlerFunc into an httprouter.Handle.
|
||||||
func (r *Router) handle(h http.HandlerFunc) httprouter.Handle {
|
func (r *Router) handle(handlerName string, h http.HandlerFunc) httprouter.Handle {
|
||||||
return func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
|
return func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@ -47,33 +53,36 @@ func (r *Router) handle(h http.HandlerFunc) httprouter.Handle {
|
|||||||
for _, p := range params {
|
for _, p := range params {
|
||||||
ctx = context.WithValue(ctx, param(p.Key), p.Value)
|
ctx = context.WithValue(ctx, param(p.Key), p.Value)
|
||||||
}
|
}
|
||||||
|
if r.instrh != nil {
|
||||||
|
h = r.instrh(handlerName, h)
|
||||||
|
}
|
||||||
h(w, req.WithContext(ctx))
|
h(w, req.WithContext(ctx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get registers a new GET route.
|
// Get registers a new GET route.
|
||||||
func (r *Router) Get(path string, h http.HandlerFunc) {
|
func (r *Router) Get(path string, h http.HandlerFunc) {
|
||||||
r.rtr.GET(r.prefix+path, r.handle(h))
|
r.rtr.GET(r.prefix+path, r.handle(path, h))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Options registers a new OPTIONS route.
|
// Options registers a new OPTIONS route.
|
||||||
func (r *Router) Options(path string, h http.HandlerFunc) {
|
func (r *Router) Options(path string, h http.HandlerFunc) {
|
||||||
r.rtr.OPTIONS(r.prefix+path, r.handle(h))
|
r.rtr.OPTIONS(r.prefix+path, r.handle(path, h))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Del registers a new DELETE route.
|
// Del registers a new DELETE route.
|
||||||
func (r *Router) Del(path string, h http.HandlerFunc) {
|
func (r *Router) Del(path string, h http.HandlerFunc) {
|
||||||
r.rtr.DELETE(r.prefix+path, r.handle(h))
|
r.rtr.DELETE(r.prefix+path, r.handle(path, h))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put registers a new PUT route.
|
// Put registers a new PUT route.
|
||||||
func (r *Router) Put(path string, h http.HandlerFunc) {
|
func (r *Router) Put(path string, h http.HandlerFunc) {
|
||||||
r.rtr.PUT(r.prefix+path, r.handle(h))
|
r.rtr.PUT(r.prefix+path, r.handle(path, h))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Post registers a new POST route.
|
// Post registers a new POST route.
|
||||||
func (r *Router) Post(path string, h http.HandlerFunc) {
|
func (r *Router) Post(path string, h http.HandlerFunc) {
|
||||||
r.rtr.POST(r.prefix+path, r.handle(h))
|
r.rtr.POST(r.prefix+path, r.handle(path, h))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redirect takes an absolute path and sends an internal HTTP redirect for it,
|
// Redirect takes an absolute path and sends an internal HTTP redirect for it,
|
||||||
|
32
vendor/github.com/prometheus/common/route/route_test.go
generated
vendored
32
vendor/github.com/prometheus/common/route/route_test.go
generated
vendored
@ -42,3 +42,35 @@ func TestContext(t *testing.T) {
|
|||||||
}
|
}
|
||||||
router.ServeHTTP(nil, r)
|
router.ServeHTTP(nil, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestInstrumentation(t *testing.T) {
|
||||||
|
var got string
|
||||||
|
cases := []struct {
|
||||||
|
router *Router
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
router: New(),
|
||||||
|
want: "",
|
||||||
|
}, {
|
||||||
|
router: New().WithInstrumentation(func(handlerName string, handler http.HandlerFunc) http.HandlerFunc {
|
||||||
|
got = handlerName
|
||||||
|
return handler
|
||||||
|
}),
|
||||||
|
want: "/foo",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
c.router.Get("/foo", func(w http.ResponseWriter, r *http.Request) {})
|
||||||
|
|
||||||
|
r, err := http.NewRequest("GET", "http://localhost:9090/foo", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error building test request: %s", err)
|
||||||
|
}
|
||||||
|
c.router.ServeHTTP(nil, r)
|
||||||
|
if c.want != got {
|
||||||
|
t.Fatalf("Unexpected value: want %q, got %q", c.want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
1
vendor/github.com/prometheus/procfs/.gitignore
generated
vendored
Normal file
1
vendor/github.com/prometheus/procfs/.gitignore
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/fixtures/
|
14
vendor/github.com/prometheus/procfs/.travis.yml
generated
vendored
14
vendor/github.com/prometheus/procfs/.travis.yml
generated
vendored
@ -1,5 +1,15 @@
|
|||||||
sudo: false
|
sudo: false
|
||||||
|
|
||||||
language: go
|
language: go
|
||||||
|
|
||||||
go:
|
go:
|
||||||
- 1.7.6
|
- 1.7.x
|
||||||
- 1.8.3
|
- 1.8.x
|
||||||
|
- 1.9.x
|
||||||
|
- 1.10.x
|
||||||
|
- 1.x
|
||||||
|
|
||||||
|
go_import_path: github.com/prometheus/procfs
|
||||||
|
|
||||||
|
script:
|
||||||
|
- make style check_license vet test staticcheck
|
||||||
|
77
vendor/github.com/prometheus/procfs/Makefile
generated
vendored
77
vendor/github.com/prometheus/procfs/Makefile
generated
vendored
@ -1,18 +1,71 @@
|
|||||||
ci: fmt lint test
|
# Copyright 2018 The Prometheus Authors
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
fmt:
|
# Ensure GOBIN is not set during build so that promu is installed to the correct path
|
||||||
! gofmt -l *.go | read nothing
|
unexport GOBIN
|
||||||
go vet
|
|
||||||
|
|
||||||
lint:
|
GO ?= go
|
||||||
go get github.com/golang/lint/golint
|
GOFMT ?= $(GO)fmt
|
||||||
golint *.go
|
FIRST_GOPATH := $(firstword $(subst :, ,$(shell $(GO) env GOPATH)))
|
||||||
|
STATICCHECK := $(FIRST_GOPATH)/bin/staticcheck
|
||||||
|
pkgs = $(shell $(GO) list ./... | grep -v /vendor/)
|
||||||
|
|
||||||
test: sysfs/fixtures/.unpacked
|
PREFIX ?= $(shell pwd)
|
||||||
go test -v ./...
|
BIN_DIR ?= $(shell pwd)
|
||||||
|
|
||||||
sysfs/fixtures/.unpacked: sysfs/fixtures.ttar
|
ifdef DEBUG
|
||||||
./ttar -C sysfs -x -f sysfs/fixtures.ttar
|
bindata_flags = -debug
|
||||||
|
endif
|
||||||
|
|
||||||
|
STATICCHECK_IGNORE =
|
||||||
|
|
||||||
|
all: format staticcheck build test
|
||||||
|
|
||||||
|
style:
|
||||||
|
@echo ">> checking code style"
|
||||||
|
@! $(GOFMT) -d $(shell find . -path ./vendor -prune -o -name '*.go' -print) | grep '^'
|
||||||
|
|
||||||
|
check_license:
|
||||||
|
@echo ">> checking license header"
|
||||||
|
@./scripts/check_license.sh
|
||||||
|
|
||||||
|
test: fixtures/.unpacked sysfs/fixtures/.unpacked
|
||||||
|
@echo ">> running all tests"
|
||||||
|
@$(GO) test -race $(shell $(GO) list ./... | grep -v /vendor/ | grep -v examples)
|
||||||
|
|
||||||
|
format:
|
||||||
|
@echo ">> formatting code"
|
||||||
|
@$(GO) fmt $(pkgs)
|
||||||
|
|
||||||
|
vet:
|
||||||
|
@echo ">> vetting code"
|
||||||
|
@$(GO) vet $(pkgs)
|
||||||
|
|
||||||
|
staticcheck: $(STATICCHECK)
|
||||||
|
@echo ">> running staticcheck"
|
||||||
|
@$(STATICCHECK) -ignore "$(STATICCHECK_IGNORE)" $(pkgs)
|
||||||
|
|
||||||
|
%/.unpacked: %.ttar
|
||||||
|
./ttar -C $(dir $*) -x -f $*.ttar
|
||||||
touch $@
|
touch $@
|
||||||
|
|
||||||
.PHONY: fmt lint test ci
|
$(FIRST_GOPATH)/bin/staticcheck:
|
||||||
|
@GOOS= GOARCH= $(GO) get -u honnef.co/go/tools/cmd/staticcheck
|
||||||
|
|
||||||
|
.PHONY: all style check_license format test vet staticcheck
|
||||||
|
|
||||||
|
# Declaring the binaries at their default locations as PHONY targets is a hack
|
||||||
|
# to ensure the latest version is downloaded on every make execution.
|
||||||
|
# If this is not desired, copy/symlink these binaries to a different path and
|
||||||
|
# set the respective environment variables.
|
||||||
|
.PHONY: $(GOPATH)/bin/staticcheck
|
||||||
|
8
vendor/github.com/prometheus/procfs/bcache/get.go
generated
vendored
8
vendor/github.com/prometheus/procfs/bcache/get.go
generated
vendored
@ -61,7 +61,7 @@ func dehumanize(hbytes []byte) (uint64, error) {
|
|||||||
mul := float64(1)
|
mul := float64(1)
|
||||||
var (
|
var (
|
||||||
mant float64
|
mant float64
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
// If lastByte is beyond the range of ASCII digits, it must be a
|
// If lastByte is beyond the range of ASCII digits, it must be a
|
||||||
// multiplier.
|
// multiplier.
|
||||||
@ -93,7 +93,7 @@ func dehumanize(hbytes []byte) (uint64, error) {
|
|||||||
'Z': ZiB,
|
'Z': ZiB,
|
||||||
'Y': YiB,
|
'Y': YiB,
|
||||||
}
|
}
|
||||||
mul = float64(multipliers[rune(lastByte)])
|
mul = multipliers[rune(lastByte)]
|
||||||
mant, err = parsePseudoFloat(string(hbytes))
|
mant, err = parsePseudoFloat(string(hbytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -139,10 +139,10 @@ func (p *parser) readValue(fileName string) uint64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ParsePriorityStats parses lines from the priority_stats file.
|
// ParsePriorityStats parses lines from the priority_stats file.
|
||||||
func parsePriorityStats(line string, ps *PriorityStats) (error) {
|
func parsePriorityStats(line string, ps *PriorityStats) error {
|
||||||
var (
|
var (
|
||||||
value uint64
|
value uint64
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
switch {
|
switch {
|
||||||
case strings.HasPrefix(line, "Unused:"):
|
case strings.HasPrefix(line, "Unused:"):
|
||||||
|
20
vendor/github.com/prometheus/procfs/bcache/get_test.go
generated
vendored
20
vendor/github.com/prometheus/procfs/bcache/get_test.go
generated
vendored
@ -14,8 +14,8 @@
|
|||||||
package bcache
|
package bcache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
|
||||||
"math"
|
"math"
|
||||||
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDehumanizeTests(t *testing.T) {
|
func TestDehumanizeTests(t *testing.T) {
|
||||||
@ -45,8 +45,8 @@ func TestDehumanizeTests(t *testing.T) {
|
|||||||
out: 2024,
|
out: 2024,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
in: []byte(""),
|
in: []byte(""),
|
||||||
out: 0,
|
out: 0,
|
||||||
invalid: true,
|
invalid: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -59,7 +59,7 @@ func TestDehumanizeTests(t *testing.T) {
|
|||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
if got != tst.out {
|
if got != tst.out {
|
||||||
t.Errorf("dehumanize: '%s', want %f, got %f", tst.in, tst.out, got)
|
t.Errorf("dehumanize: '%s', want %d, got %d", tst.in, tst.out, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,7 +84,7 @@ func TestParsePseudoFloatTests(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, tst := range parsePseudoFloatTests {
|
for _, tst := range parsePseudoFloatTests {
|
||||||
got, err := parsePseudoFloat(tst.in)
|
got, err := parsePseudoFloat(tst.in)
|
||||||
if err != nil || math.Abs(got - tst.out) > 0.0001 {
|
if err != nil || math.Abs(got-tst.out) > 0.0001 {
|
||||||
t.Errorf("parsePseudoFloat: %s, want %f, got %f", tst.in, tst.out, got)
|
t.Errorf("parsePseudoFloat: %s, want %f, got %f", tst.in, tst.out, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,23 +92,23 @@ func TestParsePseudoFloatTests(t *testing.T) {
|
|||||||
|
|
||||||
func TestPriorityStats(t *testing.T) {
|
func TestPriorityStats(t *testing.T) {
|
||||||
var want = PriorityStats{
|
var want = PriorityStats{
|
||||||
UnusedPercent: 99,
|
UnusedPercent: 99,
|
||||||
MetadataPercent: 5,
|
MetadataPercent: 5,
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
in string
|
in string
|
||||||
gotErr error
|
gotErr error
|
||||||
got PriorityStats
|
got PriorityStats
|
||||||
)
|
)
|
||||||
in = "Metadata: 5%"
|
in = "Metadata: 5%"
|
||||||
gotErr = parsePriorityStats(in, &got)
|
gotErr = parsePriorityStats(in, &got)
|
||||||
if gotErr != nil || got.MetadataPercent != want.MetadataPercent {
|
if gotErr != nil || got.MetadataPercent != want.MetadataPercent {
|
||||||
t.Errorf("parsePriorityStats: '%s', want %f, got %f", in, want.MetadataPercent, got.MetadataPercent)
|
t.Errorf("parsePriorityStats: '%s', want %d, got %d", in, want.MetadataPercent, got.MetadataPercent)
|
||||||
}
|
}
|
||||||
|
|
||||||
in = "Unused: 99%"
|
in = "Unused: 99%"
|
||||||
gotErr = parsePriorityStats(in, &got)
|
gotErr = parsePriorityStats(in, &got)
|
||||||
if gotErr != nil || got.UnusedPercent != want.UnusedPercent {
|
if gotErr != nil || got.UnusedPercent != want.UnusedPercent {
|
||||||
t.Errorf("parsePriorityStats: '%s', want %f, got %f", in, want.UnusedPercent, got.UnusedPercent)
|
t.Errorf("parsePriorityStats: '%s', want %d, got %d", in, want.UnusedPercent, got.UnusedPercent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/prometheus/procfs/buddyinfo.go
generated
vendored
2
vendor/github.com/prometheus/procfs/buddyinfo.go
generated
vendored
@ -62,7 +62,7 @@ func parseBuddyInfo(r io.Reader) ([]BuddyInfo, error) {
|
|||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
var err error
|
var err error
|
||||||
line := scanner.Text()
|
line := scanner.Text()
|
||||||
parts := strings.Fields(string(line))
|
parts := strings.Fields(line)
|
||||||
|
|
||||||
if len(parts) < 4 {
|
if len(parts) < 4 {
|
||||||
return nil, fmt.Errorf("invalid number of fields when parsing buddyinfo")
|
return nil, fmt.Errorf("invalid number of fields when parsing buddyinfo")
|
||||||
|
446
vendor/github.com/prometheus/procfs/fixtures.ttar
generated
vendored
Normal file
446
vendor/github.com/prometheus/procfs/fixtures.ttar
generated
vendored
Normal file
@ -0,0 +1,446 @@
|
|||||||
|
# Archive created by ttar -c -f fixtures.ttar fixtures/
|
||||||
|
Directory: fixtures
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/26231
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26231/cmdline
|
||||||
|
Lines: 1
|
||||||
|
vimNULLBYTEtest.goNULLBYTE+10NULLBYTEEOF
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26231/comm
|
||||||
|
Lines: 1
|
||||||
|
vim
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26231/exe
|
||||||
|
SymlinkTo: /usr/bin/vim
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/26231/fd
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26231/fd/0
|
||||||
|
SymlinkTo: ../../symlinktargets/abc
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26231/fd/1
|
||||||
|
SymlinkTo: ../../symlinktargets/def
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26231/fd/10
|
||||||
|
SymlinkTo: ../../symlinktargets/xyz
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26231/fd/2
|
||||||
|
SymlinkTo: ../../symlinktargets/ghi
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26231/fd/3
|
||||||
|
SymlinkTo: ../../symlinktargets/uvw
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26231/io
|
||||||
|
Lines: 7
|
||||||
|
rchar: 750339
|
||||||
|
wchar: 818609
|
||||||
|
syscr: 7405
|
||||||
|
syscw: 5245
|
||||||
|
read_bytes: 1024
|
||||||
|
write_bytes: 2048
|
||||||
|
cancelled_write_bytes: -1024
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26231/limits
|
||||||
|
Lines: 17
|
||||||
|
Limit Soft Limit Hard Limit Units
|
||||||
|
Max cpu time unlimited unlimited seconds
|
||||||
|
Max file size unlimited unlimited bytes
|
||||||
|
Max data size unlimited unlimited bytes
|
||||||
|
Max stack size 8388608 unlimited bytes
|
||||||
|
Max core file size 0 unlimited bytes
|
||||||
|
Max resident set unlimited unlimited bytes
|
||||||
|
Max processes 62898 62898 processes
|
||||||
|
Max open files 2048 4096 files
|
||||||
|
Max locked memory 65536 65536 bytes
|
||||||
|
Max address space 8589934592 unlimited bytes
|
||||||
|
Max file locks unlimited unlimited locks
|
||||||
|
Max pending signals 62898 62898 signals
|
||||||
|
Max msgqueue size 819200 819200 bytes
|
||||||
|
Max nice priority 0 0
|
||||||
|
Max realtime priority 0 0
|
||||||
|
Max realtime timeout unlimited unlimited us
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26231/mountstats
|
||||||
|
Lines: 19
|
||||||
|
device rootfs mounted on / with fstype rootfs
|
||||||
|
device sysfs mounted on /sys with fstype sysfs
|
||||||
|
device proc mounted on /proc with fstype proc
|
||||||
|
device /dev/sda1 mounted on / with fstype ext4
|
||||||
|
device 192.168.1.1:/srv/test mounted on /mnt/nfs/test with fstype nfs4 statvers=1.1
|
||||||
|
opts: rw,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,acregmin=3,acregmax=60,acdirmin=30,acdirmax=60,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.5,local_lock=none
|
||||||
|
age: 13968
|
||||||
|
caps: caps=0xfff7,wtmult=512,dtsize=32768,bsize=0,namlen=255
|
||||||
|
nfsv4: bm0=0xfdffafff,bm1=0xf9be3e,bm2=0x0,acl=0x0,pnfs=not configured
|
||||||
|
sec: flavor=1,pseudoflavor=1
|
||||||
|
events: 52 226 0 0 1 13 398 0 0 331 0 47 0 0 77 0 0 77 0 0 0 0 0 0 0 0 0
|
||||||
|
bytes: 1207640230 0 0 0 1210214218 0 295483 0
|
||||||
|
RPC iostats version: 1.0 p/v: 100003/4 (nfs)
|
||||||
|
xprt: tcp 832 0 1 0 11 6428 6428 0 12154 0 24 26 5726
|
||||||
|
per-op statistics
|
||||||
|
NULL: 0 0 0 0 0 0 0 0
|
||||||
|
READ: 1298 1298 0 207680 1210292152 6 79386 79407
|
||||||
|
WRITE: 0 0 0 0 0 0 0 0
|
||||||
|
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/26231/net
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26231/net/dev
|
||||||
|
Lines: 4
|
||||||
|
Inter-| Receive | Transmit
|
||||||
|
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
|
||||||
|
lo: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
eth0: 438 5 0 0 0 0 0 0 648 8 0 0 0 0 0 0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/26231/ns
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26231/ns/mnt
|
||||||
|
SymlinkTo: mnt:[4026531840]
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26231/ns/net
|
||||||
|
SymlinkTo: net:[4026531993]
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26231/stat
|
||||||
|
Lines: 1
|
||||||
|
26231 (vim) R 5392 7446 5392 34835 7446 4218880 32533 309516 26 82 1677 44 158 99 20 0 1 0 82375 56274944 1981 18446744073709551615 4194304 6294284 140736914091744 140736914087944 139965136429984 0 0 12288 1870679807 0 0 0 17 0 0 0 31 0 0 8391624 8481048 16420864 140736914093252 140736914093279 140736914093279 140736914096107 0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/26232
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26232/cmdline
|
||||||
|
Lines: 0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26232/comm
|
||||||
|
Lines: 1
|
||||||
|
ata_sff
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/26232/fd
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26232/fd/0
|
||||||
|
SymlinkTo: ../../symlinktargets/abc
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26232/fd/1
|
||||||
|
SymlinkTo: ../../symlinktargets/def
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26232/fd/2
|
||||||
|
SymlinkTo: ../../symlinktargets/ghi
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26232/fd/3
|
||||||
|
SymlinkTo: ../../symlinktargets/uvw
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26232/fd/4
|
||||||
|
SymlinkTo: ../../symlinktargets/xyz
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26232/limits
|
||||||
|
Lines: 17
|
||||||
|
Limit Soft Limit Hard Limit Units
|
||||||
|
Max cpu time unlimited unlimited seconds
|
||||||
|
Max file size unlimited unlimited bytes
|
||||||
|
Max data size unlimited unlimited bytes
|
||||||
|
Max stack size 8388608 unlimited bytes
|
||||||
|
Max core file size 0 unlimited bytes
|
||||||
|
Max resident set unlimited unlimited bytes
|
||||||
|
Max processes 29436 29436 processes
|
||||||
|
Max open files 1024 4096 files
|
||||||
|
Max locked memory 65536 65536 bytes
|
||||||
|
Max address space unlimited unlimited bytes
|
||||||
|
Max file locks unlimited unlimited locks
|
||||||
|
Max pending signals 29436 29436 signals
|
||||||
|
Max msgqueue size 819200 819200 bytes
|
||||||
|
Max nice priority 0 0
|
||||||
|
Max realtime priority 0 0
|
||||||
|
Max realtime timeout unlimited unlimited us
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26232/stat
|
||||||
|
Lines: 1
|
||||||
|
33 (ata_sff) S 2 0 0 0 -1 69238880 0 0 0 0 0 0 0 0 0 -20 1 0 5 0 0 18446744073709551615 0 0 0 0 0 0 0 2147483647 0 18446744073709551615 0 0 17 1 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/26233
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/26233/cmdline
|
||||||
|
Lines: 1
|
||||||
|
com.github.uiautomatorNULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTEEOF
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/584
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/584/stat
|
||||||
|
Lines: 2
|
||||||
|
1020 ((a b ) ( c d) ) R 28378 1020 28378 34842 1020 4218880 286 0 0 0 0 0 0 0 20 0 1 0 10839175 10395648 155 18446744073709551615 4194304 4238788 140736466511168 140736466511168 140609271124624 0 0 0 0 0 0 0 17 5 0 0 0 0 0 6336016 6337300 25579520 140736466515030 140736466515061 140736466515061 140736466518002 0
|
||||||
|
#!/bin/cat /proc/self/stat
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/buddyinfo
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/buddyinfo/short
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/buddyinfo/short/buddyinfo
|
||||||
|
Lines: 3
|
||||||
|
Node 0, zone
|
||||||
|
Node 0, zone
|
||||||
|
Node 0, zone
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/buddyinfo/sizemismatch
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/buddyinfo/sizemismatch/buddyinfo
|
||||||
|
Lines: 3
|
||||||
|
Node 0, zone DMA 1 0 1 0 2 1 1 0 1 1 3
|
||||||
|
Node 0, zone DMA32 759 572 791 475 194 45 12 0 0 0 0 0
|
||||||
|
Node 0, zone Normal 4381 1093 185 1530 567 102 4 0 0 0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/buddyinfo/valid
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/buddyinfo/valid/buddyinfo
|
||||||
|
Lines: 3
|
||||||
|
Node 0, zone DMA 1 0 1 0 2 1 1 0 1 1 3
|
||||||
|
Node 0, zone DMA32 759 572 791 475 194 45 12 0 0 0 0
|
||||||
|
Node 0, zone Normal 4381 1093 185 1530 567 102 4 0 0 0 0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/fs
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/fs/xfs
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/fs/xfs/stat
|
||||||
|
Lines: 23
|
||||||
|
extent_alloc 92447 97589 92448 93751
|
||||||
|
abt 0 0 0 0
|
||||||
|
blk_map 1767055 188820 184891 92447 92448 2140766 0
|
||||||
|
bmbt 0 0 0 0
|
||||||
|
dir 185039 92447 92444 136422
|
||||||
|
trans 706 944304 0
|
||||||
|
ig 185045 58807 0 126238 0 33637 22
|
||||||
|
log 2883 113448 9 17360 739
|
||||||
|
push_ail 945014 0 134260 15483 0 3940 464 159985 0 40
|
||||||
|
xstrat 92447 0
|
||||||
|
rw 107739 94045
|
||||||
|
attr 4 0 0 0
|
||||||
|
icluster 8677 7849 135802
|
||||||
|
vnodes 92601 0 0 0 92444 92444 92444 0
|
||||||
|
buf 2666287 7122 2659202 3599 2 7085 0 10297 7085
|
||||||
|
abtb2 184941 1277345 13257 13278 0 0 0 0 0 0 0 0 0 0 2746147
|
||||||
|
abtc2 345295 2416764 172637 172658 0 0 0 0 0 0 0 0 0 0 21406023
|
||||||
|
bmbt2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
ibt2 343004 1358467 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
fibt2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
qm 0 0 0 0 0 0 0 0
|
||||||
|
xpc 399724544 92823103 86219234
|
||||||
|
debug 0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/mdstat
|
||||||
|
Lines: 26
|
||||||
|
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
|
||||||
|
md3 : active raid6 sda1[8] sdh1[7] sdg1[6] sdf1[5] sde1[11] sdd1[3] sdc1[10] sdb1[9]
|
||||||
|
5853468288 blocks super 1.2 level 6, 64k chunk, algorithm 2 [8/8] [UUUUUUUU]
|
||||||
|
|
||||||
|
md127 : active raid1 sdi2[0] sdj2[1]
|
||||||
|
312319552 blocks [2/2] [UU]
|
||||||
|
|
||||||
|
md0 : active raid1 sdk[2](S) sdi1[0] sdj1[1]
|
||||||
|
248896 blocks [2/2] [UU]
|
||||||
|
|
||||||
|
md4 : inactive raid1 sda3[0] sdb3[1]
|
||||||
|
4883648 blocks [2/2] [UU]
|
||||||
|
|
||||||
|
md6 : active raid1 sdb2[2] sda2[0]
|
||||||
|
195310144 blocks [2/1] [U_]
|
||||||
|
[=>...................] recovery = 8.5% (16775552/195310144) finish=17.0min speed=259783K/sec
|
||||||
|
|
||||||
|
md8 : active raid1 sdb1[1] sda1[0]
|
||||||
|
195310144 blocks [2/2] [UU]
|
||||||
|
[=>...................] resync = 8.5% (16775552/195310144) finish=17.0min speed=259783K/sec
|
||||||
|
|
||||||
|
md7 : active raid6 sdb1[0] sde1[3] sdd1[2] sdc1[1]
|
||||||
|
7813735424 blocks super 1.2 level 6, 512k chunk, algorithm 2 [4/3] [U_UU]
|
||||||
|
bitmap: 0/30 pages [0KB], 65536KB chunk
|
||||||
|
|
||||||
|
unused devices: <none>
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/net
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/net/dev
|
||||||
|
Lines: 6
|
||||||
|
Inter-| Receive | Transmit
|
||||||
|
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
|
||||||
|
vethf345468: 648 8 0 0 0 0 0 0 438 5 0 0 0 0 0 0
|
||||||
|
lo: 1664039048 1566805 0 0 0 0 0 0 1664039048 1566805 0 0 0 0 0 0
|
||||||
|
docker0: 2568 38 0 0 0 0 0 0 438 5 0 0 0 0 0 0
|
||||||
|
eth0: 874354587 1036395 0 0 0 0 0 0 563352563 732147 0 0 0 0 0 0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/net/ip_vs
|
||||||
|
Lines: 21
|
||||||
|
IP Virtual Server version 1.2.1 (size=4096)
|
||||||
|
Prot LocalAddress:Port Scheduler Flags
|
||||||
|
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
|
||||||
|
TCP C0A80016:0CEA wlc
|
||||||
|
-> C0A85216:0CEA Tunnel 100 248 2
|
||||||
|
-> C0A85318:0CEA Tunnel 100 248 2
|
||||||
|
-> C0A85315:0CEA Tunnel 100 248 1
|
||||||
|
TCP C0A80039:0CEA wlc
|
||||||
|
-> C0A85416:0CEA Tunnel 0 0 0
|
||||||
|
-> C0A85215:0CEA Tunnel 100 1499 0
|
||||||
|
-> C0A83215:0CEA Tunnel 100 1498 0
|
||||||
|
TCP C0A80037:0CEA wlc
|
||||||
|
-> C0A8321A:0CEA Tunnel 0 0 0
|
||||||
|
-> C0A83120:0CEA Tunnel 100 0 0
|
||||||
|
TCP [2620:0000:0000:0000:0000:0000:0000:0001]:0050 sh
|
||||||
|
-> [2620:0000:0000:0000:0000:0000:0000:0002]:0050 Route 1 0 0
|
||||||
|
-> [2620:0000:0000:0000:0000:0000:0000:0003]:0050 Route 1 0 0
|
||||||
|
-> [2620:0000:0000:0000:0000:0000:0000:0004]:0050 Route 1 1 1
|
||||||
|
FWM 10001000 wlc
|
||||||
|
-> C0A8321A:0CEA Route 0 0 1
|
||||||
|
-> C0A83215:0CEA Route 0 0 2
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/net/ip_vs_stats
|
||||||
|
Lines: 6
|
||||||
|
Total Incoming Outgoing Incoming Outgoing
|
||||||
|
Conns Packets Packets Bytes Bytes
|
||||||
|
16AA370 E33656E5 0 51D8C8883AB3 0
|
||||||
|
|
||||||
|
Conns/s Pkts/s Pkts/s Bytes/s Bytes/s
|
||||||
|
4 1FB3C 0 1282A8F 0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/net/rpc
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/net/rpc/nfs
|
||||||
|
Lines: 5
|
||||||
|
net 18628 0 18628 6
|
||||||
|
rpc 4329785 0 4338291
|
||||||
|
proc2 18 2 69 0 0 4410 0 0 0 0 0 0 0 0 0 0 0 99 2
|
||||||
|
proc3 22 1 4084749 29200 94754 32580 186 47747 7981 8639 0 6356 0 6962 0 7958 0 0 241 4 4 2 39
|
||||||
|
proc4 61 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/net/rpc/nfsd
|
||||||
|
Lines: 11
|
||||||
|
rc 0 6 18622
|
||||||
|
fh 0 0 0 0 0
|
||||||
|
io 157286400 0
|
||||||
|
th 8 0 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
|
||||||
|
ra 32 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
net 18628 0 18628 6
|
||||||
|
rpc 18628 0 0 0 0
|
||||||
|
proc2 18 2 69 0 0 4410 0 0 0 0 0 0 0 0 0 0 0 99 2
|
||||||
|
proc3 22 2 112 0 2719 111 0 0 0 0 0 0 0 0 0 0 0 27 216 0 2 1 0
|
||||||
|
proc4 2 2 10853
|
||||||
|
proc4ops 72 0 0 0 1098 2 0 0 0 0 8179 5896 0 0 0 0 5900 0 0 2 0 2 0 9609 0 2 150 1272 0 0 0 1236 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/net/xfrm_stat
|
||||||
|
Lines: 28
|
||||||
|
XfrmInError 1
|
||||||
|
XfrmInBufferError 2
|
||||||
|
XfrmInHdrError 4
|
||||||
|
XfrmInNoStates 3
|
||||||
|
XfrmInStateProtoError 40
|
||||||
|
XfrmInStateModeError 100
|
||||||
|
XfrmInStateSeqError 6000
|
||||||
|
XfrmInStateExpired 4
|
||||||
|
XfrmInStateMismatch 23451
|
||||||
|
XfrmInStateInvalid 55555
|
||||||
|
XfrmInTmplMismatch 51
|
||||||
|
XfrmInNoPols 65432
|
||||||
|
XfrmInPolBlock 100
|
||||||
|
XfrmInPolError 10000
|
||||||
|
XfrmOutError 1000000
|
||||||
|
XfrmOutBundleGenError 43321
|
||||||
|
XfrmOutBundleCheckError 555
|
||||||
|
XfrmOutNoStates 869
|
||||||
|
XfrmOutStateProtoError 4542
|
||||||
|
XfrmOutStateModeError 4
|
||||||
|
XfrmOutStateSeqError 543
|
||||||
|
XfrmOutStateExpired 565
|
||||||
|
XfrmOutPolBlock 43456
|
||||||
|
XfrmOutPolDead 7656
|
||||||
|
XfrmOutPolError 1454
|
||||||
|
XfrmFwdHdrError 6654
|
||||||
|
XfrmOutStateInvalid 28765
|
||||||
|
XfrmAcquireError 24532
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/self
|
||||||
|
SymlinkTo: 26231
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/stat
|
||||||
|
Lines: 16
|
||||||
|
cpu 301854 612 111922 8979004 3552 2 3944 0 0 0
|
||||||
|
cpu0 44490 19 21045 1087069 220 1 3410 0 0 0
|
||||||
|
cpu1 47869 23 16474 1110787 591 0 46 0 0 0
|
||||||
|
cpu2 46504 36 15916 1112321 441 0 326 0 0 0
|
||||||
|
cpu3 47054 102 15683 1113230 533 0 60 0 0 0
|
||||||
|
cpu4 28413 25 10776 1140321 217 0 8 0 0 0
|
||||||
|
cpu5 29271 101 11586 1136270 672 0 30 0 0 0
|
||||||
|
cpu6 29152 36 10276 1139721 319 0 29 0 0 0
|
||||||
|
cpu7 29098 268 10164 1139282 555 0 31 0 0 0
|
||||||
|
intr 8885917 17 0 0 0 0 0 0 0 1 79281 0 0 0 0 0 0 0 231237 0 0 0 0 250586 103 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 223424 190745 13 906 1283803 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
ctxt 38014093
|
||||||
|
btime 1418183276
|
||||||
|
processes 26442
|
||||||
|
procs_running 2
|
||||||
|
procs_blocked 1
|
||||||
|
softirq 5057579 250191 1481983 1647 211099 186066 0 1783454 622196 12499 508444
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/symlinktargets
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/symlinktargets/README
|
||||||
|
Lines: 2
|
||||||
|
This directory contains some empty files that are the symlinks the files in the "fd" directory point to.
|
||||||
|
They are otherwise ignored by the tests
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/symlinktargets/abc
|
||||||
|
Lines: 0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/symlinktargets/def
|
||||||
|
Lines: 0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/symlinktargets/ghi
|
||||||
|
Lines: 0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/symlinktargets/uvw
|
||||||
|
Lines: 0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/symlinktargets/xyz
|
||||||
|
Lines: 0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
BIN
vendor/github.com/prometheus/procfs/fixtures/26231/cmdline
generated
vendored
BIN
vendor/github.com/prometheus/procfs/fixtures/26231/cmdline
generated
vendored
Binary file not shown.
1
vendor/github.com/prometheus/procfs/fixtures/26231/comm
generated
vendored
1
vendor/github.com/prometheus/procfs/fixtures/26231/comm
generated
vendored
@ -1 +0,0 @@
|
|||||||
vim
|
|
1
vendor/github.com/prometheus/procfs/fixtures/26231/exe
generated
vendored
1
vendor/github.com/prometheus/procfs/fixtures/26231/exe
generated
vendored
@ -1 +0,0 @@
|
|||||||
/usr/bin/vim
|
|
1
vendor/github.com/prometheus/procfs/fixtures/26231/fd/0
generated
vendored
1
vendor/github.com/prometheus/procfs/fixtures/26231/fd/0
generated
vendored
@ -1 +0,0 @@
|
|||||||
../../symlinktargets/abc
|
|
1
vendor/github.com/prometheus/procfs/fixtures/26231/fd/1
generated
vendored
1
vendor/github.com/prometheus/procfs/fixtures/26231/fd/1
generated
vendored
@ -1 +0,0 @@
|
|||||||
../../symlinktargets/def
|
|
1
vendor/github.com/prometheus/procfs/fixtures/26231/fd/10
generated
vendored
1
vendor/github.com/prometheus/procfs/fixtures/26231/fd/10
generated
vendored
@ -1 +0,0 @@
|
|||||||
../../symlinktargets/xyz
|
|
1
vendor/github.com/prometheus/procfs/fixtures/26231/fd/2
generated
vendored
1
vendor/github.com/prometheus/procfs/fixtures/26231/fd/2
generated
vendored
@ -1 +0,0 @@
|
|||||||
../../symlinktargets/ghi
|
|
1
vendor/github.com/prometheus/procfs/fixtures/26231/fd/3
generated
vendored
1
vendor/github.com/prometheus/procfs/fixtures/26231/fd/3
generated
vendored
@ -1 +0,0 @@
|
|||||||
../../symlinktargets/uvw
|
|
7
vendor/github.com/prometheus/procfs/fixtures/26231/io
generated
vendored
7
vendor/github.com/prometheus/procfs/fixtures/26231/io
generated
vendored
@ -1,7 +0,0 @@
|
|||||||
rchar: 750339
|
|
||||||
wchar: 818609
|
|
||||||
syscr: 7405
|
|
||||||
syscw: 5245
|
|
||||||
read_bytes: 1024
|
|
||||||
write_bytes: 2048
|
|
||||||
cancelled_write_bytes: -1024
|
|
17
vendor/github.com/prometheus/procfs/fixtures/26231/limits
generated
vendored
17
vendor/github.com/prometheus/procfs/fixtures/26231/limits
generated
vendored
@ -1,17 +0,0 @@
|
|||||||
Limit Soft Limit Hard Limit Units
|
|
||||||
Max cpu time unlimited unlimited seconds
|
|
||||||
Max file size unlimited unlimited bytes
|
|
||||||
Max data size unlimited unlimited bytes
|
|
||||||
Max stack size 8388608 unlimited bytes
|
|
||||||
Max core file size 0 unlimited bytes
|
|
||||||
Max resident set unlimited unlimited bytes
|
|
||||||
Max processes 62898 62898 processes
|
|
||||||
Max open files 2048 4096 files
|
|
||||||
Max locked memory 65536 65536 bytes
|
|
||||||
Max address space 8589934592 unlimited bytes
|
|
||||||
Max file locks unlimited unlimited locks
|
|
||||||
Max pending signals 62898 62898 signals
|
|
||||||
Max msgqueue size 819200 819200 bytes
|
|
||||||
Max nice priority 0 0
|
|
||||||
Max realtime priority 0 0
|
|
||||||
Max realtime timeout unlimited unlimited us
|
|
19
vendor/github.com/prometheus/procfs/fixtures/26231/mountstats
generated
vendored
19
vendor/github.com/prometheus/procfs/fixtures/26231/mountstats
generated
vendored
@ -1,19 +0,0 @@
|
|||||||
device rootfs mounted on / with fstype rootfs
|
|
||||||
device sysfs mounted on /sys with fstype sysfs
|
|
||||||
device proc mounted on /proc with fstype proc
|
|
||||||
device /dev/sda1 mounted on / with fstype ext4
|
|
||||||
device 192.168.1.1:/srv/test mounted on /mnt/nfs/test with fstype nfs4 statvers=1.1
|
|
||||||
opts: rw,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,acregmin=3,acregmax=60,acdirmin=30,acdirmax=60,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.5,local_lock=none
|
|
||||||
age: 13968
|
|
||||||
caps: caps=0xfff7,wtmult=512,dtsize=32768,bsize=0,namlen=255
|
|
||||||
nfsv4: bm0=0xfdffafff,bm1=0xf9be3e,bm2=0x0,acl=0x0,pnfs=not configured
|
|
||||||
sec: flavor=1,pseudoflavor=1
|
|
||||||
events: 52 226 0 0 1 13 398 0 0 331 0 47 0 0 77 0 0 77 0 0 0 0 0 0 0 0 0
|
|
||||||
bytes: 1207640230 0 0 0 1210214218 0 295483 0
|
|
||||||
RPC iostats version: 1.0 p/v: 100003/4 (nfs)
|
|
||||||
xprt: tcp 832 0 1 0 11 6428 6428 0 12154 0 24 26 5726
|
|
||||||
per-op statistics
|
|
||||||
NULL: 0 0 0 0 0 0 0 0
|
|
||||||
READ: 1298 1298 0 207680 1210292152 6 79386 79407
|
|
||||||
WRITE: 0 0 0 0 0 0 0 0
|
|
||||||
|
|
1
vendor/github.com/prometheus/procfs/fixtures/26231/stat
generated
vendored
1
vendor/github.com/prometheus/procfs/fixtures/26231/stat
generated
vendored
@ -1 +0,0 @@
|
|||||||
26231 (vim) R 5392 7446 5392 34835 7446 4218880 32533 309516 26 82 1677 44 158 99 20 0 1 0 82375 56274944 1981 18446744073709551615 4194304 6294284 140736914091744 140736914087944 139965136429984 0 0 12288 1870679807 0 0 0 17 0 0 0 31 0 0 8391624 8481048 16420864 140736914093252 140736914093279 140736914093279 140736914096107 0
|
|
0
vendor/github.com/prometheus/procfs/fixtures/26232/cmdline
generated
vendored
0
vendor/github.com/prometheus/procfs/fixtures/26232/cmdline
generated
vendored
1
vendor/github.com/prometheus/procfs/fixtures/26232/comm
generated
vendored
1
vendor/github.com/prometheus/procfs/fixtures/26232/comm
generated
vendored
@ -1 +0,0 @@
|
|||||||
ata_sff
|
|
1
vendor/github.com/prometheus/procfs/fixtures/26232/fd/0
generated
vendored
1
vendor/github.com/prometheus/procfs/fixtures/26232/fd/0
generated
vendored
@ -1 +0,0 @@
|
|||||||
../../symlinktargets/abc
|
|
1
vendor/github.com/prometheus/procfs/fixtures/26232/fd/1
generated
vendored
1
vendor/github.com/prometheus/procfs/fixtures/26232/fd/1
generated
vendored
@ -1 +0,0 @@
|
|||||||
../../symlinktargets/def
|
|
1
vendor/github.com/prometheus/procfs/fixtures/26232/fd/2
generated
vendored
1
vendor/github.com/prometheus/procfs/fixtures/26232/fd/2
generated
vendored
@ -1 +0,0 @@
|
|||||||
../../symlinktargets/ghi
|
|
1
vendor/github.com/prometheus/procfs/fixtures/26232/fd/3
generated
vendored
1
vendor/github.com/prometheus/procfs/fixtures/26232/fd/3
generated
vendored
@ -1 +0,0 @@
|
|||||||
../../symlinktargets/uvw
|
|
1
vendor/github.com/prometheus/procfs/fixtures/26232/fd/4
generated
vendored
1
vendor/github.com/prometheus/procfs/fixtures/26232/fd/4
generated
vendored
@ -1 +0,0 @@
|
|||||||
../../symlinktargets/xyz
|
|
17
vendor/github.com/prometheus/procfs/fixtures/26232/limits
generated
vendored
17
vendor/github.com/prometheus/procfs/fixtures/26232/limits
generated
vendored
@ -1,17 +0,0 @@
|
|||||||
Limit Soft Limit Hard Limit Units
|
|
||||||
Max cpu time unlimited unlimited seconds
|
|
||||||
Max file size unlimited unlimited bytes
|
|
||||||
Max data size unlimited unlimited bytes
|
|
||||||
Max stack size 8388608 unlimited bytes
|
|
||||||
Max core file size 0 unlimited bytes
|
|
||||||
Max resident set unlimited unlimited bytes
|
|
||||||
Max processes 29436 29436 processes
|
|
||||||
Max open files 1024 4096 files
|
|
||||||
Max locked memory 65536 65536 bytes
|
|
||||||
Max address space unlimited unlimited bytes
|
|
||||||
Max file locks unlimited unlimited locks
|
|
||||||
Max pending signals 29436 29436 signals
|
|
||||||
Max msgqueue size 819200 819200 bytes
|
|
||||||
Max nice priority 0 0
|
|
||||||
Max realtime priority 0 0
|
|
||||||
Max realtime timeout unlimited unlimited us
|
|
1
vendor/github.com/prometheus/procfs/fixtures/26232/stat
generated
vendored
1
vendor/github.com/prometheus/procfs/fixtures/26232/stat
generated
vendored
@ -1 +0,0 @@
|
|||||||
33 (ata_sff) S 2 0 0 0 -1 69238880 0 0 0 0 0 0 0 0 0 -20 1 0 5 0 0 18446744073709551615 0 0 0 0 0 0 0 2147483647 0 18446744073709551615 0 0 17 1 0 0 0 0 0 0 0 0 0 0 0 0 0
|
|
2
vendor/github.com/prometheus/procfs/fixtures/584/stat
generated
vendored
2
vendor/github.com/prometheus/procfs/fixtures/584/stat
generated
vendored
@ -1,2 +0,0 @@
|
|||||||
1020 ((a b ) ( c d) ) R 28378 1020 28378 34842 1020 4218880 286 0 0 0 0 0 0 0 20 0 1 0 10839175 10395648 155 18446744073709551615 4194304 4238788 140736466511168 140736466511168 140609271124624 0 0 0 0 0 0 0 17 5 0 0 0 0 0 6336016 6337300 25579520 140736466515030 140736466515061 140736466515061 140736466518002 0
|
|
||||||
#!/bin/cat /proc/self/stat
|
|
3
vendor/github.com/prometheus/procfs/fixtures/buddyinfo/short/buddyinfo
generated
vendored
3
vendor/github.com/prometheus/procfs/fixtures/buddyinfo/short/buddyinfo
generated
vendored
@ -1,3 +0,0 @@
|
|||||||
Node 0, zone
|
|
||||||
Node 0, zone
|
|
||||||
Node 0, zone
|
|
3
vendor/github.com/prometheus/procfs/fixtures/buddyinfo/sizemismatch/buddyinfo
generated
vendored
3
vendor/github.com/prometheus/procfs/fixtures/buddyinfo/sizemismatch/buddyinfo
generated
vendored
@ -1,3 +0,0 @@
|
|||||||
Node 0, zone DMA 1 0 1 0 2 1 1 0 1 1 3
|
|
||||||
Node 0, zone DMA32 759 572 791 475 194 45 12 0 0 0 0 0
|
|
||||||
Node 0, zone Normal 4381 1093 185 1530 567 102 4 0 0 0
|
|
3
vendor/github.com/prometheus/procfs/fixtures/buddyinfo/valid/buddyinfo
generated
vendored
3
vendor/github.com/prometheus/procfs/fixtures/buddyinfo/valid/buddyinfo
generated
vendored
@ -1,3 +0,0 @@
|
|||||||
Node 0, zone DMA 1 0 1 0 2 1 1 0 1 1 3
|
|
||||||
Node 0, zone DMA32 759 572 791 475 194 45 12 0 0 0 0
|
|
||||||
Node 0, zone Normal 4381 1093 185 1530 567 102 4 0 0 0 0
|
|
23
vendor/github.com/prometheus/procfs/fixtures/fs/xfs/stat
generated
vendored
23
vendor/github.com/prometheus/procfs/fixtures/fs/xfs/stat
generated
vendored
@ -1,23 +0,0 @@
|
|||||||
extent_alloc 92447 97589 92448 93751
|
|
||||||
abt 0 0 0 0
|
|
||||||
blk_map 1767055 188820 184891 92447 92448 2140766 0
|
|
||||||
bmbt 0 0 0 0
|
|
||||||
dir 185039 92447 92444 136422
|
|
||||||
trans 706 944304 0
|
|
||||||
ig 185045 58807 0 126238 0 33637 22
|
|
||||||
log 2883 113448 9 17360 739
|
|
||||||
push_ail 945014 0 134260 15483 0 3940 464 159985 0 40
|
|
||||||
xstrat 92447 0
|
|
||||||
rw 107739 94045
|
|
||||||
attr 4 0 0 0
|
|
||||||
icluster 8677 7849 135802
|
|
||||||
vnodes 92601 0 0 0 92444 92444 92444 0
|
|
||||||
buf 2666287 7122 2659202 3599 2 7085 0 10297 7085
|
|
||||||
abtb2 184941 1277345 13257 13278 0 0 0 0 0 0 0 0 0 0 2746147
|
|
||||||
abtc2 345295 2416764 172637 172658 0 0 0 0 0 0 0 0 0 0 21406023
|
|
||||||
bmbt2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
|
||||||
ibt2 343004 1358467 0 0 0 0 0 0 0 0 0 0 0 0 0
|
|
||||||
fibt2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
|
||||||
qm 0 0 0 0 0 0 0 0
|
|
||||||
xpc 399724544 92823103 86219234
|
|
||||||
debug 0
|
|
26
vendor/github.com/prometheus/procfs/fixtures/mdstat
generated
vendored
26
vendor/github.com/prometheus/procfs/fixtures/mdstat
generated
vendored
@ -1,26 +0,0 @@
|
|||||||
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
|
|
||||||
md3 : active raid6 sda1[8] sdh1[7] sdg1[6] sdf1[5] sde1[11] sdd1[3] sdc1[10] sdb1[9]
|
|
||||||
5853468288 blocks super 1.2 level 6, 64k chunk, algorithm 2 [8/8] [UUUUUUUU]
|
|
||||||
|
|
||||||
md127 : active raid1 sdi2[0] sdj2[1]
|
|
||||||
312319552 blocks [2/2] [UU]
|
|
||||||
|
|
||||||
md0 : active raid1 sdk[2](S) sdi1[0] sdj1[1]
|
|
||||||
248896 blocks [2/2] [UU]
|
|
||||||
|
|
||||||
md4 : inactive raid1 sda3[0] sdb3[1]
|
|
||||||
4883648 blocks [2/2] [UU]
|
|
||||||
|
|
||||||
md6 : active raid1 sdb2[2] sda2[0]
|
|
||||||
195310144 blocks [2/1] [U_]
|
|
||||||
[=>...................] recovery = 8.5% (16775552/195310144) finish=17.0min speed=259783K/sec
|
|
||||||
|
|
||||||
md8 : active raid1 sdb1[1] sda1[0]
|
|
||||||
195310144 blocks [2/2] [UU]
|
|
||||||
[=>...................] resync = 8.5% (16775552/195310144) finish=17.0min speed=259783K/sec
|
|
||||||
|
|
||||||
md7 : active raid6 sdb1[0] sde1[3] sdd1[2] sdc1[1]
|
|
||||||
7813735424 blocks super 1.2 level 6, 512k chunk, algorithm 2 [4/3] [U_UU]
|
|
||||||
bitmap: 0/30 pages [0KB], 65536KB chunk
|
|
||||||
|
|
||||||
unused devices: <none>
|
|
21
vendor/github.com/prometheus/procfs/fixtures/net/ip_vs
generated
vendored
21
vendor/github.com/prometheus/procfs/fixtures/net/ip_vs
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
IP Virtual Server version 1.2.1 (size=4096)
|
|
||||||
Prot LocalAddress:Port Scheduler Flags
|
|
||||||
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
|
|
||||||
TCP C0A80016:0CEA wlc
|
|
||||||
-> C0A85216:0CEA Tunnel 100 248 2
|
|
||||||
-> C0A85318:0CEA Tunnel 100 248 2
|
|
||||||
-> C0A85315:0CEA Tunnel 100 248 1
|
|
||||||
TCP C0A80039:0CEA wlc
|
|
||||||
-> C0A85416:0CEA Tunnel 0 0 0
|
|
||||||
-> C0A85215:0CEA Tunnel 100 1499 0
|
|
||||||
-> C0A83215:0CEA Tunnel 100 1498 0
|
|
||||||
TCP C0A80037:0CEA wlc
|
|
||||||
-> C0A8321A:0CEA Tunnel 0 0 0
|
|
||||||
-> C0A83120:0CEA Tunnel 100 0 0
|
|
||||||
TCP [2620:0000:0000:0000:0000:0000:0000:0001]:0050 sh
|
|
||||||
-> [2620:0000:0000:0000:0000:0000:0000:0002]:0050 Route 1 0 0
|
|
||||||
-> [2620:0000:0000:0000:0000:0000:0000:0003]:0050 Route 1 0 0
|
|
||||||
-> [2620:0000:0000:0000:0000:0000:0000:0004]:0050 Route 1 1 1
|
|
||||||
FWM 10001000 wlc
|
|
||||||
-> C0A8321A:0CEA Route 0 0 1
|
|
||||||
-> C0A83215:0CEA Route 0 0 2
|
|
6
vendor/github.com/prometheus/procfs/fixtures/net/ip_vs_stats
generated
vendored
6
vendor/github.com/prometheus/procfs/fixtures/net/ip_vs_stats
generated
vendored
@ -1,6 +0,0 @@
|
|||||||
Total Incoming Outgoing Incoming Outgoing
|
|
||||||
Conns Packets Packets Bytes Bytes
|
|
||||||
16AA370 E33656E5 0 51D8C8883AB3 0
|
|
||||||
|
|
||||||
Conns/s Pkts/s Pkts/s Bytes/s Bytes/s
|
|
||||||
4 1FB3C 0 1282A8F 0
|
|
28
vendor/github.com/prometheus/procfs/fixtures/net/xfrm_stat
generated
vendored
28
vendor/github.com/prometheus/procfs/fixtures/net/xfrm_stat
generated
vendored
@ -1,28 +0,0 @@
|
|||||||
XfrmInError 1
|
|
||||||
XfrmInBufferError 2
|
|
||||||
XfrmInHdrError 4
|
|
||||||
XfrmInNoStates 3
|
|
||||||
XfrmInStateProtoError 40
|
|
||||||
XfrmInStateModeError 100
|
|
||||||
XfrmInStateSeqError 6000
|
|
||||||
XfrmInStateExpired 4
|
|
||||||
XfrmInStateMismatch 23451
|
|
||||||
XfrmInStateInvalid 55555
|
|
||||||
XfrmInTmplMismatch 51
|
|
||||||
XfrmInNoPols 65432
|
|
||||||
XfrmInPolBlock 100
|
|
||||||
XfrmInPolError 10000
|
|
||||||
XfrmOutError 1000000
|
|
||||||
XfrmOutBundleGenError 43321
|
|
||||||
XfrmOutBundleCheckError 555
|
|
||||||
XfrmOutNoStates 869
|
|
||||||
XfrmOutStateProtoError 4542
|
|
||||||
XfrmOutStateModeError 4
|
|
||||||
XfrmOutStateSeqError 543
|
|
||||||
XfrmOutStateExpired 565
|
|
||||||
XfrmOutPolBlock 43456
|
|
||||||
XfrmOutPolDead 7656
|
|
||||||
XfrmOutPolError 1454
|
|
||||||
XfrmFwdHdrError 6654
|
|
||||||
XfrmOutStateInvalid 28765
|
|
||||||
XfrmAcquireError 24532
|
|
1
vendor/github.com/prometheus/procfs/fixtures/self
generated
vendored
1
vendor/github.com/prometheus/procfs/fixtures/self
generated
vendored
@ -1 +0,0 @@
|
|||||||
26231
|
|
16
vendor/github.com/prometheus/procfs/fixtures/stat
generated
vendored
16
vendor/github.com/prometheus/procfs/fixtures/stat
generated
vendored
@ -1,16 +0,0 @@
|
|||||||
cpu 301854 612 111922 8979004 3552 2 3944 0 0 0
|
|
||||||
cpu0 44490 19 21045 1087069 220 1 3410 0 0 0
|
|
||||||
cpu1 47869 23 16474 1110787 591 0 46 0 0 0
|
|
||||||
cpu2 46504 36 15916 1112321 441 0 326 0 0 0
|
|
||||||
cpu3 47054 102 15683 1113230 533 0 60 0 0 0
|
|
||||||
cpu4 28413 25 10776 1140321 217 0 8 0 0 0
|
|
||||||
cpu5 29271 101 11586 1136270 672 0 30 0 0 0
|
|
||||||
cpu6 29152 36 10276 1139721 319 0 29 0 0 0
|
|
||||||
cpu7 29098 268 10164 1139282 555 0 31 0 0 0
|
|
||||||
intr 8885917 17 0 0 0 0 0 0 0 1 79281 0 0 0 0 0 0 0 231237 0 0 0 0 250586 103 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 223424 190745 13 906 1283803 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
|
||||||
ctxt 38014093
|
|
||||||
btime 1418183276
|
|
||||||
processes 26442
|
|
||||||
procs_running 2
|
|
||||||
procs_blocked 1
|
|
||||||
softirq 5057579 250191 1481983 1647 211099 186066 0 1783454 622196 12499 508444
|
|
2
vendor/github.com/prometheus/procfs/fixtures/symlinktargets/README
generated
vendored
2
vendor/github.com/prometheus/procfs/fixtures/symlinktargets/README
generated
vendored
@ -1,2 +0,0 @@
|
|||||||
This directory contains some empty files that are the symlinks the files in the "fd" directory point to.
|
|
||||||
They are otherwise ignored by the tests
|
|
0
vendor/github.com/prometheus/procfs/fixtures/symlinktargets/abc
generated
vendored
0
vendor/github.com/prometheus/procfs/fixtures/symlinktargets/abc
generated
vendored
0
vendor/github.com/prometheus/procfs/fixtures/symlinktargets/def
generated
vendored
0
vendor/github.com/prometheus/procfs/fixtures/symlinktargets/def
generated
vendored
0
vendor/github.com/prometheus/procfs/fixtures/symlinktargets/ghi
generated
vendored
0
vendor/github.com/prometheus/procfs/fixtures/symlinktargets/ghi
generated
vendored
0
vendor/github.com/prometheus/procfs/fixtures/symlinktargets/uvw
generated
vendored
0
vendor/github.com/prometheus/procfs/fixtures/symlinktargets/uvw
generated
vendored
0
vendor/github.com/prometheus/procfs/fixtures/symlinktargets/xyz
generated
vendored
0
vendor/github.com/prometheus/procfs/fixtures/symlinktargets/xyz
generated
vendored
36
vendor/github.com/prometheus/procfs/fs.go
generated
vendored
36
vendor/github.com/prometheus/procfs/fs.go
generated
vendored
@ -1,3 +1,16 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package procfs
|
package procfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -5,6 +18,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
|
"github.com/prometheus/procfs/nfs"
|
||||||
"github.com/prometheus/procfs/xfs"
|
"github.com/prometheus/procfs/xfs"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -44,3 +58,25 @@ func (fs FS) XFSStats() (*xfs.Stats, error) {
|
|||||||
|
|
||||||
return xfs.ParseStats(f)
|
return xfs.ParseStats(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NFSClientRPCStats retrieves NFS client RPC statistics.
|
||||||
|
func (fs FS) NFSClientRPCStats() (*nfs.ClientRPCStats, error) {
|
||||||
|
f, err := os.Open(fs.Path("net/rpc/nfs"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
return nfs.ParseClientRPCStats(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NFSdServerRPCStats retrieves NFS daemon RPC statistics.
|
||||||
|
func (fs FS) NFSdServerRPCStats() (*nfs.ServerRPCStats, error) {
|
||||||
|
f, err := os.Open(fs.Path("net/rpc/nfsd"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
return nfs.ParseServerRPCStats(f)
|
||||||
|
}
|
||||||
|
13
vendor/github.com/prometheus/procfs/fs_test.go
generated
vendored
13
vendor/github.com/prometheus/procfs/fs_test.go
generated
vendored
@ -1,3 +1,16 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package procfs
|
package procfs
|
||||||
|
|
||||||
import "testing"
|
import "testing"
|
||||||
|
46
vendor/github.com/prometheus/procfs/internal/util/parse.go
generated
vendored
Normal file
46
vendor/github.com/prometheus/procfs/internal/util/parse.go
generated
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package util
|
||||||
|
|
||||||
|
import "strconv"
|
||||||
|
|
||||||
|
// ParseUint32s parses a slice of strings into a slice of uint32s.
|
||||||
|
func ParseUint32s(ss []string) ([]uint32, error) {
|
||||||
|
us := make([]uint32, 0, len(ss))
|
||||||
|
for _, s := range ss {
|
||||||
|
u, err := strconv.ParseUint(s, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
us = append(us, uint32(u))
|
||||||
|
}
|
||||||
|
|
||||||
|
return us, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseUint64s parses a slice of strings into a slice of uint64s.
|
||||||
|
func ParseUint64s(ss []string) ([]uint64, error) {
|
||||||
|
us := make([]uint64, 0, len(ss))
|
||||||
|
for _, s := range ss {
|
||||||
|
u, err := strconv.ParseUint(s, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
us = append(us, u)
|
||||||
|
}
|
||||||
|
|
||||||
|
return us, nil
|
||||||
|
}
|
23
vendor/github.com/prometheus/procfs/ipvs.go
generated
vendored
23
vendor/github.com/prometheus/procfs/ipvs.go
generated
vendored
@ -1,3 +1,16 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package procfs
|
package procfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -31,16 +44,16 @@ type IPVSStats struct {
|
|||||||
type IPVSBackendStatus struct {
|
type IPVSBackendStatus struct {
|
||||||
// The local (virtual) IP address.
|
// The local (virtual) IP address.
|
||||||
LocalAddress net.IP
|
LocalAddress net.IP
|
||||||
|
// The remote (real) IP address.
|
||||||
|
RemoteAddress net.IP
|
||||||
// The local (virtual) port.
|
// The local (virtual) port.
|
||||||
LocalPort uint16
|
LocalPort uint16
|
||||||
|
// The remote (real) port.
|
||||||
|
RemotePort uint16
|
||||||
// The local firewall mark
|
// The local firewall mark
|
||||||
LocalMark string
|
LocalMark string
|
||||||
// The transport protocol (TCP, UDP).
|
// The transport protocol (TCP, UDP).
|
||||||
Proto string
|
Proto string
|
||||||
// The remote (real) IP address.
|
|
||||||
RemoteAddress net.IP
|
|
||||||
// The remote (real) port.
|
|
||||||
RemotePort uint16
|
|
||||||
// The current number of active connections for this virtual/real address pair.
|
// The current number of active connections for this virtual/real address pair.
|
||||||
ActiveConn uint64
|
ActiveConn uint64
|
||||||
// The current number of inactive connections for this virtual/real address pair.
|
// The current number of inactive connections for this virtual/real address pair.
|
||||||
@ -151,7 +164,7 @@ func parseIPVSBackendStatus(file io.Reader) ([]IPVSBackendStatus, error) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
fields := strings.Fields(string(scanner.Text()))
|
fields := strings.Fields(scanner.Text())
|
||||||
if len(fields) == 0 {
|
if len(fields) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
13
vendor/github.com/prometheus/procfs/ipvs_test.go
generated
vendored
13
vendor/github.com/prometheus/procfs/ipvs_test.go
generated
vendored
@ -1,3 +1,16 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package procfs
|
package procfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
13
vendor/github.com/prometheus/procfs/mdstat.go
generated
vendored
13
vendor/github.com/prometheus/procfs/mdstat.go
generated
vendored
@ -1,3 +1,16 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package procfs
|
package procfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
13
vendor/github.com/prometheus/procfs/mdstat_test.go
generated
vendored
13
vendor/github.com/prometheus/procfs/mdstat_test.go
generated
vendored
@ -1,3 +1,16 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package procfs
|
package procfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
13
vendor/github.com/prometheus/procfs/mountstats.go
generated
vendored
13
vendor/github.com/prometheus/procfs/mountstats.go
generated
vendored
@ -1,3 +1,16 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package procfs
|
package procfs
|
||||||
|
|
||||||
// While implementing parsing of /proc/[pid]/mountstats, this blog was used
|
// While implementing parsing of /proc/[pid]/mountstats, this blog was used
|
||||||
|
13
vendor/github.com/prometheus/procfs/mountstats_test.go
generated
vendored
13
vendor/github.com/prometheus/procfs/mountstats_test.go
generated
vendored
@ -1,3 +1,16 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package procfs
|
package procfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
216
vendor/github.com/prometheus/procfs/net_dev.go
generated
vendored
Normal file
216
vendor/github.com/prometheus/procfs/net_dev.go
generated
vendored
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package procfs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NetDevLine is single line parsed from /proc/net/dev or /proc/[pid]/net/dev.
|
||||||
|
type NetDevLine struct {
|
||||||
|
Name string `json:"name"` // The name of the interface.
|
||||||
|
RxBytes uint64 `json:"rx_bytes"` // Cumulative count of bytes received.
|
||||||
|
RxPackets uint64 `json:"rx_packets"` // Cumulative count of packets received.
|
||||||
|
RxErrors uint64 `json:"rx_errors"` // Cumulative count of receive errors encountered.
|
||||||
|
RxDropped uint64 `json:"rx_dropped"` // Cumulative count of packets dropped while receiving.
|
||||||
|
RxFIFO uint64 `json:"rx_fifo"` // Cumulative count of FIFO buffer errors.
|
||||||
|
RxFrame uint64 `json:"rx_frame"` // Cumulative count of packet framing errors.
|
||||||
|
RxCompressed uint64 `json:"rx_compressed"` // Cumulative count of compressed packets received by the device driver.
|
||||||
|
RxMulticast uint64 `json:"rx_multicast"` // Cumulative count of multicast frames received by the device driver.
|
||||||
|
TxBytes uint64 `json:"tx_bytes"` // Cumulative count of bytes transmitted.
|
||||||
|
TxPackets uint64 `json:"tx_packets"` // Cumulative count of packets transmitted.
|
||||||
|
TxErrors uint64 `json:"tx_errors"` // Cumulative count of transmit errors encountered.
|
||||||
|
TxDropped uint64 `json:"tx_dropped"` // Cumulative count of packets dropped while transmitting.
|
||||||
|
TxFIFO uint64 `json:"tx_fifo"` // Cumulative count of FIFO buffer errors.
|
||||||
|
TxCollisions uint64 `json:"tx_collisions"` // Cumulative count of collisions detected on the interface.
|
||||||
|
TxCarrier uint64 `json:"tx_carrier"` // Cumulative count of carrier losses detected by the device driver.
|
||||||
|
TxCompressed uint64 `json:"tx_compressed"` // Cumulative count of compressed packets transmitted by the device driver.
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetDev is parsed from /proc/net/dev or /proc/[pid]/net/dev. The map keys
|
||||||
|
// are interface names.
|
||||||
|
type NetDev map[string]NetDevLine
|
||||||
|
|
||||||
|
// NewNetDev returns kernel/system statistics read from /proc/net/dev.
|
||||||
|
func NewNetDev() (NetDev, error) {
|
||||||
|
fs, err := NewFS(DefaultMountPoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return fs.NewNetDev()
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNetDev returns kernel/system statistics read from /proc/net/dev.
|
||||||
|
func (fs FS) NewNetDev() (NetDev, error) {
|
||||||
|
return newNetDev(fs.Path("net/dev"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNetDev returns kernel/system statistics read from /proc/[pid]/net/dev.
|
||||||
|
func (p Proc) NewNetDev() (NetDev, error) {
|
||||||
|
return newNetDev(p.path("net/dev"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// newNetDev creates a new NetDev from the contents of the given file.
|
||||||
|
func newNetDev(file string) (NetDev, error) {
|
||||||
|
f, err := os.Open(file)
|
||||||
|
if err != nil {
|
||||||
|
return NetDev{}, err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
nd := NetDev{}
|
||||||
|
s := bufio.NewScanner(f)
|
||||||
|
for n := 0; s.Scan(); n++ {
|
||||||
|
// Skip the 2 header lines.
|
||||||
|
if n < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
line, err := nd.parseLine(s.Text())
|
||||||
|
if err != nil {
|
||||||
|
return nd, err
|
||||||
|
}
|
||||||
|
|
||||||
|
nd[line.Name] = *line
|
||||||
|
}
|
||||||
|
|
||||||
|
return nd, s.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseLine parses a single line from the /proc/net/dev file. Header lines
|
||||||
|
// must be filtered prior to calling this method.
|
||||||
|
func (nd NetDev) parseLine(rawLine string) (*NetDevLine, error) {
|
||||||
|
parts := strings.SplitN(rawLine, ":", 2)
|
||||||
|
if len(parts) != 2 {
|
||||||
|
return nil, errors.New("invalid net/dev line, missing colon")
|
||||||
|
}
|
||||||
|
fields := strings.Fields(strings.TrimSpace(parts[1]))
|
||||||
|
|
||||||
|
var err error
|
||||||
|
line := &NetDevLine{}
|
||||||
|
|
||||||
|
// Interface Name
|
||||||
|
line.Name = strings.TrimSpace(parts[0])
|
||||||
|
if line.Name == "" {
|
||||||
|
return nil, errors.New("invalid net/dev line, empty interface name")
|
||||||
|
}
|
||||||
|
|
||||||
|
// RX
|
||||||
|
line.RxBytes, err = strconv.ParseUint(fields[0], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
line.RxPackets, err = strconv.ParseUint(fields[1], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
line.RxErrors, err = strconv.ParseUint(fields[2], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
line.RxDropped, err = strconv.ParseUint(fields[3], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
line.RxFIFO, err = strconv.ParseUint(fields[4], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
line.RxFrame, err = strconv.ParseUint(fields[5], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
line.RxCompressed, err = strconv.ParseUint(fields[6], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
line.RxMulticast, err = strconv.ParseUint(fields[7], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TX
|
||||||
|
line.TxBytes, err = strconv.ParseUint(fields[8], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
line.TxPackets, err = strconv.ParseUint(fields[9], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
line.TxErrors, err = strconv.ParseUint(fields[10], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
line.TxDropped, err = strconv.ParseUint(fields[11], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
line.TxFIFO, err = strconv.ParseUint(fields[12], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
line.TxCollisions, err = strconv.ParseUint(fields[13], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
line.TxCarrier, err = strconv.ParseUint(fields[14], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
line.TxCompressed, err = strconv.ParseUint(fields[15], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return line, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Total aggregates the values across interfaces and returns a new NetDevLine.
|
||||||
|
// The Name field will be a sorted comma seperated list of interface names.
|
||||||
|
func (nd NetDev) Total() NetDevLine {
|
||||||
|
total := NetDevLine{}
|
||||||
|
|
||||||
|
names := make([]string, 0, len(nd))
|
||||||
|
for _, ifc := range nd {
|
||||||
|
names = append(names, ifc.Name)
|
||||||
|
total.RxBytes += ifc.RxBytes
|
||||||
|
total.RxPackets += ifc.RxPackets
|
||||||
|
total.RxPackets += ifc.RxPackets
|
||||||
|
total.RxErrors += ifc.RxErrors
|
||||||
|
total.RxDropped += ifc.RxDropped
|
||||||
|
total.RxFIFO += ifc.RxFIFO
|
||||||
|
total.RxFrame += ifc.RxFrame
|
||||||
|
total.RxCompressed += ifc.RxCompressed
|
||||||
|
total.RxMulticast += ifc.RxMulticast
|
||||||
|
total.TxBytes += ifc.TxBytes
|
||||||
|
total.TxPackets += ifc.TxPackets
|
||||||
|
total.TxErrors += ifc.TxErrors
|
||||||
|
total.TxDropped += ifc.TxDropped
|
||||||
|
total.TxFIFO += ifc.TxFIFO
|
||||||
|
total.TxCollisions += ifc.TxCollisions
|
||||||
|
total.TxCarrier += ifc.TxCarrier
|
||||||
|
total.TxCompressed += ifc.TxCompressed
|
||||||
|
}
|
||||||
|
sort.Strings(names)
|
||||||
|
total.Name = strings.Join(names, ", ")
|
||||||
|
|
||||||
|
return total
|
||||||
|
}
|
86
vendor/github.com/prometheus/procfs/net_dev_test.go
generated
vendored
Normal file
86
vendor/github.com/prometheus/procfs/net_dev_test.go
generated
vendored
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package procfs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNetDevParseLine(t *testing.T) {
|
||||||
|
const rawLine = ` eth0: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16`
|
||||||
|
|
||||||
|
have, err := NetDev{}.parseLine(rawLine)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := NetDevLine{"eth0", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
|
||||||
|
if want != *have {
|
||||||
|
t.Errorf("want %v, have %v", want, have)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewNetDev(t *testing.T) {
|
||||||
|
fs, err := NewFS("fixtures")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
nd, err := fs.NewNetDev()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
lines := map[string]NetDevLine{
|
||||||
|
"vethf345468": {Name: "vethf345468", RxBytes: 648, RxPackets: 8, TxBytes: 438, TxPackets: 5},
|
||||||
|
"lo": {Name: "lo", RxBytes: 1664039048, RxPackets: 1566805, TxBytes: 1664039048, TxPackets: 1566805},
|
||||||
|
"docker0": {Name: "docker0", RxBytes: 2568, RxPackets: 38, TxBytes: 438, TxPackets: 5},
|
||||||
|
"eth0": {Name: "eth0", RxBytes: 874354587, RxPackets: 1036395, TxBytes: 563352563, TxPackets: 732147},
|
||||||
|
}
|
||||||
|
|
||||||
|
if want, have := len(lines), len(nd); want != have {
|
||||||
|
t.Errorf("want %d parsed net/dev lines, have %d", want, have)
|
||||||
|
}
|
||||||
|
for _, line := range nd {
|
||||||
|
if want, have := lines[line.Name], line; want != have {
|
||||||
|
t.Errorf("%s: want %v, have %v", line.Name, want, have)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProcNewNetDev(t *testing.T) {
|
||||||
|
p, err := FS("fixtures").NewProc(26231)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
nd, err := p.NewNetDev()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
lines := map[string]NetDevLine{
|
||||||
|
"lo": {Name: "lo"},
|
||||||
|
"eth0": {Name: "eth0", RxBytes: 438, RxPackets: 5, TxBytes: 648, TxPackets: 8},
|
||||||
|
}
|
||||||
|
|
||||||
|
if want, have := len(lines), len(nd); want != have {
|
||||||
|
t.Errorf("want %d parsed net/dev lines, have %d", want, have)
|
||||||
|
}
|
||||||
|
for _, line := range nd {
|
||||||
|
if want, have := lines[line.Name], line; want != have {
|
||||||
|
t.Errorf("%s: want %v, have %v", line.Name, want, have)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
263
vendor/github.com/prometheus/procfs/nfs/nfs.go
generated
vendored
Normal file
263
vendor/github.com/prometheus/procfs/nfs/nfs.go
generated
vendored
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// Package nfsd implements parsing of /proc/net/rpc/nfsd.
|
||||||
|
// Fields are documented in https://www.svennd.be/nfsd-stats-explained-procnetrpcnfsd/
|
||||||
|
package nfs
|
||||||
|
|
||||||
|
// ReplyCache models the "rc" line.
|
||||||
|
type ReplyCache struct {
|
||||||
|
Hits uint64
|
||||||
|
Misses uint64
|
||||||
|
NoCache uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileHandles models the "fh" line.
|
||||||
|
type FileHandles struct {
|
||||||
|
Stale uint64
|
||||||
|
TotalLookups uint64
|
||||||
|
AnonLookups uint64
|
||||||
|
DirNoCache uint64
|
||||||
|
NoDirNoCache uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// InputOutput models the "io" line.
|
||||||
|
type InputOutput struct {
|
||||||
|
Read uint64
|
||||||
|
Write uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// Threads models the "th" line.
|
||||||
|
type Threads struct {
|
||||||
|
Threads uint64
|
||||||
|
FullCnt uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadAheadCache models the "ra" line.
|
||||||
|
type ReadAheadCache struct {
|
||||||
|
CacheSize uint64
|
||||||
|
CacheHistogram []uint64
|
||||||
|
NotFound uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// Network models the "net" line.
|
||||||
|
type Network struct {
|
||||||
|
NetCount uint64
|
||||||
|
UDPCount uint64
|
||||||
|
TCPCount uint64
|
||||||
|
TCPConnect uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientRPC models the nfs "rpc" line.
|
||||||
|
type ClientRPC struct {
|
||||||
|
RPCCount uint64
|
||||||
|
Retransmissions uint64
|
||||||
|
AuthRefreshes uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServerRPC models the nfsd "rpc" line.
|
||||||
|
type ServerRPC struct {
|
||||||
|
RPCCount uint64
|
||||||
|
BadCnt uint64
|
||||||
|
BadFmt uint64
|
||||||
|
BadAuth uint64
|
||||||
|
BadcInt uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// V2Stats models the "proc2" line.
|
||||||
|
type V2Stats struct {
|
||||||
|
Null uint64
|
||||||
|
GetAttr uint64
|
||||||
|
SetAttr uint64
|
||||||
|
Root uint64
|
||||||
|
Lookup uint64
|
||||||
|
ReadLink uint64
|
||||||
|
Read uint64
|
||||||
|
WrCache uint64
|
||||||
|
Write uint64
|
||||||
|
Create uint64
|
||||||
|
Remove uint64
|
||||||
|
Rename uint64
|
||||||
|
Link uint64
|
||||||
|
SymLink uint64
|
||||||
|
MkDir uint64
|
||||||
|
RmDir uint64
|
||||||
|
ReadDir uint64
|
||||||
|
FsStat uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// V3Stats models the "proc3" line.
|
||||||
|
type V3Stats struct {
|
||||||
|
Null uint64
|
||||||
|
GetAttr uint64
|
||||||
|
SetAttr uint64
|
||||||
|
Lookup uint64
|
||||||
|
Access uint64
|
||||||
|
ReadLink uint64
|
||||||
|
Read uint64
|
||||||
|
Write uint64
|
||||||
|
Create uint64
|
||||||
|
MkDir uint64
|
||||||
|
SymLink uint64
|
||||||
|
MkNod uint64
|
||||||
|
Remove uint64
|
||||||
|
RmDir uint64
|
||||||
|
Rename uint64
|
||||||
|
Link uint64
|
||||||
|
ReadDir uint64
|
||||||
|
ReadDirPlus uint64
|
||||||
|
FsStat uint64
|
||||||
|
FsInfo uint64
|
||||||
|
PathConf uint64
|
||||||
|
Commit uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientV4Stats models the nfs "proc4" line.
|
||||||
|
type ClientV4Stats struct {
|
||||||
|
Null uint64
|
||||||
|
Read uint64
|
||||||
|
Write uint64
|
||||||
|
Commit uint64
|
||||||
|
Open uint64
|
||||||
|
OpenConfirm uint64
|
||||||
|
OpenNoattr uint64
|
||||||
|
OpenDowngrade uint64
|
||||||
|
Close uint64
|
||||||
|
Setattr uint64
|
||||||
|
FsInfo uint64
|
||||||
|
Renew uint64
|
||||||
|
SetClientId uint64
|
||||||
|
SetClientIdConfirm uint64
|
||||||
|
Lock uint64
|
||||||
|
Lockt uint64
|
||||||
|
Locku uint64
|
||||||
|
Access uint64
|
||||||
|
Getattr uint64
|
||||||
|
Lookup uint64
|
||||||
|
LookupRoot uint64
|
||||||
|
Remove uint64
|
||||||
|
Rename uint64
|
||||||
|
Link uint64
|
||||||
|
Symlink uint64
|
||||||
|
Create uint64
|
||||||
|
Pathconf uint64
|
||||||
|
StatFs uint64
|
||||||
|
ReadLink uint64
|
||||||
|
ReadDir uint64
|
||||||
|
ServerCaps uint64
|
||||||
|
DelegReturn uint64
|
||||||
|
GetAcl uint64
|
||||||
|
SetAcl uint64
|
||||||
|
FsLocations uint64
|
||||||
|
ReleaseLockowner uint64
|
||||||
|
Secinfo uint64
|
||||||
|
FsidPresent uint64
|
||||||
|
ExchangeId uint64
|
||||||
|
CreateSession uint64
|
||||||
|
DestroySession uint64
|
||||||
|
Sequence uint64
|
||||||
|
GetLeaseTime uint64
|
||||||
|
ReclaimComplete uint64
|
||||||
|
LayoutGet uint64
|
||||||
|
GetDeviceInfo uint64
|
||||||
|
LayoutCommit uint64
|
||||||
|
LayoutReturn uint64
|
||||||
|
SecinfoNoName uint64
|
||||||
|
TestStateId uint64
|
||||||
|
FreeStateId uint64
|
||||||
|
GetDeviceList uint64
|
||||||
|
BindConnToSession uint64
|
||||||
|
DestroyClientId uint64
|
||||||
|
Seek uint64
|
||||||
|
Allocate uint64
|
||||||
|
DeAllocate uint64
|
||||||
|
LayoutStats uint64
|
||||||
|
Clone uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServerV4Stats models the nfsd "proc4" line.
|
||||||
|
type ServerV4Stats struct {
|
||||||
|
Null uint64
|
||||||
|
Compound uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// V4Ops models the "proc4ops" line: NFSv4 operations
|
||||||
|
// Variable list, see:
|
||||||
|
// v4.0 https://tools.ietf.org/html/rfc3010 (38 operations)
|
||||||
|
// v4.1 https://tools.ietf.org/html/rfc5661 (58 operations)
|
||||||
|
// v4.2 https://tools.ietf.org/html/draft-ietf-nfsv4-minorversion2-41 (71 operations)
|
||||||
|
type V4Ops struct {
|
||||||
|
//Values uint64 // Variable depending on v4.x sub-version. TODO: Will this always at least include the fields in this struct?
|
||||||
|
Op0Unused uint64
|
||||||
|
Op1Unused uint64
|
||||||
|
Op2Future uint64
|
||||||
|
Access uint64
|
||||||
|
Close uint64
|
||||||
|
Commit uint64
|
||||||
|
Create uint64
|
||||||
|
DelegPurge uint64
|
||||||
|
DelegReturn uint64
|
||||||
|
GetAttr uint64
|
||||||
|
GetFH uint64
|
||||||
|
Link uint64
|
||||||
|
Lock uint64
|
||||||
|
Lockt uint64
|
||||||
|
Locku uint64
|
||||||
|
Lookup uint64
|
||||||
|
LookupRoot uint64
|
||||||
|
Nverify uint64
|
||||||
|
Open uint64
|
||||||
|
OpenAttr uint64
|
||||||
|
OpenConfirm uint64
|
||||||
|
OpenDgrd uint64
|
||||||
|
PutFH uint64
|
||||||
|
PutPubFH uint64
|
||||||
|
PutRootFH uint64
|
||||||
|
Read uint64
|
||||||
|
ReadDir uint64
|
||||||
|
ReadLink uint64
|
||||||
|
Remove uint64
|
||||||
|
Rename uint64
|
||||||
|
Renew uint64
|
||||||
|
RestoreFH uint64
|
||||||
|
SaveFH uint64
|
||||||
|
SecInfo uint64
|
||||||
|
SetAttr uint64
|
||||||
|
Verify uint64
|
||||||
|
Write uint64
|
||||||
|
RelLockOwner uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// RPCStats models all stats from /proc/net/rpc/nfs.
|
||||||
|
type ClientRPCStats struct {
|
||||||
|
Network Network
|
||||||
|
ClientRPC ClientRPC
|
||||||
|
V2Stats V2Stats
|
||||||
|
V3Stats V3Stats
|
||||||
|
ClientV4Stats ClientV4Stats
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServerRPCStats models all stats from /proc/net/rpc/nfsd.
|
||||||
|
type ServerRPCStats struct {
|
||||||
|
ReplyCache ReplyCache
|
||||||
|
FileHandles FileHandles
|
||||||
|
InputOutput InputOutput
|
||||||
|
Threads Threads
|
||||||
|
ReadAheadCache ReadAheadCache
|
||||||
|
Network Network
|
||||||
|
ServerRPC ServerRPC
|
||||||
|
V2Stats V2Stats
|
||||||
|
V3Stats V3Stats
|
||||||
|
ServerV4Stats ServerV4Stats
|
||||||
|
V4Ops V4Ops
|
||||||
|
}
|
317
vendor/github.com/prometheus/procfs/nfs/parse.go
generated
vendored
Normal file
317
vendor/github.com/prometheus/procfs/nfs/parse.go
generated
vendored
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package nfs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func parseReplyCache(v []uint64) (ReplyCache, error) {
|
||||||
|
if len(v) != 3 {
|
||||||
|
return ReplyCache{}, fmt.Errorf("invalid ReplyCache line %q", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ReplyCache{
|
||||||
|
Hits: v[0],
|
||||||
|
Misses: v[1],
|
||||||
|
NoCache: v[2],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseFileHandles(v []uint64) (FileHandles, error) {
|
||||||
|
if len(v) != 5 {
|
||||||
|
return FileHandles{}, fmt.Errorf("invalid FileHandles, line %q", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return FileHandles{
|
||||||
|
Stale: v[0],
|
||||||
|
TotalLookups: v[1],
|
||||||
|
AnonLookups: v[2],
|
||||||
|
DirNoCache: v[3],
|
||||||
|
NoDirNoCache: v[4],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseInputOutput(v []uint64) (InputOutput, error) {
|
||||||
|
if len(v) != 2 {
|
||||||
|
return InputOutput{}, fmt.Errorf("invalid InputOutput line %q", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return InputOutput{
|
||||||
|
Read: v[0],
|
||||||
|
Write: v[1],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseThreads(v []uint64) (Threads, error) {
|
||||||
|
if len(v) != 2 {
|
||||||
|
return Threads{}, fmt.Errorf("invalid Threads line %q", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Threads{
|
||||||
|
Threads: v[0],
|
||||||
|
FullCnt: v[1],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseReadAheadCache(v []uint64) (ReadAheadCache, error) {
|
||||||
|
if len(v) != 12 {
|
||||||
|
return ReadAheadCache{}, fmt.Errorf("invalid ReadAheadCache line %q", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ReadAheadCache{
|
||||||
|
CacheSize: v[0],
|
||||||
|
CacheHistogram: v[1:11],
|
||||||
|
NotFound: v[11],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseNetwork(v []uint64) (Network, error) {
|
||||||
|
if len(v) != 4 {
|
||||||
|
return Network{}, fmt.Errorf("invalid Network line %q", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Network{
|
||||||
|
NetCount: v[0],
|
||||||
|
UDPCount: v[1],
|
||||||
|
TCPCount: v[2],
|
||||||
|
TCPConnect: v[3],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseServerRPC(v []uint64) (ServerRPC, error) {
|
||||||
|
if len(v) != 5 {
|
||||||
|
return ServerRPC{}, fmt.Errorf("invalid RPC line %q", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ServerRPC{
|
||||||
|
RPCCount: v[0],
|
||||||
|
BadCnt: v[1],
|
||||||
|
BadFmt: v[2],
|
||||||
|
BadAuth: v[3],
|
||||||
|
BadcInt: v[4],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseClientRPC(v []uint64) (ClientRPC, error) {
|
||||||
|
if len(v) != 3 {
|
||||||
|
return ClientRPC{}, fmt.Errorf("invalid RPC line %q", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ClientRPC{
|
||||||
|
RPCCount: v[0],
|
||||||
|
Retransmissions: v[1],
|
||||||
|
AuthRefreshes: v[2],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseV2Stats(v []uint64) (V2Stats, error) {
|
||||||
|
values := int(v[0])
|
||||||
|
if len(v[1:]) != values || values != 18 {
|
||||||
|
return V2Stats{}, fmt.Errorf("invalid V2Stats line %q", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return V2Stats{
|
||||||
|
Null: v[1],
|
||||||
|
GetAttr: v[2],
|
||||||
|
SetAttr: v[3],
|
||||||
|
Root: v[4],
|
||||||
|
Lookup: v[5],
|
||||||
|
ReadLink: v[6],
|
||||||
|
Read: v[7],
|
||||||
|
WrCache: v[8],
|
||||||
|
Write: v[9],
|
||||||
|
Create: v[10],
|
||||||
|
Remove: v[11],
|
||||||
|
Rename: v[12],
|
||||||
|
Link: v[13],
|
||||||
|
SymLink: v[14],
|
||||||
|
MkDir: v[15],
|
||||||
|
RmDir: v[16],
|
||||||
|
ReadDir: v[17],
|
||||||
|
FsStat: v[18],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseV3Stats(v []uint64) (V3Stats, error) {
|
||||||
|
values := int(v[0])
|
||||||
|
if len(v[1:]) != values || values != 22 {
|
||||||
|
return V3Stats{}, fmt.Errorf("invalid V3Stats line %q", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return V3Stats{
|
||||||
|
Null: v[1],
|
||||||
|
GetAttr: v[2],
|
||||||
|
SetAttr: v[3],
|
||||||
|
Lookup: v[4],
|
||||||
|
Access: v[5],
|
||||||
|
ReadLink: v[6],
|
||||||
|
Read: v[7],
|
||||||
|
Write: v[8],
|
||||||
|
Create: v[9],
|
||||||
|
MkDir: v[10],
|
||||||
|
SymLink: v[11],
|
||||||
|
MkNod: v[12],
|
||||||
|
Remove: v[13],
|
||||||
|
RmDir: v[14],
|
||||||
|
Rename: v[15],
|
||||||
|
Link: v[16],
|
||||||
|
ReadDir: v[17],
|
||||||
|
ReadDirPlus: v[18],
|
||||||
|
FsStat: v[19],
|
||||||
|
FsInfo: v[20],
|
||||||
|
PathConf: v[21],
|
||||||
|
Commit: v[22],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseClientV4Stats(v []uint64) (ClientV4Stats, error) {
|
||||||
|
values := int(v[0])
|
||||||
|
if len(v[1:]) != values {
|
||||||
|
return ClientV4Stats{}, fmt.Errorf("invalid ClientV4Stats line %q", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function currently supports mapping 59 NFS v4 client stats. Older
|
||||||
|
// kernels may emit fewer stats, so we must detect this and pad out the
|
||||||
|
// values to match the expected slice size.
|
||||||
|
if values < 59 {
|
||||||
|
newValues := make([]uint64, 60)
|
||||||
|
copy(newValues, v)
|
||||||
|
v = newValues
|
||||||
|
}
|
||||||
|
|
||||||
|
return ClientV4Stats{
|
||||||
|
Null: v[1],
|
||||||
|
Read: v[2],
|
||||||
|
Write: v[3],
|
||||||
|
Commit: v[4],
|
||||||
|
Open: v[5],
|
||||||
|
OpenConfirm: v[6],
|
||||||
|
OpenNoattr: v[7],
|
||||||
|
OpenDowngrade: v[8],
|
||||||
|
Close: v[9],
|
||||||
|
Setattr: v[10],
|
||||||
|
FsInfo: v[11],
|
||||||
|
Renew: v[12],
|
||||||
|
SetClientId: v[13],
|
||||||
|
SetClientIdConfirm: v[14],
|
||||||
|
Lock: v[15],
|
||||||
|
Lockt: v[16],
|
||||||
|
Locku: v[17],
|
||||||
|
Access: v[18],
|
||||||
|
Getattr: v[19],
|
||||||
|
Lookup: v[20],
|
||||||
|
LookupRoot: v[21],
|
||||||
|
Remove: v[22],
|
||||||
|
Rename: v[23],
|
||||||
|
Link: v[24],
|
||||||
|
Symlink: v[25],
|
||||||
|
Create: v[26],
|
||||||
|
Pathconf: v[27],
|
||||||
|
StatFs: v[28],
|
||||||
|
ReadLink: v[29],
|
||||||
|
ReadDir: v[30],
|
||||||
|
ServerCaps: v[31],
|
||||||
|
DelegReturn: v[32],
|
||||||
|
GetAcl: v[33],
|
||||||
|
SetAcl: v[34],
|
||||||
|
FsLocations: v[35],
|
||||||
|
ReleaseLockowner: v[36],
|
||||||
|
Secinfo: v[37],
|
||||||
|
FsidPresent: v[38],
|
||||||
|
ExchangeId: v[39],
|
||||||
|
CreateSession: v[40],
|
||||||
|
DestroySession: v[41],
|
||||||
|
Sequence: v[42],
|
||||||
|
GetLeaseTime: v[43],
|
||||||
|
ReclaimComplete: v[44],
|
||||||
|
LayoutGet: v[45],
|
||||||
|
GetDeviceInfo: v[46],
|
||||||
|
LayoutCommit: v[47],
|
||||||
|
LayoutReturn: v[48],
|
||||||
|
SecinfoNoName: v[49],
|
||||||
|
TestStateId: v[50],
|
||||||
|
FreeStateId: v[51],
|
||||||
|
GetDeviceList: v[52],
|
||||||
|
BindConnToSession: v[53],
|
||||||
|
DestroyClientId: v[54],
|
||||||
|
Seek: v[55],
|
||||||
|
Allocate: v[56],
|
||||||
|
DeAllocate: v[57],
|
||||||
|
LayoutStats: v[58],
|
||||||
|
Clone: v[59],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseServerV4Stats(v []uint64) (ServerV4Stats, error) {
|
||||||
|
values := int(v[0])
|
||||||
|
if len(v[1:]) != values || values != 2 {
|
||||||
|
return ServerV4Stats{}, fmt.Errorf("invalid V4Stats line %q", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ServerV4Stats{
|
||||||
|
Null: v[1],
|
||||||
|
Compound: v[2],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseV4Ops(v []uint64) (V4Ops, error) {
|
||||||
|
values := int(v[0])
|
||||||
|
if len(v[1:]) != values || values < 39 {
|
||||||
|
return V4Ops{}, fmt.Errorf("invalid V4Ops line %q", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
stats := V4Ops{
|
||||||
|
Op0Unused: v[1],
|
||||||
|
Op1Unused: v[2],
|
||||||
|
Op2Future: v[3],
|
||||||
|
Access: v[4],
|
||||||
|
Close: v[5],
|
||||||
|
Commit: v[6],
|
||||||
|
Create: v[7],
|
||||||
|
DelegPurge: v[8],
|
||||||
|
DelegReturn: v[9],
|
||||||
|
GetAttr: v[10],
|
||||||
|
GetFH: v[11],
|
||||||
|
Link: v[12],
|
||||||
|
Lock: v[13],
|
||||||
|
Lockt: v[14],
|
||||||
|
Locku: v[15],
|
||||||
|
Lookup: v[16],
|
||||||
|
LookupRoot: v[17],
|
||||||
|
Nverify: v[18],
|
||||||
|
Open: v[19],
|
||||||
|
OpenAttr: v[20],
|
||||||
|
OpenConfirm: v[21],
|
||||||
|
OpenDgrd: v[22],
|
||||||
|
PutFH: v[23],
|
||||||
|
PutPubFH: v[24],
|
||||||
|
PutRootFH: v[25],
|
||||||
|
Read: v[26],
|
||||||
|
ReadDir: v[27],
|
||||||
|
ReadLink: v[28],
|
||||||
|
Remove: v[29],
|
||||||
|
Rename: v[30],
|
||||||
|
Renew: v[31],
|
||||||
|
RestoreFH: v[32],
|
||||||
|
SaveFH: v[33],
|
||||||
|
SecInfo: v[34],
|
||||||
|
SetAttr: v[35],
|
||||||
|
Verify: v[36],
|
||||||
|
Write: v[37],
|
||||||
|
RelLockOwner: v[38],
|
||||||
|
}
|
||||||
|
|
||||||
|
return stats, nil
|
||||||
|
}
|
67
vendor/github.com/prometheus/procfs/nfs/parse_nfs.go
generated
vendored
Normal file
67
vendor/github.com/prometheus/procfs/nfs/parse_nfs.go
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package nfs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/prometheus/procfs/internal/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ParseClientRPCStats returns stats read from /proc/net/rpc/nfs
|
||||||
|
func ParseClientRPCStats(r io.Reader) (*ClientRPCStats, error) {
|
||||||
|
stats := &ClientRPCStats{}
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(r)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
parts := strings.Fields(scanner.Text())
|
||||||
|
// require at least <key> <value>
|
||||||
|
if len(parts) < 2 {
|
||||||
|
return nil, fmt.Errorf("invalid NFS metric line %q", line)
|
||||||
|
}
|
||||||
|
|
||||||
|
values, err := util.ParseUint64s(parts[1:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error parsing NFS metric line: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch metricLine := parts[0]; metricLine {
|
||||||
|
case "net":
|
||||||
|
stats.Network, err = parseNetwork(values)
|
||||||
|
case "rpc":
|
||||||
|
stats.ClientRPC, err = parseClientRPC(values)
|
||||||
|
case "proc2":
|
||||||
|
stats.V2Stats, err = parseV2Stats(values)
|
||||||
|
case "proc3":
|
||||||
|
stats.V3Stats, err = parseV3Stats(values)
|
||||||
|
case "proc4":
|
||||||
|
stats.ClientV4Stats, err = parseClientV4Stats(values)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown NFS metric line %q", metricLine)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("errors parsing NFS metric line: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return nil, fmt.Errorf("error scanning NFS file: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return stats, nil
|
||||||
|
}
|
305
vendor/github.com/prometheus/procfs/nfs/parse_nfs_test.go
generated
vendored
Normal file
305
vendor/github.com/prometheus/procfs/nfs/parse_nfs_test.go
generated
vendored
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package nfs_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/prometheus/procfs/nfs"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewNFSClientRPCStats(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
content string
|
||||||
|
stats *nfs.ClientRPCStats
|
||||||
|
invalid bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "invalid file",
|
||||||
|
content: "invalid",
|
||||||
|
invalid: true,
|
||||||
|
}, {
|
||||||
|
name: "good old kernel version file",
|
||||||
|
content: `net 70 70 69 45
|
||||||
|
rpc 1218785755 374636 1218815394
|
||||||
|
proc2 18 16 57 74 52 71 73 45 86 0 52 83 61 17 53 50 23 70 82
|
||||||
|
proc3 22 0 1061909262 48906 4077635 117661341 5 29391916 2570425 2993289 590 0 0 7815 15 1130 0 3983 92385 13332 2 1 23729
|
||||||
|
proc4 48 98 51 54 83 85 23 24 1 28 73 68 83 12 84 39 68 59 58 88 29 74 69 96 21 84 15 53 86 54 66 56 97 36 49 32 85 81 11 58 32 67 13 28 35 90 1 26 1337
|
||||||
|
`,
|
||||||
|
stats: &nfs.ClientRPCStats{
|
||||||
|
Network: nfs.Network{
|
||||||
|
NetCount: 70,
|
||||||
|
UDPCount: 70,
|
||||||
|
TCPCount: 69,
|
||||||
|
TCPConnect: 45,
|
||||||
|
},
|
||||||
|
ClientRPC: nfs.ClientRPC{
|
||||||
|
RPCCount: 1218785755,
|
||||||
|
Retransmissions: 374636,
|
||||||
|
AuthRefreshes: 1218815394,
|
||||||
|
},
|
||||||
|
V2Stats: nfs.V2Stats{
|
||||||
|
Null: 16,
|
||||||
|
GetAttr: 57,
|
||||||
|
SetAttr: 74,
|
||||||
|
Root: 52,
|
||||||
|
Lookup: 71,
|
||||||
|
ReadLink: 73,
|
||||||
|
Read: 45,
|
||||||
|
WrCache: 86,
|
||||||
|
Write: 0,
|
||||||
|
Create: 52,
|
||||||
|
Remove: 83,
|
||||||
|
Rename: 61,
|
||||||
|
Link: 17,
|
||||||
|
SymLink: 53,
|
||||||
|
MkDir: 50,
|
||||||
|
RmDir: 23,
|
||||||
|
ReadDir: 70,
|
||||||
|
FsStat: 82,
|
||||||
|
},
|
||||||
|
V3Stats: nfs.V3Stats{
|
||||||
|
Null: 0,
|
||||||
|
GetAttr: 1061909262,
|
||||||
|
SetAttr: 48906,
|
||||||
|
Lookup: 4077635,
|
||||||
|
Access: 117661341,
|
||||||
|
ReadLink: 5,
|
||||||
|
Read: 29391916,
|
||||||
|
Write: 2570425,
|
||||||
|
Create: 2993289,
|
||||||
|
MkDir: 590,
|
||||||
|
SymLink: 0,
|
||||||
|
MkNod: 0,
|
||||||
|
Remove: 7815,
|
||||||
|
RmDir: 15,
|
||||||
|
Rename: 1130,
|
||||||
|
Link: 0,
|
||||||
|
ReadDir: 3983,
|
||||||
|
ReadDirPlus: 92385,
|
||||||
|
FsStat: 13332,
|
||||||
|
FsInfo: 2,
|
||||||
|
PathConf: 1,
|
||||||
|
Commit: 23729},
|
||||||
|
ClientV4Stats: nfs.ClientV4Stats{
|
||||||
|
Null: 98,
|
||||||
|
Read: 51,
|
||||||
|
Write: 54,
|
||||||
|
Commit: 83,
|
||||||
|
Open: 85,
|
||||||
|
OpenConfirm: 23,
|
||||||
|
OpenNoattr: 24,
|
||||||
|
OpenDowngrade: 1,
|
||||||
|
Close: 28,
|
||||||
|
Setattr: 73,
|
||||||
|
FsInfo: 68,
|
||||||
|
Renew: 83,
|
||||||
|
SetClientId: 12,
|
||||||
|
SetClientIdConfirm: 84,
|
||||||
|
Lock: 39,
|
||||||
|
Lockt: 68,
|
||||||
|
Locku: 59,
|
||||||
|
Access: 58,
|
||||||
|
Getattr: 88,
|
||||||
|
Lookup: 29,
|
||||||
|
LookupRoot: 74,
|
||||||
|
Remove: 69,
|
||||||
|
Rename: 96,
|
||||||
|
Link: 21,
|
||||||
|
Symlink: 84,
|
||||||
|
Create: 15,
|
||||||
|
Pathconf: 53,
|
||||||
|
StatFs: 86,
|
||||||
|
ReadLink: 54,
|
||||||
|
ReadDir: 66,
|
||||||
|
ServerCaps: 56,
|
||||||
|
DelegReturn: 97,
|
||||||
|
GetAcl: 36,
|
||||||
|
SetAcl: 49,
|
||||||
|
FsLocations: 32,
|
||||||
|
ReleaseLockowner: 85,
|
||||||
|
Secinfo: 81,
|
||||||
|
FsidPresent: 11,
|
||||||
|
ExchangeId: 58,
|
||||||
|
CreateSession: 32,
|
||||||
|
DestroySession: 67,
|
||||||
|
Sequence: 13,
|
||||||
|
GetLeaseTime: 28,
|
||||||
|
ReclaimComplete: 35,
|
||||||
|
LayoutGet: 90,
|
||||||
|
GetDeviceInfo: 1,
|
||||||
|
LayoutCommit: 26,
|
||||||
|
LayoutReturn: 1337,
|
||||||
|
SecinfoNoName: 0,
|
||||||
|
TestStateId: 0,
|
||||||
|
FreeStateId: 0,
|
||||||
|
GetDeviceList: 0,
|
||||||
|
BindConnToSession: 0,
|
||||||
|
DestroyClientId: 0,
|
||||||
|
Seek: 0,
|
||||||
|
Allocate: 0,
|
||||||
|
DeAllocate: 0,
|
||||||
|
LayoutStats: 0,
|
||||||
|
Clone: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
name: "good file",
|
||||||
|
content: `net 18628 0 18628 6
|
||||||
|
rpc 4329785 0 4338291
|
||||||
|
proc2 18 2 69 0 0 4410 0 0 0 0 0 0 0 0 0 0 0 99 2
|
||||||
|
proc3 22 1 4084749 29200 94754 32580 186 47747 7981 8639 0 6356 0 6962 0 7958 0 0 241 4 4 2 39
|
||||||
|
proc4 61 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
`,
|
||||||
|
stats: &nfs.ClientRPCStats{
|
||||||
|
Network: nfs.Network{
|
||||||
|
NetCount: 18628,
|
||||||
|
UDPCount: 0,
|
||||||
|
TCPCount: 18628,
|
||||||
|
TCPConnect: 6,
|
||||||
|
},
|
||||||
|
ClientRPC: nfs.ClientRPC{
|
||||||
|
RPCCount: 4329785,
|
||||||
|
Retransmissions: 0,
|
||||||
|
AuthRefreshes: 4338291,
|
||||||
|
},
|
||||||
|
V2Stats: nfs.V2Stats{
|
||||||
|
Null: 2,
|
||||||
|
GetAttr: 69,
|
||||||
|
SetAttr: 0,
|
||||||
|
Root: 0,
|
||||||
|
Lookup: 4410,
|
||||||
|
ReadLink: 0,
|
||||||
|
Read: 0,
|
||||||
|
WrCache: 0,
|
||||||
|
Write: 0,
|
||||||
|
Create: 0,
|
||||||
|
Remove: 0,
|
||||||
|
Rename: 0,
|
||||||
|
Link: 0,
|
||||||
|
SymLink: 0,
|
||||||
|
MkDir: 0,
|
||||||
|
RmDir: 0,
|
||||||
|
ReadDir: 99,
|
||||||
|
FsStat: 2,
|
||||||
|
},
|
||||||
|
V3Stats: nfs.V3Stats{
|
||||||
|
Null: 1,
|
||||||
|
GetAttr: 4084749,
|
||||||
|
SetAttr: 29200,
|
||||||
|
Lookup: 94754,
|
||||||
|
Access: 32580,
|
||||||
|
ReadLink: 186,
|
||||||
|
Read: 47747,
|
||||||
|
Write: 7981,
|
||||||
|
Create: 8639,
|
||||||
|
MkDir: 0,
|
||||||
|
SymLink: 6356,
|
||||||
|
MkNod: 0,
|
||||||
|
Remove: 6962,
|
||||||
|
RmDir: 0,
|
||||||
|
Rename: 7958,
|
||||||
|
Link: 0,
|
||||||
|
ReadDir: 0,
|
||||||
|
ReadDirPlus: 241,
|
||||||
|
FsStat: 4,
|
||||||
|
FsInfo: 4,
|
||||||
|
PathConf: 2,
|
||||||
|
Commit: 39,
|
||||||
|
},
|
||||||
|
ClientV4Stats: nfs.ClientV4Stats{
|
||||||
|
Null: 1,
|
||||||
|
Read: 0,
|
||||||
|
Write: 0,
|
||||||
|
Commit: 0,
|
||||||
|
Open: 0,
|
||||||
|
OpenConfirm: 0,
|
||||||
|
OpenNoattr: 0,
|
||||||
|
OpenDowngrade: 0,
|
||||||
|
Close: 0,
|
||||||
|
Setattr: 0,
|
||||||
|
FsInfo: 0,
|
||||||
|
Renew: 0,
|
||||||
|
SetClientId: 1,
|
||||||
|
SetClientIdConfirm: 1,
|
||||||
|
Lock: 0,
|
||||||
|
Lockt: 0,
|
||||||
|
Locku: 0,
|
||||||
|
Access: 0,
|
||||||
|
Getattr: 0,
|
||||||
|
Lookup: 0,
|
||||||
|
LookupRoot: 0,
|
||||||
|
Remove: 2,
|
||||||
|
Rename: 0,
|
||||||
|
Link: 0,
|
||||||
|
Symlink: 0,
|
||||||
|
Create: 0,
|
||||||
|
Pathconf: 0,
|
||||||
|
StatFs: 0,
|
||||||
|
ReadLink: 0,
|
||||||
|
ReadDir: 0,
|
||||||
|
ServerCaps: 0,
|
||||||
|
DelegReturn: 0,
|
||||||
|
GetAcl: 0,
|
||||||
|
SetAcl: 0,
|
||||||
|
FsLocations: 0,
|
||||||
|
ReleaseLockowner: 0,
|
||||||
|
Secinfo: 0,
|
||||||
|
FsidPresent: 0,
|
||||||
|
ExchangeId: 0,
|
||||||
|
CreateSession: 0,
|
||||||
|
DestroySession: 0,
|
||||||
|
Sequence: 0,
|
||||||
|
GetLeaseTime: 0,
|
||||||
|
ReclaimComplete: 0,
|
||||||
|
LayoutGet: 0,
|
||||||
|
GetDeviceInfo: 0,
|
||||||
|
LayoutCommit: 0,
|
||||||
|
LayoutReturn: 0,
|
||||||
|
SecinfoNoName: 0,
|
||||||
|
TestStateId: 0,
|
||||||
|
FreeStateId: 0,
|
||||||
|
GetDeviceList: 0,
|
||||||
|
BindConnToSession: 0,
|
||||||
|
DestroyClientId: 0,
|
||||||
|
Seek: 0,
|
||||||
|
Allocate: 0,
|
||||||
|
DeAllocate: 0,
|
||||||
|
LayoutStats: 0,
|
||||||
|
Clone: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
stats, err := nfs.ParseClientRPCStats(strings.NewReader(tt.content))
|
||||||
|
|
||||||
|
if tt.invalid && err == nil {
|
||||||
|
t.Fatal("expected an error, but none occurred")
|
||||||
|
}
|
||||||
|
if !tt.invalid && err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if want, have := tt.stats, stats; !reflect.DeepEqual(want, have) {
|
||||||
|
t.Fatalf("unexpected NFS stats:\nwant:\n%v\nhave:\n%v", want, have)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
89
vendor/github.com/prometheus/procfs/nfs/parse_nfsd.go
generated
vendored
Normal file
89
vendor/github.com/prometheus/procfs/nfs/parse_nfsd.go
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package nfs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/prometheus/procfs/internal/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ParseServerRPCStats returns stats read from /proc/net/rpc/nfsd
|
||||||
|
func ParseServerRPCStats(r io.Reader) (*ServerRPCStats, error) {
|
||||||
|
stats := &ServerRPCStats{}
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(r)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
parts := strings.Fields(scanner.Text())
|
||||||
|
// require at least <key> <value>
|
||||||
|
if len(parts) < 2 {
|
||||||
|
return nil, fmt.Errorf("invalid NFSd metric line %q", line)
|
||||||
|
}
|
||||||
|
label := parts[0]
|
||||||
|
|
||||||
|
var values []uint64
|
||||||
|
var err error
|
||||||
|
if label == "th" {
|
||||||
|
if len(parts) < 3 {
|
||||||
|
return nil, fmt.Errorf("invalid NFSd th metric line %q", line)
|
||||||
|
}
|
||||||
|
values, err = util.ParseUint64s(parts[1:3])
|
||||||
|
} else {
|
||||||
|
values, err = util.ParseUint64s(parts[1:])
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error parsing NFSd metric line: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch metricLine := parts[0]; metricLine {
|
||||||
|
case "rc":
|
||||||
|
stats.ReplyCache, err = parseReplyCache(values)
|
||||||
|
case "fh":
|
||||||
|
stats.FileHandles, err = parseFileHandles(values)
|
||||||
|
case "io":
|
||||||
|
stats.InputOutput, err = parseInputOutput(values)
|
||||||
|
case "th":
|
||||||
|
stats.Threads, err = parseThreads(values)
|
||||||
|
case "ra":
|
||||||
|
stats.ReadAheadCache, err = parseReadAheadCache(values)
|
||||||
|
case "net":
|
||||||
|
stats.Network, err = parseNetwork(values)
|
||||||
|
case "rpc":
|
||||||
|
stats.ServerRPC, err = parseServerRPC(values)
|
||||||
|
case "proc2":
|
||||||
|
stats.V2Stats, err = parseV2Stats(values)
|
||||||
|
case "proc3":
|
||||||
|
stats.V3Stats, err = parseV3Stats(values)
|
||||||
|
case "proc4":
|
||||||
|
stats.ServerV4Stats, err = parseServerV4Stats(values)
|
||||||
|
case "proc4ops":
|
||||||
|
stats.V4Ops, err = parseV4Ops(values)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown NFSd metric line %q", metricLine)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("errors parsing NFSd metric line: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return nil, fmt.Errorf("error scanning NFSd file: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return stats, nil
|
||||||
|
}
|
196
vendor/github.com/prometheus/procfs/nfs/parse_nfsd_test.go
generated
vendored
Normal file
196
vendor/github.com/prometheus/procfs/nfs/parse_nfsd_test.go
generated
vendored
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package nfs_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/prometheus/procfs/nfs"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewNFSdServerRPCStats(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
content string
|
||||||
|
stats *nfs.ServerRPCStats
|
||||||
|
invalid bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "invalid file",
|
||||||
|
content: "invalid",
|
||||||
|
invalid: true,
|
||||||
|
}, {
|
||||||
|
name: "good file",
|
||||||
|
content: `rc 0 6 18622
|
||||||
|
fh 0 0 0 0 0
|
||||||
|
io 157286400 0
|
||||||
|
th 8 0 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
|
||||||
|
ra 32 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
net 18628 0 18628 6
|
||||||
|
rpc 18628 0 0 0 0
|
||||||
|
proc2 18 2 69 0 0 4410 0 0 0 0 0 0 0 0 0 0 0 99 2
|
||||||
|
proc3 22 2 112 0 2719 111 0 0 0 0 0 0 0 0 0 0 0 27 216 0 2 1 0
|
||||||
|
proc4 2 2 10853
|
||||||
|
proc4ops 72 0 0 0 1098 2 0 0 0 0 8179 5896 0 0 0 0 5900 0 0 2 0 2 0 9609 0 2 150 1272 0 0 0 1236 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
`,
|
||||||
|
stats: &nfs.ServerRPCStats{
|
||||||
|
ReplyCache: nfs.ReplyCache{
|
||||||
|
Hits: 0,
|
||||||
|
Misses: 6,
|
||||||
|
NoCache: 18622,
|
||||||
|
},
|
||||||
|
FileHandles: nfs.FileHandles{
|
||||||
|
Stale: 0,
|
||||||
|
TotalLookups: 0,
|
||||||
|
AnonLookups: 0,
|
||||||
|
DirNoCache: 0,
|
||||||
|
NoDirNoCache: 0,
|
||||||
|
},
|
||||||
|
InputOutput: nfs.InputOutput{
|
||||||
|
Read: 157286400,
|
||||||
|
Write: 0,
|
||||||
|
},
|
||||||
|
Threads: nfs.Threads{
|
||||||
|
Threads: 8,
|
||||||
|
FullCnt: 0,
|
||||||
|
},
|
||||||
|
ReadAheadCache: nfs.ReadAheadCache{
|
||||||
|
CacheSize: 32,
|
||||||
|
CacheHistogram: []uint64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
NotFound: 0,
|
||||||
|
},
|
||||||
|
Network: nfs.Network{
|
||||||
|
NetCount: 18628,
|
||||||
|
UDPCount: 0,
|
||||||
|
TCPCount: 18628,
|
||||||
|
TCPConnect: 6,
|
||||||
|
},
|
||||||
|
ServerRPC: nfs.ServerRPC{
|
||||||
|
RPCCount: 18628,
|
||||||
|
BadCnt: 0,
|
||||||
|
BadFmt: 0,
|
||||||
|
BadAuth: 0,
|
||||||
|
BadcInt: 0,
|
||||||
|
},
|
||||||
|
V2Stats: nfs.V2Stats{
|
||||||
|
Null: 2,
|
||||||
|
GetAttr: 69,
|
||||||
|
SetAttr: 0,
|
||||||
|
Root: 0,
|
||||||
|
Lookup: 4410,
|
||||||
|
ReadLink: 0,
|
||||||
|
Read: 0,
|
||||||
|
WrCache: 0,
|
||||||
|
Write: 0,
|
||||||
|
Create: 0,
|
||||||
|
Remove: 0,
|
||||||
|
Rename: 0,
|
||||||
|
Link: 0,
|
||||||
|
SymLink: 0,
|
||||||
|
MkDir: 0,
|
||||||
|
RmDir: 0,
|
||||||
|
ReadDir: 99,
|
||||||
|
FsStat: 2,
|
||||||
|
},
|
||||||
|
V3Stats: nfs.V3Stats{
|
||||||
|
Null: 2,
|
||||||
|
GetAttr: 112,
|
||||||
|
SetAttr: 0,
|
||||||
|
Lookup: 2719,
|
||||||
|
Access: 111,
|
||||||
|
ReadLink: 0,
|
||||||
|
Read: 0,
|
||||||
|
Write: 0,
|
||||||
|
Create: 0,
|
||||||
|
MkDir: 0,
|
||||||
|
SymLink: 0,
|
||||||
|
MkNod: 0,
|
||||||
|
Remove: 0,
|
||||||
|
RmDir: 0,
|
||||||
|
Rename: 0,
|
||||||
|
Link: 0,
|
||||||
|
ReadDir: 27,
|
||||||
|
ReadDirPlus: 216,
|
||||||
|
FsStat: 0,
|
||||||
|
FsInfo: 2,
|
||||||
|
PathConf: 1,
|
||||||
|
Commit: 0,
|
||||||
|
},
|
||||||
|
ServerV4Stats: nfs.ServerV4Stats{
|
||||||
|
Null: 2,
|
||||||
|
Compound: 10853,
|
||||||
|
},
|
||||||
|
V4Ops: nfs.V4Ops{
|
||||||
|
Op0Unused: 0,
|
||||||
|
Op1Unused: 0,
|
||||||
|
Op2Future: 0,
|
||||||
|
Access: 1098,
|
||||||
|
Close: 2,
|
||||||
|
Commit: 0,
|
||||||
|
Create: 0,
|
||||||
|
DelegPurge: 0,
|
||||||
|
DelegReturn: 0,
|
||||||
|
GetAttr: 8179,
|
||||||
|
GetFH: 5896,
|
||||||
|
Link: 0,
|
||||||
|
Lock: 0,
|
||||||
|
Lockt: 0,
|
||||||
|
Locku: 0,
|
||||||
|
Lookup: 5900,
|
||||||
|
LookupRoot: 0,
|
||||||
|
Nverify: 0,
|
||||||
|
Open: 2,
|
||||||
|
OpenAttr: 0,
|
||||||
|
OpenConfirm: 2,
|
||||||
|
OpenDgrd: 0,
|
||||||
|
PutFH: 9609,
|
||||||
|
PutPubFH: 0,
|
||||||
|
PutRootFH: 2,
|
||||||
|
Read: 150,
|
||||||
|
ReadDir: 1272,
|
||||||
|
ReadLink: 0,
|
||||||
|
Remove: 0,
|
||||||
|
Rename: 0,
|
||||||
|
Renew: 1236,
|
||||||
|
RestoreFH: 0,
|
||||||
|
SaveFH: 0,
|
||||||
|
SecInfo: 0,
|
||||||
|
SetAttr: 0,
|
||||||
|
Verify: 3,
|
||||||
|
Write: 3,
|
||||||
|
RelLockOwner: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
stats, err := nfs.ParseServerRPCStats(strings.NewReader(tt.content))
|
||||||
|
|
||||||
|
if tt.invalid && err == nil {
|
||||||
|
t.Fatal("expected an error, but none occurred")
|
||||||
|
}
|
||||||
|
if !tt.invalid && err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if want, have := tt.stats, stats; !reflect.DeepEqual(want, have) {
|
||||||
|
t.Fatalf("unexpected NFS stats:\nwant:\n%v\nhave:\n%v", want, have)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
16
vendor/github.com/prometheus/procfs/proc.go
generated
vendored
16
vendor/github.com/prometheus/procfs/proc.go
generated
vendored
@ -1,6 +1,20 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package procfs
|
package procfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
@ -113,7 +127,7 @@ func (p Proc) CmdLine() ([]string, error) {
|
|||||||
return []string{}, nil
|
return []string{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.Split(string(data[:len(data)-1]), string(byte(0))), nil
|
return strings.Split(string(bytes.TrimRight(data, string("\x00"))), string(byte(0))), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comm returns the command name of a process.
|
// Comm returns the command name of a process.
|
||||||
|
18
vendor/github.com/prometheus/procfs/proc_io.go
generated
vendored
18
vendor/github.com/prometheus/procfs/proc_io.go
generated
vendored
@ -1,3 +1,16 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package procfs
|
package procfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -47,9 +60,6 @@ func (p Proc) NewIO() (ProcIO, error) {
|
|||||||
|
|
||||||
_, err = fmt.Sscanf(string(data), ioFormat, &pio.RChar, &pio.WChar, &pio.SyscR,
|
_, err = fmt.Sscanf(string(data), ioFormat, &pio.RChar, &pio.WChar, &pio.SyscR,
|
||||||
&pio.SyscW, &pio.ReadBytes, &pio.WriteBytes, &pio.CancelledWriteBytes)
|
&pio.SyscW, &pio.ReadBytes, &pio.WriteBytes, &pio.CancelledWriteBytes)
|
||||||
if err != nil {
|
|
||||||
return pio, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return pio, nil
|
return pio, err
|
||||||
}
|
}
|
||||||
|
13
vendor/github.com/prometheus/procfs/proc_io_test.go
generated
vendored
13
vendor/github.com/prometheus/procfs/proc_io_test.go
generated
vendored
@ -1,3 +1,16 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package procfs
|
package procfs
|
||||||
|
|
||||||
import "testing"
|
import "testing"
|
||||||
|
13
vendor/github.com/prometheus/procfs/proc_limits.go
generated
vendored
13
vendor/github.com/prometheus/procfs/proc_limits.go
generated
vendored
@ -1,3 +1,16 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package procfs
|
package procfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
13
vendor/github.com/prometheus/procfs/proc_limits_test.go
generated
vendored
13
vendor/github.com/prometheus/procfs/proc_limits_test.go
generated
vendored
@ -1,3 +1,16 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package procfs
|
package procfs
|
||||||
|
|
||||||
import "testing"
|
import "testing"
|
||||||
|
68
vendor/github.com/prometheus/procfs/proc_ns.go
generated
vendored
Normal file
68
vendor/github.com/prometheus/procfs/proc_ns.go
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package procfs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Namespace represents a single namespace of a process.
|
||||||
|
type Namespace struct {
|
||||||
|
Type string // Namespace type.
|
||||||
|
Inode uint32 // Inode number of the namespace. If two processes are in the same namespace their inodes will match.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Namespaces contains all of the namespaces that the process is contained in.
|
||||||
|
type Namespaces map[string]Namespace
|
||||||
|
|
||||||
|
// NewNamespaces reads from /proc/[pid/ns/* to get the namespaces of which the
|
||||||
|
// process is a member.
|
||||||
|
func (p Proc) NewNamespaces() (Namespaces, error) {
|
||||||
|
d, err := os.Open(p.path("ns"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer d.Close()
|
||||||
|
|
||||||
|
names, err := d.Readdirnames(-1)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to read contents of ns dir: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ns := make(Namespaces, len(names))
|
||||||
|
for _, name := range names {
|
||||||
|
target, err := os.Readlink(p.path("ns", name))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fields := strings.SplitN(target, ":", 2)
|
||||||
|
if len(fields) != 2 {
|
||||||
|
return nil, fmt.Errorf("failed to parse namespace type and inode from '%v'", target)
|
||||||
|
}
|
||||||
|
|
||||||
|
typ := fields[0]
|
||||||
|
inode, err := strconv.ParseUint(strings.Trim(fields[1], "[]"), 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to parse inode from '%v': %v", fields[1], err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ns[name] = Namespace{typ, uint32(inode)}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ns, nil
|
||||||
|
}
|
44
vendor/github.com/prometheus/procfs/proc_ns_test.go
generated
vendored
Normal file
44
vendor/github.com/prometheus/procfs/proc_ns_test.go
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright 2018 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package procfs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewNamespaces(t *testing.T) {
|
||||||
|
p, err := FS("fixtures").NewProc(26231)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
namespaces, err := p.NewNamespaces()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedNamespaces := map[string]Namespace{
|
||||||
|
"mnt": {"mnt", 4026531840},
|
||||||
|
"net": {"net", 4026531993},
|
||||||
|
}
|
||||||
|
|
||||||
|
if want, have := len(expectedNamespaces), len(namespaces); want != have {
|
||||||
|
t.Errorf("want %d parsed namespaces, have %d", want, have)
|
||||||
|
}
|
||||||
|
for _, ns := range namespaces {
|
||||||
|
if want, have := expectedNamespaces[ns.Type], ns; want != have {
|
||||||
|
t.Errorf("%s: want %v, have %v", ns.Type, want, have)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user