Add device path to metrics
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
c90e0c94a5
commit
d219b47f65
5 changed files with 91 additions and 20 deletions
|
@ -1,6 +1,6 @@
|
||||||
github.com/crosbymichael/go-runc bd9aef7cf4402a3a8728e3ef83dcca6a5a1be899
|
github.com/crosbymichael/go-runc bd9aef7cf4402a3a8728e3ef83dcca6a5a1be899
|
||||||
github.com/crosbymichael/console 4bf9d88357031b516b3794a2594b6d060a29c59c
|
github.com/crosbymichael/console 4bf9d88357031b516b3794a2594b6d060a29c59c
|
||||||
github.com/crosbymichael/cgroups 66fd96cb5fc92fdcd32b61518b2619d489784256
|
github.com/crosbymichael/cgroups 74ce513f69d6dbdb355668b4b4ca7ac3d0886664
|
||||||
github.com/docker/go-metrics 8fd5772bf1584597834c6f7961a530f06cbfbb87
|
github.com/docker/go-metrics 8fd5772bf1584597834c6f7961a530f06cbfbb87
|
||||||
github.com/prometheus/client_golang v0.8.0
|
github.com/prometheus/client_golang v0.8.0
|
||||||
github.com/prometheus/client_model fa8ad6fec33561be4280a8f0514318c79d7f6cb6
|
github.com/prometheus/client_model fa8ad6fec33561be4280a8f0514318c79d7f6cb6
|
||||||
|
|
74
vendor/github.com/crosbymichael/cgroups/blkio.go
generated
vendored
74
vendor/github.com/crosbymichael/cgroups/blkio.go
generated
vendored
|
@ -8,6 +8,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
)
|
)
|
||||||
|
@ -104,15 +105,21 @@ func (b *blkioController) Stat(path string, stats *Stats) error {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
devices, err := getDevices("/dev")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
for _, t := range settings {
|
for _, t := range settings {
|
||||||
if err := b.readEntry(path, t.name, t.entry); err != nil {
|
if err := b.readEntry(devices, path, t.name, t.entry); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *blkioController) readEntry(path, name string, entry *[]BlkioEntry) error {
|
func (b *blkioController) readEntry(devices map[deviceKey]string, path, name string, entry *[]BlkioEntry) error {
|
||||||
f, err := os.Open(filepath.Join(b.Path(path), fmt.Sprintf("blkio.%s", name)))
|
f, err := os.Open(filepath.Join(b.Path(path), fmt.Sprintf("blkio.%s", name)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -152,6 +159,7 @@ func (b *blkioController) readEntry(path, name string, entry *[]BlkioEntry) erro
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
*entry = append(*entry, BlkioEntry{
|
*entry = append(*entry, BlkioEntry{
|
||||||
|
Device: devices[deviceKey{major, minor}],
|
||||||
Major: major,
|
Major: major,
|
||||||
Minor: minor,
|
Minor: minor,
|
||||||
Op: op,
|
Op: op,
|
||||||
|
@ -160,6 +168,7 @@ func (b *blkioController) readEntry(path, name string, entry *[]BlkioEntry) erro
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createBlkioSettings(blkio *specs.LinuxBlockIO) []blkioSettings {
|
func createBlkioSettings(blkio *specs.LinuxBlockIO) []blkioSettings {
|
||||||
settings := []blkioSettings{
|
settings := []blkioSettings{
|
||||||
{
|
{
|
||||||
|
@ -251,3 +260,64 @@ func throttleddev(v interface{}) []byte {
|
||||||
func splitBlkioStatLine(r rune) bool {
|
func splitBlkioStatLine(r rune) bool {
|
||||||
return r == ' ' || r == ':'
|
return r == ' ' || r == ':'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type deviceKey struct {
|
||||||
|
major, minor uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// getDevices makes a best effort attempt to read all the devices into a map
|
||||||
|
// keyed by major and minor number. Since devices may be mapped multiple times,
|
||||||
|
// we err on taking the first occurrence.
|
||||||
|
func getDevices(path string) (map[deviceKey]string, error) {
|
||||||
|
// TODO(stevvooe): We are ignoring lots of errors. It might be kind of
|
||||||
|
// challenging to debug this if we aren't mapping devices correctly.
|
||||||
|
// Consider logging these errors.
|
||||||
|
devices := map[deviceKey]string{}
|
||||||
|
if err := filepath.Walk(path, func(p string, fi os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case fi.IsDir():
|
||||||
|
switch fi.Name() {
|
||||||
|
case "pts", "shm", "fd", "mqueue", ".lxc", ".lxd-mounts":
|
||||||
|
return filepath.SkipDir
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
case fi.Name() == "console":
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
if fi.Mode()&os.ModeDevice == 0 {
|
||||||
|
// skip non-devices
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
st, ok := fi.Sys().(*syscall.Stat_t)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("%s: unable to convert to system stat", p)
|
||||||
|
}
|
||||||
|
|
||||||
|
key := deviceKey{major(st.Rdev), minor(st.Rdev)}
|
||||||
|
if _, ok := devices[key]; ok {
|
||||||
|
return nil // skip it if we have already populated the path.
|
||||||
|
}
|
||||||
|
|
||||||
|
devices[key] = p
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return devices, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func major(devNumber uint64) uint64 {
|
||||||
|
return (devNumber >> 8) & 0xfff
|
||||||
|
}
|
||||||
|
|
||||||
|
func minor(devNumber uint64) uint64 {
|
||||||
|
return (devNumber & 0xff) | ((devNumber >> 12) & 0xfff00)
|
||||||
|
}
|
||||||
|
|
14
vendor/github.com/crosbymichael/cgroups/prometheus/blkio.go
generated
vendored
14
vendor/github.com/crosbymichael/cgroups/prometheus/blkio.go
generated
vendored
|
@ -12,7 +12,7 @@ var blkioMetrics = []*metric{
|
||||||
help: "The blkio io merged recursive",
|
help: "The blkio io merged recursive",
|
||||||
unit: metrics.Total,
|
unit: metrics.Total,
|
||||||
vt: prometheus.GaugeValue,
|
vt: prometheus.GaugeValue,
|
||||||
labels: []string{"op", "major", "minor"},
|
labels: []string{"op", "device", "major", "minor"},
|
||||||
getValues: func(stats *cgroups.Stats) []value {
|
getValues: func(stats *cgroups.Stats) []value {
|
||||||
if stats.Blkio == nil {
|
if stats.Blkio == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -25,7 +25,7 @@ var blkioMetrics = []*metric{
|
||||||
help: "The blkio io queued recursive",
|
help: "The blkio io queued recursive",
|
||||||
unit: metrics.Total,
|
unit: metrics.Total,
|
||||||
vt: prometheus.GaugeValue,
|
vt: prometheus.GaugeValue,
|
||||||
labels: []string{"op", "major", "minor"},
|
labels: []string{"op", "device", "major", "minor"},
|
||||||
getValues: func(stats *cgroups.Stats) []value {
|
getValues: func(stats *cgroups.Stats) []value {
|
||||||
if stats.Blkio == nil {
|
if stats.Blkio == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -38,7 +38,7 @@ var blkioMetrics = []*metric{
|
||||||
help: "The blkio io service bytes recursive",
|
help: "The blkio io service bytes recursive",
|
||||||
unit: metrics.Bytes,
|
unit: metrics.Bytes,
|
||||||
vt: prometheus.GaugeValue,
|
vt: prometheus.GaugeValue,
|
||||||
labels: []string{"op", "major", "minor"},
|
labels: []string{"op", "device", "major", "minor"},
|
||||||
getValues: func(stats *cgroups.Stats) []value {
|
getValues: func(stats *cgroups.Stats) []value {
|
||||||
if stats.Blkio == nil {
|
if stats.Blkio == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -51,7 +51,7 @@ var blkioMetrics = []*metric{
|
||||||
help: "The blkio io servie time recursive",
|
help: "The blkio io servie time recursive",
|
||||||
unit: metrics.Total,
|
unit: metrics.Total,
|
||||||
vt: prometheus.GaugeValue,
|
vt: prometheus.GaugeValue,
|
||||||
labels: []string{"op", "major", "minor"},
|
labels: []string{"op", "device", "major", "minor"},
|
||||||
getValues: func(stats *cgroups.Stats) []value {
|
getValues: func(stats *cgroups.Stats) []value {
|
||||||
if stats.Blkio == nil {
|
if stats.Blkio == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -64,7 +64,7 @@ var blkioMetrics = []*metric{
|
||||||
help: "The blkio io servied recursive",
|
help: "The blkio io servied recursive",
|
||||||
unit: metrics.Total,
|
unit: metrics.Total,
|
||||||
vt: prometheus.GaugeValue,
|
vt: prometheus.GaugeValue,
|
||||||
labels: []string{"op", "major", "minor"},
|
labels: []string{"op", "device", "major", "minor"},
|
||||||
getValues: func(stats *cgroups.Stats) []value {
|
getValues: func(stats *cgroups.Stats) []value {
|
||||||
if stats.Blkio == nil {
|
if stats.Blkio == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -77,7 +77,7 @@ var blkioMetrics = []*metric{
|
||||||
help: "The blkio io time recursive",
|
help: "The blkio io time recursive",
|
||||||
unit: metrics.Total,
|
unit: metrics.Total,
|
||||||
vt: prometheus.GaugeValue,
|
vt: prometheus.GaugeValue,
|
||||||
labels: []string{"op", "major", "minor"},
|
labels: []string{"op", "device", "major", "minor"},
|
||||||
getValues: func(stats *cgroups.Stats) []value {
|
getValues: func(stats *cgroups.Stats) []value {
|
||||||
if stats.Blkio == nil {
|
if stats.Blkio == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -90,7 +90,7 @@ var blkioMetrics = []*metric{
|
||||||
help: "The blkio sectors recursive",
|
help: "The blkio sectors recursive",
|
||||||
unit: metrics.Total,
|
unit: metrics.Total,
|
||||||
vt: prometheus.GaugeValue,
|
vt: prometheus.GaugeValue,
|
||||||
labels: []string{"op", "major", "minor"},
|
labels: []string{"op", "device", "major", "minor"},
|
||||||
getValues: func(stats *cgroups.Stats) []value {
|
getValues: func(stats *cgroups.Stats) []value {
|
||||||
if stats.Blkio == nil {
|
if stats.Blkio == nil {
|
||||||
return nil
|
return nil
|
||||||
|
|
4
vendor/github.com/crosbymichael/cgroups/prometheus/metrics.go
generated
vendored
4
vendor/github.com/crosbymichael/cgroups/prometheus/metrics.go
generated
vendored
|
@ -59,7 +59,7 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) {
|
||||||
|
|
||||||
func (c *Collector) collect(id string, cg cgroups.Cgroup, ch chan<- prometheus.Metric, wg *sync.WaitGroup) {
|
func (c *Collector) collect(id string, cg cgroups.Cgroup, ch chan<- prometheus.Metric, wg *sync.WaitGroup) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
stats, err := cg.Stat()
|
stats, err := cg.Stat(cgroups.IgnoreNotExist)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithError(err).Errorf("stat cgroup %s", id)
|
logrus.WithError(err).Errorf("stat cgroup %s", id)
|
||||||
return
|
return
|
||||||
|
@ -92,7 +92,7 @@ func blkioValues(l []cgroups.BlkioEntry) []value {
|
||||||
for _, e := range l {
|
for _, e := range l {
|
||||||
out = append(out, value{
|
out = append(out, value{
|
||||||
v: float64(e.Value),
|
v: float64(e.Value),
|
||||||
l: []string{e.Op, strconv.FormatUint(e.Major, 10), strconv.FormatUint(e.Minor, 10)},
|
l: []string{e.Op, e.Device, strconv.FormatUint(e.Major, 10), strconv.FormatUint(e.Minor, 10)},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return out
|
return out
|
||||||
|
|
1
vendor/github.com/crosbymichael/cgroups/stats.go
generated
vendored
1
vendor/github.com/crosbymichael/cgroups/stats.go
generated
vendored
|
@ -102,6 +102,7 @@ type BlkioStat struct {
|
||||||
|
|
||||||
type BlkioEntry struct {
|
type BlkioEntry struct {
|
||||||
Op string
|
Op string
|
||||||
|
Device string
|
||||||
Major uint64
|
Major uint64
|
||||||
Minor uint64
|
Minor uint64
|
||||||
Value uint64
|
Value uint64
|
||||||
|
|
Loading…
Reference in a new issue