Clean up code around Prometheus metrics, more DRY.

With this change, all definitions and functionality for a given metric
are in a single place only instead of being distributed all over the
file. This makes it easier to inspect the code for correctness and
adding/changing metrics.
This commit is contained in:
Julius Volz 2015-03-13 00:00:21 +01:00 committed by Julius Volz
parent b28b26ca30
commit fa17966229

View File

@ -23,61 +23,52 @@ import (
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
// This will usually be manager.Manager, but can be swapped out for testing.
type subcontainersInfoProvider interface { type subcontainersInfoProvider interface {
// Get information about all subcontainers of the specified container (includes self). // Get information about all subcontainers of the specified container (includes self).
SubcontainersInfo(containerName string, query *info.ContainerInfoRequest) ([]*info.ContainerInfo, error) SubcontainersInfo(containerName string, query *info.ContainerInfoRequest) ([]*info.ContainerInfo, error)
} }
type prometheusMetric struct { // metricValue describes a single metric value for a given set of label values
valueType prometheus.ValueType // within a parent containerMetric.
value float64 type metricValue struct {
labels []string value float64
labels []string
}
type metricValues []metricValue
// fsValues is a helper method for assembling per-filesystem stats.
func fsValues(fsStats []info.FsStats, valueFn func(*info.FsStats) float64) metricValues {
values := make(metricValues, 0, len(fsStats))
for _, stat := range fsStats {
values = append(values, metricValue{
value: valueFn(&stat),
labels: []string{stat.Device},
})
}
return values
}
// A containerMetric describes a multi-dimensional metric used for exposing
// a certain type of container statistic.
type containerMetric struct {
name string
help string
valueType prometheus.ValueType
extraLabels []string
getValues func(s *info.ContainerStats) metricValues
}
func (cm *containerMetric) desc() *prometheus.Desc {
return prometheus.NewDesc(cm.name, cm.help, append([]string{"name", "id"}, cm.extraLabels...), nil)
} }
// PrometheusCollector implements prometheus.Collector. // PrometheusCollector implements prometheus.Collector.
type PrometheusCollector struct { type PrometheusCollector struct {
infoProvider subcontainersInfoProvider infoProvider subcontainersInfoProvider
errors prometheus.Gauge
errors prometheus.Gauge containerMetrics []containerMetric
lastSeen *prometheus.Desc
cpuUsageUserSeconds *prometheus.Desc
cpuUsageSystemSeconds *prometheus.Desc
cpuUsageSecondsPerCPU *prometheus.Desc
memoryUsageBytes *prometheus.Desc
memoryWorkingSet *prometheus.Desc
memoryFailures *prometheus.Desc
fsLimit *prometheus.Desc
fsUsage *prometheus.Desc
fsReads *prometheus.Desc
fsReadsSectors *prometheus.Desc
fsReadsMerged *prometheus.Desc
fsReadTime *prometheus.Desc
fsWrites *prometheus.Desc
fsWritesSectors *prometheus.Desc
fsWritesMerged *prometheus.Desc
fsWriteTime *prometheus.Desc
fsIoInProgress *prometheus.Desc
fsIoTime *prometheus.Desc
fsWeightedIoTime *prometheus.Desc
networkRxBytes *prometheus.Desc
networkRxPackets *prometheus.Desc
networkRxErrors *prometheus.Desc
networkRxDropped *prometheus.Desc
networkTxBytes *prometheus.Desc
networkTxPackets *prometheus.Desc
networkTxErrors *prometheus.Desc
networkTxDropped *prometheus.Desc
tasks *prometheus.Desc
descs []*prometheus.Desc
} }
// NewPrometheusCollector returns a new PrometheusCollector. // NewPrometheusCollector returns a new PrometheusCollector.
@ -89,188 +80,299 @@ func NewPrometheusCollector(infoProvider subcontainersInfoProvider) *PrometheusC
Name: "scrape_error", Name: "scrape_error",
Help: "1 if there was an error while getting container metrics, 0 otherwise", Help: "1 if there was an error while getting container metrics, 0 otherwise",
}), }),
lastSeen: prometheus.NewDesc( containerMetrics: []containerMetric{
"container_last_seen", {
"Last time a container was seen by the exporter", name: "container_last_seen",
[]string{"name", "id"}, help: "Last time a container was seen by the exporter",
nil), valueType: prometheus.GaugeValue,
cpuUsageUserSeconds: prometheus.NewDesc( getValues: func(s *info.ContainerStats) metricValues {
"container_cpu_user_seconds_total", return metricValues{{value: float64(time.Now().Unix())}}
"Cumulative user cpu time consumed in seconds.", },
[]string{"name", "id"}, }, {
nil), name: "container_cpu_user_seconds_total",
cpuUsageSystemSeconds: prometheus.NewDesc( help: "Cumulative user cpu time consumed in seconds.",
"container_cpu_system_seconds_total", valueType: prometheus.CounterValue,
"Cumulative system cpu time consumed in seconds.", getValues: func(s *info.ContainerStats) metricValues {
[]string{"name", "id"}, return metricValues{{value: float64(s.Cpu.Usage.User) / float64(time.Second)}}
nil), },
cpuUsageSecondsPerCPU: prometheus.NewDesc( }, {
"container_cpu_usage_seconds_total", name: "container_cpu_system_seconds_total",
"Cumulative cpu time consumed per cpu in seconds.", help: "Cumulative system cpu time consumed in seconds.",
[]string{"name", "id", "cpu"}, valueType: prometheus.CounterValue,
nil), getValues: func(s *info.ContainerStats) metricValues {
memoryUsageBytes: prometheus.NewDesc( return metricValues{{value: float64(s.Cpu.Usage.System) / float64(time.Second)}}
"container_memory_usage_bytes", },
"Current memory usage in bytes.", }, {
[]string{"name", "id"}, name: "container_cpu_usage_seconds_total",
nil), help: "Cumulative cpu time consumed per cpu in seconds.",
memoryWorkingSet: prometheus.NewDesc( valueType: prometheus.CounterValue,
"container_memory_working_set_bytes", extraLabels: []string{"cpu"},
"Current working set in bytes.", getValues: func(s *info.ContainerStats) metricValues {
[]string{"name", "id"}, values := make(metricValues, 0, len(s.Cpu.Usage.PerCpu))
nil), for i, value := range s.Cpu.Usage.PerCpu {
memoryFailures: prometheus.NewDesc( values = append(values, metricValue{
"container_memory_failures_total", value: float64(value) / float64(time.Second),
"Cumulative count of memory allocation failures.", labels: []string{fmt.Sprintf("cpu%02d", i)},
[]string{"type", "scope", "name", "id"}, })
nil), }
return values
fsLimit: prometheus.NewDesc( },
"container_fs_limit_bytes", }, {
"Number of bytes that can be consumed by the container on this filesystem.", name: "container_memory_usage_bytes",
[]string{"name", "id", "device"}, help: "Current memory usage in bytes.",
nil), valueType: prometheus.GaugeValue,
fsUsage: prometheus.NewDesc( getValues: func(s *info.ContainerStats) metricValues {
"container_fs_usage_bytes", return metricValues{{value: float64(s.Memory.Usage)}}
"Number of bytes that are consumed by the container on this filesystem.", },
[]string{"name", "id", "device"}, }, {
nil), name: "container_memory_working_set_bytes",
fsReads: prometheus.NewDesc( help: "Current working set in bytes.",
"container_fs_reads_total", valueType: prometheus.GaugeValue,
"Cumulative count of reads completed", getValues: func(s *info.ContainerStats) metricValues {
[]string{"name", "id", "device"}, return metricValues{{value: float64(s.Memory.WorkingSet)}}
nil), },
fsReadsSectors: prometheus.NewDesc( }, {
"container_fs_sector_reads_total", name: "container_memory_failures_total",
"Cumulative count of sector reads completed", help: "Cumulative count of memory allocation failures.",
[]string{"name", "id", "device"}, valueType: prometheus.CounterValue,
nil), extraLabels: []string{"type", "scope"},
fsReadsMerged: prometheus.NewDesc( getValues: func(s *info.ContainerStats) metricValues {
"container_fs_reads_merged_total", return metricValues{
"Cumulative count of reads merged", {
[]string{"name", "id", "device"}, value: float64(s.Memory.ContainerData.Pgfault),
nil), labels: []string{"pgfault", "container"},
fsReadTime: prometheus.NewDesc( },
"container_fs_read_seconds_total", {
"Cumulative count of seconds spent reading", value: float64(s.Memory.ContainerData.Pgmajfault),
[]string{"name", "id", "device"}, labels: []string{"pgmajfault", "container"},
nil), },
fsWrites: prometheus.NewDesc( {
"container_fs_writes_total", value: float64(s.Memory.HierarchicalData.Pgfault),
"Cumulative count of writes completed", labels: []string{"pgfault", "hierarchy"},
[]string{"name", "id", "device"}, },
nil), {
fsWritesSectors: prometheus.NewDesc( value: float64(s.Memory.HierarchicalData.Pgmajfault),
"container_fs_sector_writes_total", labels: []string{"pgmajfault", "hierarchy"},
"Cumulative count of sector writes completed", },
[]string{"name", "id", "device"}, }
nil), },
fsWritesMerged: prometheus.NewDesc( }, {
"container_fs_writes_merged_total", name: "container_fs_limit_bytes",
"Cumulative count of writes merged", help: "Number of bytes that can be consumed by the container on this filesystem.",
[]string{"name", "id", "device"}, valueType: prometheus.GaugeValue,
nil), extraLabels: []string{"device"},
fsWriteTime: prometheus.NewDesc( getValues: func(s *info.ContainerStats) metricValues {
"container_fs_write_seconds_total", return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
"Cumulative count of seconds spent writing", return float64(fs.Limit)
[]string{"name", "id", "device"}, })
nil), },
fsIoInProgress: prometheus.NewDesc( }, {
"container_fs_io_current", name: "container_fs_usage_bytes",
"Number of I/Os currently in progress", help: "Number of bytes that are consumed by the container on this filesystem.",
[]string{"name", "id", "device"}, valueType: prometheus.GaugeValue,
nil), extraLabels: []string{"device"},
fsIoTime: prometheus.NewDesc( getValues: func(s *info.ContainerStats) metricValues {
"container_fs_io_time_seconds_total", return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
"Cumulative count of seconds spent doing I/Os", return float64(fs.Usage)
[]string{"name", "id", "device"}, })
nil), },
fsWeightedIoTime: prometheus.NewDesc( }, {
"container_fs_io_time_weighted_seconds_total", name: "container_fs_reads_total",
"Cumulative weighted I/O time in seconds", help: "Cumulative count of reads completed",
[]string{"name", "id", "device"}, valueType: prometheus.CounterValue,
nil), extraLabels: []string{"device"},
networkRxBytes: prometheus.NewDesc( getValues: func(s *info.ContainerStats) metricValues {
"container_network_receive_bytes_total", return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
"Cumulative count of bytes received", return float64(fs.ReadsCompleted)
[]string{"name", "id"}, })
nil), },
networkRxPackets: prometheus.NewDesc( }, {
"container_network_receive_packets_total", name: "container_fs_sector_reads_total",
"Cumulative count of packets received", help: "Cumulative count of sector reads completed",
[]string{"name", "id"}, valueType: prometheus.CounterValue,
nil), extraLabels: []string{"device"},
networkRxDropped: prometheus.NewDesc( getValues: func(s *info.ContainerStats) metricValues {
"container_network_receive_packets_dropped_total", return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
"Cumulative count of packets dropped while receiving", return float64(fs.SectorsRead)
[]string{"name", "id"}, })
nil), },
networkRxErrors: prometheus.NewDesc( }, {
"container_network_receive_errors_total", name: "container_fs_reads_merged_total",
"Cumulative count of errors encountered while receiving", help: "Cumulative count of reads merged",
[]string{"name", "id"}, valueType: prometheus.CounterValue,
nil), extraLabels: []string{"device"},
networkTxBytes: prometheus.NewDesc( getValues: func(s *info.ContainerStats) metricValues {
"container_network_transmit_bytes_total", return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
"Cumulative count of bytes transmitted", return float64(fs.ReadsMerged)
[]string{"name", "id"}, })
nil), },
networkTxPackets: prometheus.NewDesc( }, {
"container_network_transmit_packets_total", name: "container_fs_read_seconds_total",
"Cumulative count of packets transmitted", help: "Cumulative count of seconds spent reading",
[]string{"name", "id"}, valueType: prometheus.CounterValue,
nil), extraLabels: []string{"device"},
networkTxDropped: prometheus.NewDesc( getValues: func(s *info.ContainerStats) metricValues {
"container_network_transmit_packets_dropped_total", return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
"Cumulative count of packets dropped while transmitting", return float64(fs.ReadTime) / float64(time.Second)
[]string{"name", "id"}, })
nil), },
networkTxErrors: prometheus.NewDesc( }, {
"container_network_transmit_errors_total", name: "container_fs_writes_total",
"Cumulative count of errors encountered while transmitting", help: "Cumulative count of writes completed",
[]string{"name", "id"}, valueType: prometheus.CounterValue,
nil), extraLabels: []string{"device"},
getValues: func(s *info.ContainerStats) metricValues {
tasks: prometheus.NewDesc( return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
"container_tasks_state", return float64(fs.WritesCompleted)
"Number of tasks in given state", })
[]string{"state", "name", "id"}, },
nil), }, {
} name: "container_fs_sector_writes_total",
c.descs = []*prometheus.Desc{ help: "Cumulative count of sector writes completed",
c.lastSeen, valueType: prometheus.CounterValue,
extraLabels: []string{"device"},
c.cpuUsageUserSeconds, getValues: func(s *info.ContainerStats) metricValues {
c.cpuUsageSystemSeconds, return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
return float64(fs.SectorsWritten)
c.memoryUsageBytes, })
c.memoryWorkingSet, },
c.memoryFailures, }, {
name: "container_fs_writes_merged_total",
c.fsLimit, help: "Cumulative count of writes merged",
c.fsUsage, valueType: prometheus.CounterValue,
c.fsReads, extraLabels: []string{"device"},
c.fsReadsSectors, getValues: func(s *info.ContainerStats) metricValues {
c.fsReadsMerged, return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
c.fsReadTime, return float64(fs.WritesMerged)
c.fsWrites, })
c.fsWritesSectors, },
c.fsWritesMerged, }, {
c.fsWriteTime, name: "container_fs_write_seconds_total",
c.fsIoInProgress, help: "Cumulative count of seconds spent writing",
c.fsIoTime, valueType: prometheus.CounterValue,
c.fsWeightedIoTime, extraLabels: []string{"device"},
getValues: func(s *info.ContainerStats) metricValues {
c.networkRxBytes, return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
c.networkRxPackets, return float64(fs.WriteTime) / float64(time.Second)
c.networkRxErrors, })
c.networkRxDropped, },
c.networkTxBytes, }, {
c.networkTxPackets, name: "container_fs_io_current",
c.networkTxErrors, help: "Number of I/Os currently in progress",
c.networkTxDropped, valueType: prometheus.GaugeValue,
extraLabels: []string{"device"},
c.tasks, getValues: func(s *info.ContainerStats) metricValues {
return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
return float64(fs.IoInProgress)
})
},
}, {
name: "container_fs_io_time_seconds_total",
help: "Cumulative count of seconds spent doing I/Os",
valueType: prometheus.CounterValue,
extraLabels: []string{"device"},
getValues: func(s *info.ContainerStats) metricValues {
return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
return float64(float64(fs.IoTime) / float64(time.Second))
})
},
}, {
name: "container_fs_io_time_weighted_seconds_total",
help: "Cumulative weighted I/O time in seconds",
valueType: prometheus.CounterValue,
extraLabels: []string{"device"},
getValues: func(s *info.ContainerStats) metricValues {
return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
return float64(fs.WeightedIoTime) / float64(time.Second)
})
},
}, {
name: "container_network_receive_bytes_total",
help: "Cumulative count of bytes received",
valueType: prometheus.CounterValue,
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{{value: float64(s.Network.RxBytes)}}
},
}, {
name: "container_network_receive_packets_total",
help: "Cumulative count of packets received",
valueType: prometheus.CounterValue,
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{{value: float64(s.Network.RxPackets)}}
},
}, {
name: "container_network_receive_packets_dropped_total",
help: "Cumulative count of packets dropped while receiving",
valueType: prometheus.CounterValue,
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{{value: float64(s.Network.RxDropped)}}
},
}, {
name: "container_network_receive_errors_total",
help: "Cumulative count of errors encountered while receiving",
valueType: prometheus.CounterValue,
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{{value: float64(s.Network.RxErrors)}}
},
}, {
name: "container_network_transmit_bytes_total",
help: "Cumulative count of bytes transmitted",
valueType: prometheus.CounterValue,
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{{value: float64(s.Network.TxBytes)}}
},
}, {
name: "container_network_transmit_packets_total",
help: "Cumulative count of packets transmitted",
valueType: prometheus.CounterValue,
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{{value: float64(s.Network.TxPackets)}}
},
}, {
name: "container_network_transmit_packets_dropped_total",
help: "Cumulative count of packets dropped while transmitting",
valueType: prometheus.CounterValue,
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{{value: float64(s.Network.TxDropped)}}
},
}, {
name: "container_network_transmit_errors_total",
help: "Cumulative count of errors encountered while transmitting",
valueType: prometheus.CounterValue,
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{{value: float64(s.Network.TxErrors)}}
},
}, {
name: "container_tasks_state",
help: "Number of tasks in given state",
extraLabels: []string{"state"},
valueType: prometheus.GaugeValue,
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{
{
value: float64(s.TaskStats.NrSleeping),
labels: []string{"sleeping"},
},
{
value: float64(s.TaskStats.NrRunning),
labels: []string{"running"},
},
{
value: float64(s.TaskStats.NrStopped),
labels: []string{"stopped"},
},
{
value: float64(s.TaskStats.NrUninterruptible),
labels: []string{"uninterruptible"},
},
{
value: float64(s.TaskStats.NrIoWait),
labels: []string{"iowaiting"},
},
}
},
},
},
} }
return c return c
} }
@ -279,8 +381,8 @@ func NewPrometheusCollector(infoProvider subcontainersInfoProvider) *PrometheusC
// implements prometheus.PrometheusCollector. // implements prometheus.PrometheusCollector.
func (c *PrometheusCollector) Describe(ch chan<- *prometheus.Desc) { func (c *PrometheusCollector) Describe(ch chan<- *prometheus.Desc) {
c.errors.Describe(ch) c.errors.Describe(ch)
for _, d := range c.descs { for _, cm := range c.containerMetrics {
ch <- d ch <- cm.desc()
} }
} }
@ -301,68 +403,10 @@ func (c *PrometheusCollector) Collect(ch chan<- prometheus.Metric) {
} }
stats := container.Stats[0] stats := container.Stats[0]
for desc, metrics := range map[*prometheus.Desc][]prometheusMetric{ for _, cm := range c.containerMetrics {
c.cpuUsageUserSeconds: {{valueType: prometheus.CounterValue, value: float64(stats.Cpu.Usage.User) / float64(time.Second)}}, desc := cm.desc()
c.cpuUsageSystemSeconds: {{valueType: prometheus.CounterValue, value: float64(stats.Cpu.Usage.System) / float64(time.Second)}}, for _, metricValue := range cm.getValues(stats) {
ch <- prometheus.MustNewConstMetric(desc, cm.valueType, float64(metricValue.value), append([]string{name, id}, metricValue.labels...)...)
c.memoryFailures: {
{valueType: prometheus.CounterValue, labels: []string{"pgfault", "container"}, value: float64(stats.Memory.ContainerData.Pgfault)},
{valueType: prometheus.CounterValue, labels: []string{"pgmajfault", "container"}, value: float64(stats.Memory.ContainerData.Pgmajfault)},
{valueType: prometheus.CounterValue, labels: []string{"pgfault", "hierarchy"}, value: float64(stats.Memory.HierarchicalData.Pgfault)},
{valueType: prometheus.CounterValue, labels: []string{"pgmajfault", "hierarchy"}, value: float64(stats.Memory.HierarchicalData.Pgmajfault)},
},
c.tasks: {
{valueType: prometheus.GaugeValue, labels: []string{"sleeping"}, value: float64(stats.TaskStats.NrSleeping)},
{valueType: prometheus.GaugeValue, labels: []string{"running"}, value: float64(stats.TaskStats.NrRunning)},
{valueType: prometheus.GaugeValue, labels: []string{"stopped"}, value: float64(stats.TaskStats.NrStopped)},
{valueType: prometheus.GaugeValue, labels: []string{"uninterruptible"}, value: float64(stats.TaskStats.NrUninterruptible)},
{valueType: prometheus.GaugeValue, labels: []string{"iowaiting"}, value: float64(stats.TaskStats.NrIoWait)},
},
c.lastSeen: {{valueType: prometheus.GaugeValue, value: float64(time.Now().Unix())}},
c.memoryUsageBytes: {{valueType: prometheus.GaugeValue, value: float64(stats.Memory.Usage)}},
c.memoryWorkingSet: {{valueType: prometheus.GaugeValue, value: float64(stats.Memory.WorkingSet)}},
c.networkRxBytes: {{valueType: prometheus.CounterValue, value: float64(stats.Network.RxBytes)}},
c.networkRxPackets: {{valueType: prometheus.CounterValue, value: float64(stats.Network.RxPackets)}},
c.networkRxErrors: {{valueType: prometheus.CounterValue, value: float64(stats.Network.RxErrors)}},
c.networkRxDropped: {{valueType: prometheus.CounterValue, value: float64(stats.Network.RxDropped)}},
c.networkTxBytes: {{valueType: prometheus.CounterValue, value: float64(stats.Network.TxBytes)}},
c.networkTxPackets: {{valueType: prometheus.CounterValue, value: float64(stats.Network.TxPackets)}},
c.networkTxErrors: {{valueType: prometheus.CounterValue, value: float64(stats.Network.TxErrors)}},
c.networkTxDropped: {{valueType: prometheus.CounterValue, value: float64(stats.Network.TxDropped)}},
} {
for _, m := range metrics {
ch <- prometheus.MustNewConstMetric(desc, m.valueType, float64(m.value), append(m.labels, name, id)...)
}
}
// Metrics with dynamic labels
for i, value := range stats.Cpu.Usage.PerCpu {
ch <- prometheus.MustNewConstMetric(c.cpuUsageSecondsPerCPU, prometheus.CounterValue, float64(value)/float64(time.Second), name, id, fmt.Sprintf("cpu%02d", i))
}
for _, stat := range stats.Filesystem {
for desc, m := range map[*prometheus.Desc]prometheusMetric{
c.fsReads: {valueType: prometheus.CounterValue, value: float64(stat.ReadsCompleted)},
c.fsReadsSectors: {valueType: prometheus.CounterValue, value: float64(stat.SectorsRead)},
c.fsReadsMerged: {valueType: prometheus.CounterValue, value: float64(stat.ReadsMerged)},
c.fsReadTime: {valueType: prometheus.CounterValue, value: float64(stat.ReadTime) / float64(time.Second)},
c.fsWrites: {valueType: prometheus.CounterValue, value: float64(stat.WritesCompleted)},
c.fsWritesSectors: {valueType: prometheus.CounterValue, value: float64(stat.SectorsWritten)},
c.fsWritesMerged: {valueType: prometheus.CounterValue, value: float64(stat.WritesMerged)},
c.fsWriteTime: {valueType: prometheus.CounterValue, value: float64(stat.WriteTime) / float64(time.Second)},
c.fsIoTime: {valueType: prometheus.CounterValue, value: float64(stat.IoTime) / float64(time.Second)},
c.fsWeightedIoTime: {valueType: prometheus.CounterValue, value: float64(stat.WeightedIoTime) / float64(time.Second)},
c.fsIoInProgress: {valueType: prometheus.GaugeValue, value: float64(stat.IoInProgress)},
c.fsLimit: {valueType: prometheus.GaugeValue, value: float64(stat.Limit)},
c.fsUsage: {valueType: prometheus.GaugeValue, value: float64(stat.Usage)},
} {
ch <- prometheus.MustNewConstMetric(desc, m.valueType, m.value, name, id, stat.Device)
} }
} }
} }