1 // Exports runtime variables using prometheus.
14 "github.com/prometheus/client_golang/prometheus"
18 availFS
= flag
.String("varz_avail_fs",
20 "If non-empty, /varz will contain the number of available bytes on the specified filesystem")
28 memAllocBytesGauge
= prometheus
.NewGaugeFunc(
31 Name
: "mem_alloc_bytes",
32 Help
: "Bytes allocated and still in use.",
35 var m runtime
.MemStats
36 runtime
.ReadMemStats(&m
)
37 return float64(m
.Alloc
)
41 availFSGauge
= prometheus
.NewGaugeFunc(
43 Name
: "avail_fs_bytes",
44 Help
: "Number of available bytes on -varz_avail_fs.",
48 var stat syscall
.Statfs_t
49 if err
:= syscall
.Statfs(*availFS
, &stat
); err
!= nil {
50 log
.Printf("Could not stat filesystem for %q: %v\n", *availFS
, err
)
52 return float64(stat
.Bavail
* uint64(stat
.Bsize
))
60 type cpuTimeMetric
struct {
64 func (ct
*cpuTimeMetric
) Describe(ch
chan<- *prometheus
.Desc
) {
68 func (ct cpuTimeMetric
) Collect(ch
chan<- prometheus
.Metric
) {
69 var rusage syscall
.Rusage
70 if err
:= syscall
.Getrusage(syscall
.RUSAGE_SELF
, &rusage
); err
== nil {
71 ch
<- prometheus
.MustNewConstMetric(ct
.desc
, prometheus
.CounterValue
, float64(syscall
.TimevalToNsec(rusage
.Utime
)), "user")
73 ch
<- prometheus
.MustNewConstMetric(ct
.desc
, prometheus
.CounterValue
, float64(syscall
.TimevalToNsec(rusage
.Stime
)), "system")
77 type diskStatsMetric
struct {
78 reads
*prometheus
.Desc
79 writes
*prometheus
.Desc
80 readbytes
*prometheus
.Desc
81 writtenbytes
*prometheus
.Desc
84 func (ct
*diskStatsMetric
) Describe(ch
chan<- *prometheus
.Desc
) {
91 func (ct diskStatsMetric
) Collect(ch
chan<- prometheus
.Metric
) {
92 diskstats
, err
:= os
.Open("/proc/diskstats")
96 defer diskstats
.Close()
98 scanner
:= bufio
.NewScanner(diskstats
)
100 // From http://sources.debian.net/src/linux/3.16.7-2/block/genhd.c/?hl=1141#L1141
101 // seq_printf(seqf, "%4d %7d %s %lu %lu %lu %u %lu %lu %lu %u %u %u %u\n",
102 var major
, minor
uint64
104 var reads
, mergedreads
, readsectors
, readms
uint64
105 var writes
, mergedwrites
, writtensectors
, writems
uint64
106 var inflight
, ioticks
, timeinqueue
uint64
107 fmt
.Sscanf(scanner
.Text(), "%4d %7d %s %d %d %d %d %d %d %d %d %d %d %d",
108 &major
, &minor
, &device
,
109 &reads
, &mergedreads
, &readsectors
, &readms
,
110 &writes
, &mergedwrites
, &writtensectors
, &writems
,
111 &inflight
, &ioticks
, &timeinqueue
)
112 // Matches sda, xvda, nvme0n1, …
113 if !strings
.HasSuffix(device
, "da") &&
114 !strings
.HasSuffix(device
, "n1") {
117 ch
<- prometheus
.MustNewConstMetric(ct
.reads
, prometheus
.CounterValue
, float64(reads
), device
)
118 ch
<- prometheus
.MustNewConstMetric(ct
.writes
, prometheus
.CounterValue
, float64(writes
), device
)
119 ch
<- prometheus
.MustNewConstMetric(ct
.readbytes
, prometheus
.CounterValue
, float64(readsectors
*bytesPerSector
), device
)
120 ch
<- prometheus
.MustNewConstMetric(ct
.writtenbytes
, prometheus
.CounterValue
, float64(writtensectors
*bytesPerSector
), device
)
125 prometheus
.MustRegister(memAllocBytesGauge
)
126 prometheus
.MustRegister(availFSGauge
)
128 prometheus
.MustRegister(&cpuTimeMetric
{
129 desc
: prometheus
.NewDesc("process_cpu_nsec",
130 "CPU time spent in ns, split by user/system.",
135 prometheus
.MustRegister(&diskStatsMetric
{
136 reads
: prometheus
.NewDesc("system_disk_reads",
137 "Disk reads, per device name (e.g. xvda).",
141 writes
: prometheus
.NewDesc("system_disk_writes",
142 "Disk writes, per device name (e.g. xvda).",
146 readbytes
: prometheus
.NewDesc("disk_read_bytes",
147 "Bytes read from disk, per device name (e.g. xvda).",
151 writtenbytes
: prometheus
.NewDesc("disk_written_bytes",
152 "Bytes written to disk, per device name (e.g. xvda).",
158 // vim:ts=4:sw=4:noexpandtab