mirror of
https://github.com/prometheus/node_exporter.git
synced 2025-01-20 07:19:01 +01:00
Merge pull request #28 from prometheus/reduce-globals
Reduce number of global variables used
This commit is contained in:
commit
600a529e09
@ -7,12 +7,9 @@ import (
|
|||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
attributes *prometheus.GaugeVec
|
|
||||||
)
|
|
||||||
|
|
||||||
type attributesCollector struct {
|
type attributesCollector struct {
|
||||||
config Config
|
config Config
|
||||||
|
metric *prometheus.GaugeVec
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -22,28 +19,28 @@ func init() {
|
|||||||
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
||||||
// labels from the config.
|
// labels from the config.
|
||||||
func NewAttributesCollector(config Config) (Collector, error) {
|
func NewAttributesCollector(config Config) (Collector, error) {
|
||||||
c := attributesCollector{
|
|
||||||
config: config,
|
|
||||||
}
|
|
||||||
labelNames := []string{}
|
labelNames := []string{}
|
||||||
for l := range c.config.Attributes {
|
for l := range config.Attributes {
|
||||||
labelNames = append(labelNames, l)
|
labelNames = append(labelNames, l)
|
||||||
}
|
}
|
||||||
attributes = prometheus.NewGaugeVec(
|
|
||||||
prometheus.GaugeOpts{
|
return &attributesCollector{
|
||||||
Namespace: Namespace,
|
config: config,
|
||||||
Name: "attributes",
|
metric: prometheus.NewGaugeVec(
|
||||||
Help: "The node_exporter attributes.",
|
prometheus.GaugeOpts{
|
||||||
},
|
Namespace: Namespace,
|
||||||
labelNames,
|
Name: "attributes",
|
||||||
)
|
Help: "The node_exporter attributes.",
|
||||||
return &c, nil
|
},
|
||||||
|
labelNames,
|
||||||
|
),
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *attributesCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
func (c *attributesCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
||||||
glog.V(1).Info("Set node_attributes{%v}: 1", c.config.Attributes)
|
glog.V(1).Info("Set node_attributes{%v}: 1", c.config.Attributes)
|
||||||
attributes.Reset()
|
c.metric.Reset()
|
||||||
attributes.With(c.config.Attributes).Set(1)
|
c.metric.With(c.config.Attributes).Set(1)
|
||||||
attributes.Collect(ch)
|
c.metric.Collect(ch)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -16,22 +16,9 @@ const (
|
|||||||
sysfsNet = "/sys/class/net"
|
sysfsNet = "/sys/class/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
type bondingCollector struct {
|
||||||
bondingSlaves = prometheus.NewGaugeVec(
|
slaves, active *prometheus.GaugeVec
|
||||||
prometheus.GaugeOpts{
|
}
|
||||||
Namespace: Namespace,
|
|
||||||
Name: "net_bonding_slaves",
|
|
||||||
Help: "Number of configured slaves per bonding interface.",
|
|
||||||
}, []string{"master"})
|
|
||||||
bondingSlavesActive = prometheus.NewGaugeVec(
|
|
||||||
prometheus.GaugeOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Name: "net_bonding_slaves_active",
|
|
||||||
Help: "Number of active slaves per bonding interface.",
|
|
||||||
}, []string{"master"})
|
|
||||||
)
|
|
||||||
|
|
||||||
type bondingCollector struct{}
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
Factories["bonding"] = NewBondingCollector
|
Factories["bonding"] = NewBondingCollector
|
||||||
@ -40,8 +27,24 @@ func init() {
|
|||||||
// NewBondingCollector returns a newly allocated bondingCollector.
|
// NewBondingCollector returns a newly allocated bondingCollector.
|
||||||
// It exposes the number of configured and active slave of linux bonding interfaces.
|
// It exposes the number of configured and active slave of linux bonding interfaces.
|
||||||
func NewBondingCollector(config Config) (Collector, error) {
|
func NewBondingCollector(config Config) (Collector, error) {
|
||||||
c := bondingCollector{}
|
return &bondingCollector{
|
||||||
return &c, nil
|
slaves: prometheus.NewGaugeVec(
|
||||||
|
prometheus.GaugeOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Name: "net_bonding_slaves",
|
||||||
|
Help: "Number of configured slaves per bonding interface.",
|
||||||
|
},
|
||||||
|
[]string{"master"},
|
||||||
|
),
|
||||||
|
active: prometheus.NewGaugeVec(
|
||||||
|
prometheus.GaugeOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Name: "net_bonding_slaves_active",
|
||||||
|
Help: "Number of active slaves per bonding interface.",
|
||||||
|
},
|
||||||
|
[]string{"master"},
|
||||||
|
),
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update reads and exposes bonding states, implements Collector interface. Caution: This works only on linux.
|
// Update reads and exposes bonding states, implements Collector interface. Caution: This works only on linux.
|
||||||
@ -51,11 +54,11 @@ func (c *bondingCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for master, status := range bondingStats {
|
for master, status := range bondingStats {
|
||||||
bondingSlaves.WithLabelValues(master).Set(float64(status[0]))
|
c.slaves.WithLabelValues(master).Set(float64(status[0]))
|
||||||
bondingSlavesActive.WithLabelValues(master).Set(float64(status[1]))
|
c.active.WithLabelValues(master).Set(float64(status[1]))
|
||||||
}
|
}
|
||||||
bondingSlaves.Collect(ch)
|
c.slaves.Collect(ch)
|
||||||
bondingSlavesActive.Collect(ch)
|
c.active.Collect(ch)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,116 +23,12 @@ const (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
ignoredDevices = flag.String("diskstatsIgnoredDevices", "^(ram|loop|(h|s|xv)d[a-z])\\d+$", "Regexp of devices to ignore for diskstats.")
|
ignoredDevices = flag.String("diskstatsIgnoredDevices", "^(ram|loop|(h|s|xv)d[a-z])\\d+$", "Regexp of devices to ignore for diskstats.")
|
||||||
|
|
||||||
diskLabelNames = []string{"device"}
|
|
||||||
|
|
||||||
// Docs from https://www.kernel.org/doc/Documentation/iostats.txt
|
|
||||||
diskStatsMetrics = []prometheus.Collector{
|
|
||||||
prometheus.NewCounterVec(
|
|
||||||
prometheus.CounterOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Subsystem: diskSubsystem,
|
|
||||||
Name: "reads_completed",
|
|
||||||
Help: "The total number of reads completed successfully.",
|
|
||||||
},
|
|
||||||
diskLabelNames,
|
|
||||||
),
|
|
||||||
prometheus.NewCounterVec(
|
|
||||||
prometheus.CounterOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Subsystem: diskSubsystem,
|
|
||||||
Name: "reads_merged",
|
|
||||||
Help: "The number of reads merged. See https://www.kernel.org/doc/Documentation/iostats.txt.",
|
|
||||||
},
|
|
||||||
diskLabelNames,
|
|
||||||
),
|
|
||||||
prometheus.NewCounterVec(
|
|
||||||
prometheus.CounterOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Subsystem: diskSubsystem,
|
|
||||||
Name: "sectors_read",
|
|
||||||
Help: "The total number of sectors read successfully.",
|
|
||||||
},
|
|
||||||
diskLabelNames,
|
|
||||||
),
|
|
||||||
prometheus.NewCounterVec(
|
|
||||||
prometheus.CounterOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Subsystem: diskSubsystem,
|
|
||||||
Name: "read_time_ms",
|
|
||||||
Help: "The total number of milliseconds spent by all reads.",
|
|
||||||
},
|
|
||||||
diskLabelNames,
|
|
||||||
),
|
|
||||||
prometheus.NewCounterVec(
|
|
||||||
prometheus.CounterOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Subsystem: diskSubsystem,
|
|
||||||
Name: "writes_completed",
|
|
||||||
Help: "The total number of writes completed successfully.",
|
|
||||||
},
|
|
||||||
diskLabelNames,
|
|
||||||
),
|
|
||||||
prometheus.NewCounterVec(
|
|
||||||
prometheus.CounterOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Subsystem: diskSubsystem,
|
|
||||||
Name: "writes_merged",
|
|
||||||
Help: "The number of writes merged. See https://www.kernel.org/doc/Documentation/iostats.txt.",
|
|
||||||
},
|
|
||||||
diskLabelNames,
|
|
||||||
),
|
|
||||||
prometheus.NewCounterVec(
|
|
||||||
prometheus.CounterOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Subsystem: diskSubsystem,
|
|
||||||
Name: "sectors_written",
|
|
||||||
Help: "The total number of sectors written successfully.",
|
|
||||||
},
|
|
||||||
diskLabelNames,
|
|
||||||
),
|
|
||||||
prometheus.NewCounterVec(
|
|
||||||
prometheus.CounterOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Subsystem: diskSubsystem,
|
|
||||||
Name: "write_time_ms",
|
|
||||||
Help: "This is the total number of milliseconds spent by all writes.",
|
|
||||||
},
|
|
||||||
diskLabelNames,
|
|
||||||
),
|
|
||||||
prometheus.NewGaugeVec(
|
|
||||||
prometheus.GaugeOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Subsystem: diskSubsystem,
|
|
||||||
Name: "io_now",
|
|
||||||
Help: "The number of I/Os currently in progress.",
|
|
||||||
},
|
|
||||||
diskLabelNames,
|
|
||||||
),
|
|
||||||
prometheus.NewCounterVec(
|
|
||||||
prometheus.CounterOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Subsystem: diskSubsystem,
|
|
||||||
Name: "io_time_ms",
|
|
||||||
Help: "Milliseconds spent doing I/Os.",
|
|
||||||
},
|
|
||||||
diskLabelNames,
|
|
||||||
),
|
|
||||||
prometheus.NewCounterVec(
|
|
||||||
prometheus.CounterOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Subsystem: diskSubsystem,
|
|
||||||
Name: "io_time_weighted",
|
|
||||||
Help: "The weighted # of milliseconds spent doing I/Os. See https://www.kernel.org/doc/Documentation/iostats.txt.",
|
|
||||||
},
|
|
||||||
diskLabelNames,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type diskstatsCollector struct {
|
type diskstatsCollector struct {
|
||||||
config Config
|
config Config
|
||||||
ignoredDevicesPattern *regexp.Regexp
|
ignoredDevicesPattern *regexp.Regexp
|
||||||
|
metrics []prometheus.Collector
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -142,38 +38,148 @@ func init() {
|
|||||||
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
||||||
// disk device stats.
|
// disk device stats.
|
||||||
func NewDiskstatsCollector(config Config) (Collector, error) {
|
func NewDiskstatsCollector(config Config) (Collector, error) {
|
||||||
c := diskstatsCollector{
|
var diskLabelNames = []string{"device"}
|
||||||
|
|
||||||
|
return &diskstatsCollector{
|
||||||
config: config,
|
config: config,
|
||||||
ignoredDevicesPattern: regexp.MustCompile(*ignoredDevices),
|
ignoredDevicesPattern: regexp.MustCompile(*ignoredDevices),
|
||||||
}
|
// Docs from https://www.kernel.org/doc/Documentation/iostats.txt
|
||||||
return &c, nil
|
metrics: []prometheus.Collector{
|
||||||
|
prometheus.NewCounterVec(
|
||||||
|
prometheus.CounterOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Subsystem: diskSubsystem,
|
||||||
|
Name: "reads_completed",
|
||||||
|
Help: "The total number of reads completed successfully.",
|
||||||
|
},
|
||||||
|
diskLabelNames,
|
||||||
|
),
|
||||||
|
prometheus.NewCounterVec(
|
||||||
|
prometheus.CounterOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Subsystem: diskSubsystem,
|
||||||
|
Name: "reads_merged",
|
||||||
|
Help: "The number of reads merged. See https://www.kernel.org/doc/Documentation/iostats.txt.",
|
||||||
|
},
|
||||||
|
diskLabelNames,
|
||||||
|
),
|
||||||
|
prometheus.NewCounterVec(
|
||||||
|
prometheus.CounterOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Subsystem: diskSubsystem,
|
||||||
|
Name: "sectors_read",
|
||||||
|
Help: "The total number of sectors read successfully.",
|
||||||
|
},
|
||||||
|
diskLabelNames,
|
||||||
|
),
|
||||||
|
prometheus.NewCounterVec(
|
||||||
|
prometheus.CounterOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Subsystem: diskSubsystem,
|
||||||
|
Name: "read_time_ms",
|
||||||
|
Help: "The total number of milliseconds spent by all reads.",
|
||||||
|
},
|
||||||
|
diskLabelNames,
|
||||||
|
),
|
||||||
|
prometheus.NewCounterVec(
|
||||||
|
prometheus.CounterOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Subsystem: diskSubsystem,
|
||||||
|
Name: "writes_completed",
|
||||||
|
Help: "The total number of writes completed successfully.",
|
||||||
|
},
|
||||||
|
diskLabelNames,
|
||||||
|
),
|
||||||
|
prometheus.NewCounterVec(
|
||||||
|
prometheus.CounterOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Subsystem: diskSubsystem,
|
||||||
|
Name: "writes_merged",
|
||||||
|
Help: "The number of writes merged. See https://www.kernel.org/doc/Documentation/iostats.txt.",
|
||||||
|
},
|
||||||
|
diskLabelNames,
|
||||||
|
),
|
||||||
|
prometheus.NewCounterVec(
|
||||||
|
prometheus.CounterOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Subsystem: diskSubsystem,
|
||||||
|
Name: "sectors_written",
|
||||||
|
Help: "The total number of sectors written successfully.",
|
||||||
|
},
|
||||||
|
diskLabelNames,
|
||||||
|
),
|
||||||
|
prometheus.NewCounterVec(
|
||||||
|
prometheus.CounterOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Subsystem: diskSubsystem,
|
||||||
|
Name: "write_time_ms",
|
||||||
|
Help: "This is the total number of milliseconds spent by all writes.",
|
||||||
|
},
|
||||||
|
diskLabelNames,
|
||||||
|
),
|
||||||
|
prometheus.NewGaugeVec(
|
||||||
|
prometheus.GaugeOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Subsystem: diskSubsystem,
|
||||||
|
Name: "io_now",
|
||||||
|
Help: "The number of I/Os currently in progress.",
|
||||||
|
},
|
||||||
|
diskLabelNames,
|
||||||
|
),
|
||||||
|
prometheus.NewCounterVec(
|
||||||
|
prometheus.CounterOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Subsystem: diskSubsystem,
|
||||||
|
Name: "io_time_ms",
|
||||||
|
Help: "Milliseconds spent doing I/Os.",
|
||||||
|
},
|
||||||
|
diskLabelNames,
|
||||||
|
),
|
||||||
|
prometheus.NewCounterVec(
|
||||||
|
prometheus.CounterOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Subsystem: diskSubsystem,
|
||||||
|
Name: "io_time_weighted",
|
||||||
|
Help: "The weighted # of milliseconds spent doing I/Os. See https://www.kernel.org/doc/Documentation/iostats.txt.",
|
||||||
|
},
|
||||||
|
diskLabelNames,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
||||||
diskStats, err := getDiskStats()
|
diskStats, err := getDiskStats()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Couldn't get diskstats: %s", err)
|
return fmt.Errorf("couldn't get diskstats: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for dev, stats := range diskStats {
|
for dev, stats := range diskStats {
|
||||||
if c.ignoredDevicesPattern.MatchString(dev) {
|
if c.ignoredDevicesPattern.MatchString(dev) {
|
||||||
glog.V(1).Infof("Ignoring device: %s", dev)
|
glog.V(1).Infof("Ignoring device: %s", dev)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(stats) != len(c.metrics) {
|
||||||
|
return fmt.Errorf("invalid line for %s for %s", procDiskStats, dev)
|
||||||
|
}
|
||||||
|
|
||||||
for k, value := range stats {
|
for k, value := range stats {
|
||||||
v, err := strconv.ParseFloat(value, 64)
|
v, err := strconv.ParseFloat(value, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Invalid value %s in diskstats: %s", value, err)
|
return fmt.Errorf("invalid value %s in diskstats: %s", value, err)
|
||||||
}
|
}
|
||||||
counter, ok := diskStatsMetrics[k].(*prometheus.CounterVec)
|
|
||||||
if ok {
|
if counter, ok := c.metrics[k].(*prometheus.CounterVec); ok {
|
||||||
counter.WithLabelValues(dev).Set(v)
|
counter.WithLabelValues(dev).Set(v)
|
||||||
} else {
|
} else if gauge, ok := c.metrics[k].(*prometheus.GaugeVec); ok {
|
||||||
var gauge = diskStatsMetrics[k].(*prometheus.GaugeVec)
|
|
||||||
gauge.WithLabelValues(dev).Set(v)
|
gauge.WithLabelValues(dev).Set(v)
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("unexpected collector %d", k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, c := range diskStatsMetrics {
|
for _, c := range c.metrics {
|
||||||
c.Collect(ch)
|
c.Collect(ch)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
@ -197,8 +203,8 @@ func parseDiskStats(r io.Reader) (map[string]map[int]string, error) {
|
|||||||
|
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
parts := strings.Fields(string(scanner.Text()))
|
parts := strings.Fields(string(scanner.Text()))
|
||||||
if len(parts) != len(diskStatsMetrics)+3 { // we strip major, minor and dev
|
if len(parts) < 4 { // we strip major, minor and dev
|
||||||
return nil, fmt.Errorf("Invalid line in %s: %s", procDiskStats, scanner.Text())
|
return nil, fmt.Errorf("invalid line in %s: %s", procDiskStats, scanner.Text())
|
||||||
}
|
}
|
||||||
dev := parts[2]
|
dev := parts[2]
|
||||||
diskStats[dev] = map[int]string{}
|
diskStats[dev] = map[int]string{}
|
||||||
|
@ -21,60 +21,14 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
filesystemLabelNames = []string{"filesystem"}
|
|
||||||
|
|
||||||
fsSizeMetric = prometheus.NewGaugeVec(
|
|
||||||
prometheus.GaugeOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Subsystem: filesystemSubsystem,
|
|
||||||
Name: "size",
|
|
||||||
Help: "Filesystem size in bytes.",
|
|
||||||
},
|
|
||||||
filesystemLabelNames,
|
|
||||||
)
|
|
||||||
fsFreeMetric = prometheus.NewGaugeVec(
|
|
||||||
prometheus.GaugeOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Subsystem: filesystemSubsystem,
|
|
||||||
Name: "free",
|
|
||||||
Help: "Filesystem free space in bytes.",
|
|
||||||
},
|
|
||||||
filesystemLabelNames,
|
|
||||||
)
|
|
||||||
fsAvailMetric = prometheus.NewGaugeVec(
|
|
||||||
prometheus.GaugeOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Subsystem: filesystemSubsystem,
|
|
||||||
Name: "avail",
|
|
||||||
Help: "Filesystem space available to non-root users in bytes.",
|
|
||||||
},
|
|
||||||
filesystemLabelNames,
|
|
||||||
)
|
|
||||||
fsFilesMetric = prometheus.NewGaugeVec(
|
|
||||||
prometheus.GaugeOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Subsystem: filesystemSubsystem,
|
|
||||||
Name: "files",
|
|
||||||
Help: "Filesystem total file nodes.",
|
|
||||||
},
|
|
||||||
filesystemLabelNames,
|
|
||||||
)
|
|
||||||
fsFilesFreeMetric = prometheus.NewGaugeVec(
|
|
||||||
prometheus.GaugeOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Subsystem: filesystemSubsystem,
|
|
||||||
Name: "files_free",
|
|
||||||
Help: "Filesystem total free file nodes.",
|
|
||||||
},
|
|
||||||
filesystemLabelNames,
|
|
||||||
)
|
|
||||||
|
|
||||||
ignoredMountPoints = flag.String("filesystemIgnoredMountPoints", "^/(sys|proc|dev)($|/)", "Regexp of mount points to ignore for filesystem collector.")
|
ignoredMountPoints = flag.String("filesystemIgnoredMountPoints", "^/(sys|proc|dev)($|/)", "Regexp of mount points to ignore for filesystem collector.")
|
||||||
)
|
)
|
||||||
|
|
||||||
type filesystemCollector struct {
|
type filesystemCollector struct {
|
||||||
config Config
|
config Config
|
||||||
ignoredMountPointsPattern *regexp.Regexp
|
ignoredMountPointsPattern *regexp.Regexp
|
||||||
|
|
||||||
|
size, free, avail, files, filesFree *prometheus.GaugeVec
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -84,11 +38,57 @@ func init() {
|
|||||||
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
||||||
// network device filesystems.
|
// network device filesystems.
|
||||||
func NewFilesystemCollector(config Config) (Collector, error) {
|
func NewFilesystemCollector(config Config) (Collector, error) {
|
||||||
c := filesystemCollector{
|
var filesystemLabelNames = []string{"filesystem"}
|
||||||
|
|
||||||
|
return &filesystemCollector{
|
||||||
config: config,
|
config: config,
|
||||||
ignoredMountPointsPattern: regexp.MustCompile(*ignoredMountPoints),
|
ignoredMountPointsPattern: regexp.MustCompile(*ignoredMountPoints),
|
||||||
}
|
size: prometheus.NewGaugeVec(
|
||||||
return &c, nil
|
prometheus.GaugeOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Subsystem: filesystemSubsystem,
|
||||||
|
Name: "size",
|
||||||
|
Help: "Filesystem size in bytes.",
|
||||||
|
},
|
||||||
|
filesystemLabelNames,
|
||||||
|
),
|
||||||
|
free: prometheus.NewGaugeVec(
|
||||||
|
prometheus.GaugeOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Subsystem: filesystemSubsystem,
|
||||||
|
Name: "free",
|
||||||
|
Help: "Filesystem free space in bytes.",
|
||||||
|
},
|
||||||
|
filesystemLabelNames,
|
||||||
|
),
|
||||||
|
avail: prometheus.NewGaugeVec(
|
||||||
|
prometheus.GaugeOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Subsystem: filesystemSubsystem,
|
||||||
|
Name: "avail",
|
||||||
|
Help: "Filesystem space available to non-root users in bytes.",
|
||||||
|
},
|
||||||
|
filesystemLabelNames,
|
||||||
|
),
|
||||||
|
files: prometheus.NewGaugeVec(
|
||||||
|
prometheus.GaugeOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Subsystem: filesystemSubsystem,
|
||||||
|
Name: "files",
|
||||||
|
Help: "Filesystem total file nodes.",
|
||||||
|
},
|
||||||
|
filesystemLabelNames,
|
||||||
|
),
|
||||||
|
filesFree: prometheus.NewGaugeVec(
|
||||||
|
prometheus.GaugeOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Subsystem: filesystemSubsystem,
|
||||||
|
Name: "files_free",
|
||||||
|
Help: "Filesystem total free file nodes.",
|
||||||
|
},
|
||||||
|
filesystemLabelNames,
|
||||||
|
),
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expose filesystem fullness.
|
// Expose filesystem fullness.
|
||||||
@ -107,17 +107,17 @@ func (c *filesystemCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Statfs on %s returned %s", mp, err)
|
return fmt.Errorf("Statfs on %s returned %s", mp, err)
|
||||||
}
|
}
|
||||||
fsSizeMetric.WithLabelValues(mp).Set(float64(buf.Blocks) * float64(buf.Bsize))
|
c.size.WithLabelValues(mp).Set(float64(buf.Blocks) * float64(buf.Bsize))
|
||||||
fsFreeMetric.WithLabelValues(mp).Set(float64(buf.Bfree) * float64(buf.Bsize))
|
c.free.WithLabelValues(mp).Set(float64(buf.Bfree) * float64(buf.Bsize))
|
||||||
fsAvailMetric.WithLabelValues(mp).Set(float64(buf.Bavail) * float64(buf.Bsize))
|
c.avail.WithLabelValues(mp).Set(float64(buf.Bavail) * float64(buf.Bsize))
|
||||||
fsFilesMetric.WithLabelValues(mp).Set(float64(buf.Files))
|
c.files.WithLabelValues(mp).Set(float64(buf.Files))
|
||||||
fsFilesFreeMetric.WithLabelValues(mp).Set(float64(buf.Ffree))
|
c.filesFree.WithLabelValues(mp).Set(float64(buf.Ffree))
|
||||||
}
|
}
|
||||||
fsSizeMetric.Collect(ch)
|
c.size.Collect(ch)
|
||||||
fsFreeMetric.Collect(ch)
|
c.free.Collect(ch)
|
||||||
fsAvailMetric.Collect(ch)
|
c.avail.Collect(ch)
|
||||||
fsFilesMetric.Collect(ch)
|
c.files.Collect(ch)
|
||||||
fsFilesFreeMetric.Collect(ch)
|
c.filesFree.Collect(ch)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,19 +17,9 @@ const (
|
|||||||
procInterrupts = "/proc/interrupts"
|
procInterrupts = "/proc/interrupts"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
interruptsMetric = prometheus.NewCounterVec(
|
|
||||||
prometheus.CounterOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Name: "interrupts",
|
|
||||||
Help: "Interrupt details from /proc/interrupts.",
|
|
||||||
},
|
|
||||||
[]string{"CPU", "type", "info", "devices"},
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
type interruptsCollector struct {
|
type interruptsCollector struct {
|
||||||
config Config
|
config Config
|
||||||
|
metric *prometheus.CounterVec
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -39,10 +29,17 @@ func init() {
|
|||||||
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
||||||
// interrupts stats
|
// interrupts stats
|
||||||
func NewInterruptsCollector(config Config) (Collector, error) {
|
func NewInterruptsCollector(config Config) (Collector, error) {
|
||||||
c := interruptsCollector{
|
return &interruptsCollector{
|
||||||
config: config,
|
config: config,
|
||||||
}
|
metric: prometheus.NewCounterVec(
|
||||||
return &c, nil
|
prometheus.CounterOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Name: "interrupts",
|
||||||
|
Help: "Interrupt details from /proc/interrupts.",
|
||||||
|
},
|
||||||
|
[]string{"CPU", "type", "info", "devices"},
|
||||||
|
),
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *interruptsCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
func (c *interruptsCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
||||||
@ -62,10 +59,10 @@ func (c *interruptsCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
|||||||
"info": interrupt.info,
|
"info": interrupt.info,
|
||||||
"devices": interrupt.devices,
|
"devices": interrupt.devices,
|
||||||
}
|
}
|
||||||
interruptsMetric.With(labels).Set(fv)
|
c.metric.With(labels).Set(fv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
interruptsMetric.Collect(ch)
|
c.metric.Collect(ch)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,17 +16,9 @@ import (
|
|||||||
|
|
||||||
const lastLoginSubsystem = "last_login"
|
const lastLoginSubsystem = "last_login"
|
||||||
|
|
||||||
var (
|
|
||||||
lastSeen = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Subsystem: lastLoginSubsystem,
|
|
||||||
Name: "time",
|
|
||||||
Help: "The time of the last login.",
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
type lastLoginCollector struct {
|
type lastLoginCollector struct {
|
||||||
config Config
|
config Config
|
||||||
|
metric prometheus.Gauge
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -36,10 +28,15 @@ func init() {
|
|||||||
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
||||||
// load, seconds since last login and a list of tags as specified by config.
|
// load, seconds since last login and a list of tags as specified by config.
|
||||||
func NewLastLoginCollector(config Config) (Collector, error) {
|
func NewLastLoginCollector(config Config) (Collector, error) {
|
||||||
c := lastLoginCollector{
|
return &lastLoginCollector{
|
||||||
config: config,
|
config: config,
|
||||||
}
|
metric: prometheus.NewGauge(prometheus.GaugeOpts{
|
||||||
return &c, nil
|
Namespace: Namespace,
|
||||||
|
Subsystem: lastLoginSubsystem,
|
||||||
|
Name: "time",
|
||||||
|
Help: "The time of the last login.",
|
||||||
|
}),
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *lastLoginCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
func (c *lastLoginCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
||||||
@ -48,8 +45,8 @@ func (c *lastLoginCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
|||||||
return fmt.Errorf("Couldn't get last seen: %s", err)
|
return fmt.Errorf("Couldn't get last seen: %s", err)
|
||||||
}
|
}
|
||||||
glog.V(1).Infof("Set node_last_login_time: %f", last)
|
glog.V(1).Infof("Set node_last_login_time: %f", last)
|
||||||
lastSeen.Set(last)
|
c.metric.Set(last)
|
||||||
lastSeen.Collect(ch)
|
c.metric.Collect(ch)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,16 +16,9 @@ const (
|
|||||||
procLoad = "/proc/loadavg"
|
procLoad = "/proc/loadavg"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
load1 = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Name: "load1",
|
|
||||||
Help: "1m load average.",
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
type loadavgCollector struct {
|
type loadavgCollector struct {
|
||||||
config Config
|
config Config
|
||||||
|
metric prometheus.Gauge
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -35,10 +28,14 @@ func init() {
|
|||||||
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
||||||
// load, seconds since last login and a list of tags as specified by config.
|
// load, seconds since last login and a list of tags as specified by config.
|
||||||
func NewLoadavgCollector(config Config) (Collector, error) {
|
func NewLoadavgCollector(config Config) (Collector, error) {
|
||||||
c := loadavgCollector{
|
return &loadavgCollector{
|
||||||
config: config,
|
config: config,
|
||||||
}
|
metric: prometheus.NewGauge(prometheus.GaugeOpts{
|
||||||
return &c, nil
|
Namespace: Namespace,
|
||||||
|
Name: "load1",
|
||||||
|
Help: "1m load average.",
|
||||||
|
}),
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *loadavgCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
func (c *loadavgCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
||||||
@ -47,8 +44,8 @@ func (c *loadavgCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
|||||||
return fmt.Errorf("Couldn't get load: %s", err)
|
return fmt.Errorf("Couldn't get load: %s", err)
|
||||||
}
|
}
|
||||||
glog.V(1).Infof("Set node_load: %f", load)
|
glog.V(1).Infof("Set node_load: %f", load)
|
||||||
load1.Set(load)
|
c.metric.Set(load)
|
||||||
load1.Collect(ch)
|
c.metric.Collect(ch)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,32 +17,60 @@ const (
|
|||||||
adapterHeaderSep = "================"
|
adapterHeaderSep = "================"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
type megaCliCollector struct {
|
||||||
driveTemperature = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
config Config
|
||||||
Namespace: Namespace,
|
cli string
|
||||||
Name: "megacli_drive_temperature_celsius",
|
|
||||||
Help: "megacli: drive temperature",
|
|
||||||
}, []string{"enclosure", "slot"})
|
|
||||||
|
|
||||||
driveCounters = prometheus.NewCounterVec(prometheus.CounterOpts{
|
driveTemperature *prometheus.GaugeVec
|
||||||
Namespace: Namespace,
|
driveCounters *prometheus.CounterVec
|
||||||
Name: "megacli_drive_count",
|
drivePresence *prometheus.GaugeVec
|
||||||
Help: "megacli: drive error and event counters",
|
}
|
||||||
}, []string{"enclosure", "slot", "type"})
|
|
||||||
|
|
||||||
drivePresence = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Name: "megacli_adapter_disk_presence",
|
|
||||||
Help: "megacli: disk presence per adapter",
|
|
||||||
}, []string{"type"})
|
|
||||||
|
|
||||||
counters = []string{"Media Error Count", "Other Error Count", "Predictive Failure Count"}
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
Factories["megacli"] = NewMegaCliCollector
|
Factories["megacli"] = NewMegaCliCollector
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
||||||
|
// RAID status through megacli.
|
||||||
|
func NewMegaCliCollector(config Config) (Collector, error) {
|
||||||
|
cli := defaultMegaCli
|
||||||
|
if config.Config["megacli_command"] != "" {
|
||||||
|
cli = config.Config["megacli_command"]
|
||||||
|
}
|
||||||
|
|
||||||
|
return &megaCliCollector{
|
||||||
|
config: config,
|
||||||
|
cli: cli,
|
||||||
|
driveTemperature: prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Name: "megacli_drive_temperature_celsius",
|
||||||
|
Help: "megacli: drive temperature",
|
||||||
|
}, []string{"enclosure", "slot"}),
|
||||||
|
driveCounters: prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Name: "megacli_drive_count",
|
||||||
|
Help: "megacli: drive error and event counters",
|
||||||
|
}, []string{"enclosure", "slot", "type"}),
|
||||||
|
drivePresence: prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Name: "megacli_adapter_disk_presence",
|
||||||
|
Help: "megacli: disk presence per adapter",
|
||||||
|
}, []string{"type"}),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *megaCliCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
||||||
|
err = c.updateAdapter()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = c.updateDisks()
|
||||||
|
c.driveTemperature.Collect(ch)
|
||||||
|
c.driveCounters.Collect(ch)
|
||||||
|
c.drivePresence.Collect(ch)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func parseMegaCliDisks(r io.Reader) (map[int]map[int]map[string]string, error) {
|
func parseMegaCliDisks(r io.Reader) (map[int]map[int]map[string]string, error) {
|
||||||
var (
|
var (
|
||||||
stats = map[int]map[int]map[string]string{}
|
stats = map[int]map[int]map[string]string{}
|
||||||
@ -118,38 +146,6 @@ func parseMegaCliAdapter(r io.Reader) (map[string]map[string]string, error) {
|
|||||||
return raidStats, nil
|
return raidStats, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type megaCliCollector struct {
|
|
||||||
config Config
|
|
||||||
cli string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
|
||||||
// RAID status through megacli.
|
|
||||||
func NewMegaCliCollector(config Config) (Collector, error) {
|
|
||||||
cli := defaultMegaCli
|
|
||||||
if config.Config["megacli_command"] != "" {
|
|
||||||
cli = config.Config["megacli_command"]
|
|
||||||
}
|
|
||||||
|
|
||||||
c := megaCliCollector{
|
|
||||||
config: config,
|
|
||||||
cli: cli,
|
|
||||||
}
|
|
||||||
return &c, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *megaCliCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
|
||||||
err = c.updateAdapter()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = c.updateDisks()
|
|
||||||
driveTemperature.Collect(ch)
|
|
||||||
driveCounters.Collect(ch)
|
|
||||||
drivePresence.Collect(ch)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *megaCliCollector) updateAdapter() error {
|
func (c *megaCliCollector) updateAdapter() error {
|
||||||
cmd := exec.Command(c.cli, "-AdpAllInfo", "-aALL")
|
cmd := exec.Command(c.cli, "-AdpAllInfo", "-aALL")
|
||||||
pipe, err := cmd.StdoutPipe()
|
pipe, err := cmd.StdoutPipe()
|
||||||
@ -174,12 +170,14 @@ func (c *megaCliCollector) updateAdapter() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
drivePresence.WithLabelValues(k).Set(value)
|
c.drivePresence.WithLabelValues(k).Set(value)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *megaCliCollector) updateDisks() error {
|
func (c *megaCliCollector) updateDisks() error {
|
||||||
|
var counters = []string{"Media Error Count", "Other Error Count", "Predictive Failure Count"}
|
||||||
|
|
||||||
cmd := exec.Command(c.cli, "-PDList", "-aALL")
|
cmd := exec.Command(c.cli, "-PDList", "-aALL")
|
||||||
pipe, err := cmd.StdoutPipe()
|
pipe, err := cmd.StdoutPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -210,15 +208,15 @@ func (c *megaCliCollector) updateDisks() error {
|
|||||||
encStr := strconv.Itoa(enc)
|
encStr := strconv.Itoa(enc)
|
||||||
slotStr := strconv.Itoa(slot)
|
slotStr := strconv.Itoa(slot)
|
||||||
|
|
||||||
driveTemperature.WithLabelValues(encStr, slotStr).Set(t)
|
c.driveTemperature.WithLabelValues(encStr, slotStr).Set(t)
|
||||||
|
|
||||||
for _, c := range counters {
|
for _, i := range counters {
|
||||||
counter, err := strconv.ParseFloat(slotStats[c], 64)
|
counter, err := strconv.ParseFloat(slotStats[i], 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
driveCounters.WithLabelValues(encStr, slotStr, c).Set(counter)
|
c.driveCounters.WithLabelValues(encStr, slotStr, i).Set(counter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,9 @@ const (
|
|||||||
memInfoSubsystem = "memory"
|
memInfoSubsystem = "memory"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
memInfoMetrics = map[string]prometheus.Gauge{}
|
|
||||||
)
|
|
||||||
|
|
||||||
type meminfoCollector struct {
|
type meminfoCollector struct {
|
||||||
config Config
|
config Config
|
||||||
|
metrics map[string]prometheus.Gauge
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -35,10 +32,10 @@ func init() {
|
|||||||
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
||||||
// memory stats.
|
// memory stats.
|
||||||
func NewMeminfoCollector(config Config) (Collector, error) {
|
func NewMeminfoCollector(config Config) (Collector, error) {
|
||||||
c := meminfoCollector{
|
return &meminfoCollector{
|
||||||
config: config,
|
config: config,
|
||||||
}
|
metrics: map[string]prometheus.Gauge{},
|
||||||
return &c, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
||||||
@ -48,16 +45,16 @@ func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
|||||||
}
|
}
|
||||||
glog.V(1).Infof("Set node_mem: %#v", memInfo)
|
glog.V(1).Infof("Set node_mem: %#v", memInfo)
|
||||||
for k, v := range memInfo {
|
for k, v := range memInfo {
|
||||||
if _, ok := memInfoMetrics[k]; !ok {
|
if _, ok := c.metrics[k]; !ok {
|
||||||
memInfoMetrics[k] = prometheus.NewGauge(prometheus.GaugeOpts{
|
c.metrics[k] = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||||
Namespace: Namespace,
|
Namespace: Namespace,
|
||||||
Subsystem: memInfoSubsystem,
|
Subsystem: memInfoSubsystem,
|
||||||
Name: k,
|
Name: k,
|
||||||
Help: k + " from /proc/meminfo.",
|
Help: k + " from /proc/meminfo.",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
memInfoMetrics[k].Set(v)
|
c.metrics[k].Set(v)
|
||||||
memInfoMetrics[k].Collect(ch)
|
c.metrics[k].Collect(ch)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -18,12 +18,9 @@ const (
|
|||||||
netDevSubsystem = "network"
|
netDevSubsystem = "network"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
netDevMetrics = map[string]*prometheus.GaugeVec{}
|
|
||||||
)
|
|
||||||
|
|
||||||
type netDevCollector struct {
|
type netDevCollector struct {
|
||||||
config Config
|
config Config
|
||||||
|
metrics map[string]*prometheus.GaugeVec
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -33,10 +30,10 @@ func init() {
|
|||||||
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
||||||
// network device stats.
|
// network device stats.
|
||||||
func NewNetDevCollector(config Config) (Collector, error) {
|
func NewNetDevCollector(config Config) (Collector, error) {
|
||||||
c := netDevCollector{
|
return &netDevCollector{
|
||||||
config: config,
|
config: config,
|
||||||
}
|
metrics: map[string]*prometheus.GaugeVec{},
|
||||||
return &c, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *netDevCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
func (c *netDevCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
||||||
@ -48,8 +45,8 @@ func (c *netDevCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
|||||||
for dev, stats := range devStats {
|
for dev, stats := range devStats {
|
||||||
for t, value := range stats {
|
for t, value := range stats {
|
||||||
key := direction + "_" + t
|
key := direction + "_" + t
|
||||||
if _, ok := netDevMetrics[key]; !ok {
|
if _, ok := c.metrics[key]; !ok {
|
||||||
netDevMetrics[key] = prometheus.NewGaugeVec(
|
c.metrics[key] = prometheus.NewGaugeVec(
|
||||||
prometheus.GaugeOpts{
|
prometheus.GaugeOpts{
|
||||||
Namespace: Namespace,
|
Namespace: Namespace,
|
||||||
Subsystem: netDevSubsystem,
|
Subsystem: netDevSubsystem,
|
||||||
@ -63,11 +60,11 @@ func (c *netDevCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Invalid value %s in netstats: %s", value, err)
|
return fmt.Errorf("Invalid value %s in netstats: %s", value, err)
|
||||||
}
|
}
|
||||||
netDevMetrics[key].WithLabelValues(dev).Set(v)
|
c.metrics[key].WithLabelValues(dev).Set(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, m := range netDevMetrics {
|
for _, m := range c.metrics {
|
||||||
m.Collect(ch)
|
m.Collect(ch)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
|
@ -18,12 +18,9 @@ const (
|
|||||||
netStatsSubsystem = "netstat"
|
netStatsSubsystem = "netstat"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
netStatsMetrics = map[string]prometheus.Gauge{}
|
|
||||||
)
|
|
||||||
|
|
||||||
type netStatCollector struct {
|
type netStatCollector struct {
|
||||||
config Config
|
config Config
|
||||||
|
metrics map[string]prometheus.Gauge
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -33,10 +30,10 @@ func init() {
|
|||||||
// NewNetStatCollector takes a config struct and returns
|
// NewNetStatCollector takes a config struct and returns
|
||||||
// a new Collector exposing network stats.
|
// a new Collector exposing network stats.
|
||||||
func NewNetStatCollector(config Config) (Collector, error) {
|
func NewNetStatCollector(config Config) (Collector, error) {
|
||||||
c := netStatCollector{
|
return &netStatCollector{
|
||||||
config: config,
|
config: config,
|
||||||
}
|
metrics: map[string]prometheus.Gauge{},
|
||||||
return &c, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *netStatCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
func (c *netStatCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
||||||
@ -47,8 +44,8 @@ func (c *netStatCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
|||||||
for protocol, protocolStats := range netStats {
|
for protocol, protocolStats := range netStats {
|
||||||
for name, value := range protocolStats {
|
for name, value := range protocolStats {
|
||||||
key := protocol + "_" + name
|
key := protocol + "_" + name
|
||||||
if _, ok := netStatsMetrics[key]; !ok {
|
if _, ok := c.metrics[key]; !ok {
|
||||||
netStatsMetrics[key] = prometheus.NewGauge(
|
c.metrics[key] = prometheus.NewGauge(
|
||||||
prometheus.GaugeOpts{
|
prometheus.GaugeOpts{
|
||||||
Namespace: Namespace,
|
Namespace: Namespace,
|
||||||
Subsystem: netStatsSubsystem,
|
Subsystem: netStatsSubsystem,
|
||||||
@ -61,10 +58,10 @@ func (c *netStatCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid value %s in netstats: %s", value, err)
|
return fmt.Errorf("invalid value %s in netstats: %s", value, err)
|
||||||
}
|
}
|
||||||
netStatsMetrics[key].Set(v)
|
c.metrics[key].Set(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, m := range netStatsMetrics {
|
for _, m := range c.metrics {
|
||||||
m.Collect(ch)
|
m.Collect(ch)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
|
@ -14,14 +14,10 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
ntpServer = flag.String("ntpServer", "", "NTP server to use for ntp collector.")
|
ntpServer = flag.String("ntpServer", "", "NTP server to use for ntp collector.")
|
||||||
ntpDrift = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Name: "ntp_drift_seconds",
|
|
||||||
Help: "Time between system time and ntp time.",
|
|
||||||
})
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ntpCollector struct {
|
type ntpCollector struct {
|
||||||
|
drift prometheus.Gauge
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -34,9 +30,14 @@ func NewNtpCollector(config Config) (Collector, error) {
|
|||||||
if *ntpServer == "" {
|
if *ntpServer == "" {
|
||||||
return nil, fmt.Errorf("No NTP server specifies, see --ntpServer")
|
return nil, fmt.Errorf("No NTP server specifies, see --ntpServer")
|
||||||
}
|
}
|
||||||
c := ntpCollector{}
|
|
||||||
|
|
||||||
return &c, nil
|
return &ntpCollector{
|
||||||
|
drift: prometheus.NewGauge(prometheus.GaugeOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Name: "ntp_drift_seconds",
|
||||||
|
Help: "Time between system time and ntp time.",
|
||||||
|
}),
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ntpCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
func (c *ntpCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
||||||
@ -46,7 +47,7 @@ func (c *ntpCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
|||||||
}
|
}
|
||||||
drift := t.Sub(time.Now())
|
drift := t.Sub(time.Now())
|
||||||
glog.V(1).Infof("Set ntp_drift_seconds: %f", drift.Seconds())
|
glog.V(1).Infof("Set ntp_drift_seconds: %f", drift.Seconds())
|
||||||
ntpDrift.Set(drift.Seconds())
|
c.drift.Set(drift.Seconds())
|
||||||
ntpDrift.Collect(ch)
|
c.drift.Collect(ch)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -8,37 +8,14 @@ import (
|
|||||||
"github.com/soundcloud/go-runit/runit"
|
"github.com/soundcloud/go-runit/runit"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
const (
|
||||||
runitLabelNames = []string{"service"}
|
runitSubsystem = "runit"
|
||||||
|
|
||||||
runitState = prometheus.NewGaugeVec(
|
|
||||||
prometheus.GaugeOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Name: "service_state",
|
|
||||||
Help: "node_exporter: state of runit service.",
|
|
||||||
},
|
|
||||||
runitLabelNames,
|
|
||||||
)
|
|
||||||
runitStateDesired = prometheus.NewGaugeVec(
|
|
||||||
prometheus.GaugeOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Name: "service_desired_state",
|
|
||||||
Help: "node_exporter: desired state of runit service.",
|
|
||||||
},
|
|
||||||
runitLabelNames,
|
|
||||||
)
|
|
||||||
runitStateNormal = prometheus.NewGaugeVec(
|
|
||||||
prometheus.GaugeOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Name: "service_normal_state",
|
|
||||||
Help: "node_exporter: normal state of runit service.",
|
|
||||||
},
|
|
||||||
runitLabelNames,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type runitCollector struct {
|
type runitCollector struct {
|
||||||
config Config
|
config Config
|
||||||
|
|
||||||
|
state, stateDesired, stateNormal *prometheus.GaugeVec
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -46,14 +23,41 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewRunitCollector(config Config) (Collector, error) {
|
func NewRunitCollector(config Config) (Collector, error) {
|
||||||
c := runitCollector{
|
var labels = []string{"service"}
|
||||||
config: config,
|
|
||||||
}
|
|
||||||
|
|
||||||
return &c, nil
|
return &runitCollector{
|
||||||
|
config: config,
|
||||||
|
state: prometheus.NewGaugeVec(
|
||||||
|
prometheus.GaugeOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Subsystem: runitSubsystem,
|
||||||
|
Name: "state",
|
||||||
|
Help: "state of runit service.",
|
||||||
|
},
|
||||||
|
labels,
|
||||||
|
),
|
||||||
|
stateDesired: prometheus.NewGaugeVec(
|
||||||
|
prometheus.GaugeOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Subsystem: runitSubsystem,
|
||||||
|
Name: "desired_state",
|
||||||
|
Help: "desired state of runit service.",
|
||||||
|
},
|
||||||
|
labels,
|
||||||
|
),
|
||||||
|
stateNormal: prometheus.NewGaugeVec(
|
||||||
|
prometheus.GaugeOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Subsystem: runitSubsystem,
|
||||||
|
Name: "normal_state",
|
||||||
|
Help: "normal state of runit service.",
|
||||||
|
},
|
||||||
|
labels,
|
||||||
|
),
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *runitCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
func (c *runitCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
services, err := runit.GetServices("/etc/service")
|
services, err := runit.GetServices("/etc/service")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -67,16 +71,17 @@ func (c *runitCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
glog.V(1).Infof("%s is %d on pid %d for %d seconds", service.Name, status.State, status.Pid, status.Duration)
|
glog.V(1).Infof("%s is %d on pid %d for %d seconds", service.Name, status.State, status.Pid, status.Duration)
|
||||||
runitState.WithLabelValues(service.Name).Set(float64(status.State))
|
c.state.WithLabelValues(service.Name).Set(float64(status.State))
|
||||||
runitStateDesired.WithLabelValues(service.Name).Set(float64(status.Want))
|
c.stateDesired.WithLabelValues(service.Name).Set(float64(status.Want))
|
||||||
if status.NormallyUp {
|
if status.NormallyUp {
|
||||||
runitStateNormal.WithLabelValues(service.Name).Set(1)
|
c.stateNormal.WithLabelValues(service.Name).Set(1)
|
||||||
} else {
|
} else {
|
||||||
runitStateNormal.WithLabelValues(service.Name).Set(1)
|
c.stateNormal.WithLabelValues(service.Name).Set(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
runitState.Collect(ch)
|
c.state.Collect(ch)
|
||||||
runitStateDesired.Collect(ch)
|
c.stateDesired.Collect(ch)
|
||||||
runitStateNormal.Collect(ch)
|
c.stateNormal.Collect(ch)
|
||||||
return err
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -18,49 +18,15 @@ const (
|
|||||||
procStat = "/proc/stat"
|
procStat = "/proc/stat"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
cpuMetrics = prometheus.NewCounterVec(
|
|
||||||
prometheus.CounterOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Name: "cpu",
|
|
||||||
Help: "Seconds the cpus spent in each mode.",
|
|
||||||
},
|
|
||||||
[]string{"cpu", "mode"},
|
|
||||||
)
|
|
||||||
intrMetric = prometheus.NewCounter(prometheus.CounterOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Name: "intr",
|
|
||||||
Help: "Total number of interrupts serviced.",
|
|
||||||
})
|
|
||||||
ctxtMetric = prometheus.NewCounter(prometheus.CounterOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Name: "context_switches",
|
|
||||||
Help: "Total number of context switches.",
|
|
||||||
})
|
|
||||||
forksMetric = prometheus.NewCounter(prometheus.CounterOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Name: "forks",
|
|
||||||
Help: "Total number of forks.",
|
|
||||||
})
|
|
||||||
btimeMetric = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Name: "boot_time",
|
|
||||||
Help: "Node boot time, in unixtime.",
|
|
||||||
})
|
|
||||||
procsRunningMetric = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Name: "procs_running",
|
|
||||||
Help: "Number of processes in runnable state.",
|
|
||||||
})
|
|
||||||
procsBlockedMetric = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Name: "procs_blocked",
|
|
||||||
Help: "Number of processes blocked waiting for I/O to complete.",
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
type statCollector struct {
|
type statCollector struct {
|
||||||
config Config
|
config Config
|
||||||
|
cpu *prometheus.CounterVec
|
||||||
|
intr prometheus.Counter
|
||||||
|
ctxt prometheus.Counter
|
||||||
|
forks prometheus.Counter
|
||||||
|
btime prometheus.Gauge
|
||||||
|
procsRunning prometheus.Gauge
|
||||||
|
procsBlocked prometheus.Gauge
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -70,10 +36,47 @@ func init() {
|
|||||||
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
||||||
// network device stats.
|
// network device stats.
|
||||||
func NewStatCollector(config Config) (Collector, error) {
|
func NewStatCollector(config Config) (Collector, error) {
|
||||||
c := statCollector{
|
return &statCollector{
|
||||||
config: config,
|
config: config,
|
||||||
}
|
cpu: prometheus.NewCounterVec(
|
||||||
return &c, nil
|
prometheus.CounterOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Name: "cpu",
|
||||||
|
Help: "Seconds the cpus spent in each mode.",
|
||||||
|
},
|
||||||
|
[]string{"cpu", "mode"},
|
||||||
|
),
|
||||||
|
intr: prometheus.NewCounter(prometheus.CounterOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Name: "intr",
|
||||||
|
Help: "Total number of interrupts serviced.",
|
||||||
|
}),
|
||||||
|
ctxt: prometheus.NewCounter(prometheus.CounterOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Name: "context_switches",
|
||||||
|
Help: "Total number of context switches.",
|
||||||
|
}),
|
||||||
|
forks: prometheus.NewCounter(prometheus.CounterOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Name: "forks",
|
||||||
|
Help: "Total number of forks.",
|
||||||
|
}),
|
||||||
|
btime: prometheus.NewGauge(prometheus.GaugeOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Name: "boot_time",
|
||||||
|
Help: "Node boot time, in unixtime.",
|
||||||
|
}),
|
||||||
|
procsRunning: prometheus.NewGauge(prometheus.GaugeOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Name: "procs_running",
|
||||||
|
Help: "Number of processes in runnable state.",
|
||||||
|
}),
|
||||||
|
procsBlocked: prometheus.NewGauge(prometheus.GaugeOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Name: "procs_blocked",
|
||||||
|
Help: "Number of processes blocked waiting for I/O to complete.",
|
||||||
|
}),
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expose a variety of stats from /proc/stats.
|
// Expose a variety of stats from /proc/stats.
|
||||||
@ -102,7 +105,7 @@ func (c *statCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
|||||||
}
|
}
|
||||||
// Convert from ticks to seconds
|
// Convert from ticks to seconds
|
||||||
value /= float64(C.sysconf(C._SC_CLK_TCK))
|
value /= float64(C.sysconf(C._SC_CLK_TCK))
|
||||||
cpuMetrics.With(prometheus.Labels{"cpu": parts[0], "mode": cpuFields[i]}).Set(value)
|
c.cpu.With(prometheus.Labels{"cpu": parts[0], "mode": cpuFields[i]}).Set(value)
|
||||||
}
|
}
|
||||||
case parts[0] == "intr":
|
case parts[0] == "intr":
|
||||||
// Only expose the overall number, use the 'interrupts' collector for more detail.
|
// Only expose the overall number, use the 'interrupts' collector for more detail.
|
||||||
@ -110,45 +113,45 @@ func (c *statCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
intrMetric.Set(value)
|
c.intr.Set(value)
|
||||||
case parts[0] == "ctxt":
|
case parts[0] == "ctxt":
|
||||||
value, err := strconv.ParseFloat(parts[1], 64)
|
value, err := strconv.ParseFloat(parts[1], 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ctxtMetric.Set(value)
|
c.ctxt.Set(value)
|
||||||
case parts[0] == "processes":
|
case parts[0] == "processes":
|
||||||
value, err := strconv.ParseFloat(parts[1], 64)
|
value, err := strconv.ParseFloat(parts[1], 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
forksMetric.Set(value)
|
c.forks.Set(value)
|
||||||
case parts[0] == "btime":
|
case parts[0] == "btime":
|
||||||
value, err := strconv.ParseFloat(parts[1], 64)
|
value, err := strconv.ParseFloat(parts[1], 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
btimeMetric.Set(value)
|
c.btime.Set(value)
|
||||||
case parts[0] == "procs_running":
|
case parts[0] == "procs_running":
|
||||||
value, err := strconv.ParseFloat(parts[1], 64)
|
value, err := strconv.ParseFloat(parts[1], 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
procsRunningMetric.Set(value)
|
c.procsRunning.Set(value)
|
||||||
case parts[0] == "procs_blocked":
|
case parts[0] == "procs_blocked":
|
||||||
value, err := strconv.ParseFloat(parts[1], 64)
|
value, err := strconv.ParseFloat(parts[1], 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
procsBlockedMetric.Set(value)
|
c.procsBlocked.Set(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cpuMetrics.Collect(ch)
|
c.cpu.Collect(ch)
|
||||||
ctxtMetric.Collect(ch)
|
c.ctxt.Collect(ch)
|
||||||
intrMetric.Collect(ch)
|
c.intr.Collect(ch)
|
||||||
forksMetric.Collect(ch)
|
c.forks.Collect(ch)
|
||||||
btimeMetric.Collect(ch)
|
c.btime.Collect(ch)
|
||||||
procsRunningMetric.Collect(ch)
|
c.procsRunning.Collect(ch)
|
||||||
procsBlockedMetric.Collect(ch)
|
c.procsBlocked.Collect(ch)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -9,16 +9,9 @@ import (
|
|||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
systemTime = prometheus.NewCounter(prometheus.CounterOpts{
|
|
||||||
Namespace: Namespace,
|
|
||||||
Name: "time",
|
|
||||||
Help: "System time in seconds since epoch (1970).",
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
type timeCollector struct {
|
type timeCollector struct {
|
||||||
config Config
|
config Config
|
||||||
|
metric prometheus.Counter
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -28,17 +21,20 @@ func init() {
|
|||||||
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
||||||
// the current system time in seconds since epoch.
|
// the current system time in seconds since epoch.
|
||||||
func NewTimeCollector(config Config) (Collector, error) {
|
func NewTimeCollector(config Config) (Collector, error) {
|
||||||
c := timeCollector{
|
return &timeCollector{
|
||||||
config: config,
|
config: config,
|
||||||
}
|
metric: prometheus.NewCounter(prometheus.CounterOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
return &c, nil
|
Name: "time",
|
||||||
|
Help: "System time in seconds since epoch (1970).",
|
||||||
|
}),
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *timeCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
func (c *timeCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
glog.V(1).Infof("Set time: %f", now.Unix())
|
glog.V(1).Infof("Set time: %f", now.Unix())
|
||||||
systemTime.Set(float64(now.Unix()))
|
c.metric.Set(float64(now.Unix()))
|
||||||
systemTime.Collect(ch)
|
c.metric.Collect(ch)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user