show: make highlight legible
[debiancodesearch.git] / varz / varz.go
blobc85802dfceeb3f5698f4ada2cb478071d1ea330b
1 // Exports runtime variables using prometheus.
2 package varz
4 import (
5 "bufio"
6 "flag"
7 "fmt"
8 "log"
9 "os"
10 "runtime"
11 "strings"
12 "syscall"
14 "github.com/prometheus/client_golang/prometheus"
17 var (
18 availFS = flag.String("varz_avail_fs",
19 "/srv/dcs",
20 "If non-empty, /varz will contain the number of available bytes on the specified filesystem")
23 const (
24 bytesPerSector = 512
27 var (
28 memAllocBytesGauge = prometheus.NewGaugeFunc(
29 prometheus.GaugeOpts{
30 Subsystem: "process",
31 Name: "mem_alloc_bytes",
32 Help: "Bytes allocated and still in use.",
34 func() float64 {
35 var m runtime.MemStats
36 runtime.ReadMemStats(&m)
37 return float64(m.Alloc)
41 availFSGauge = prometheus.NewGaugeFunc(
42 prometheus.GaugeOpts{
43 Name: "avail_fs_bytes",
44 Help: "Number of available bytes on -varz_avail_fs.",
46 func() float64 {
47 if *availFS != "" {
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)
51 } else {
52 return float64(stat.Bavail * uint64(stat.Bsize))
55 return 0
60 type cpuTimeMetric struct {
61 desc *prometheus.Desc
64 func (ct *cpuTimeMetric) Describe(ch chan<- *prometheus.Desc) {
65 ch <- ct.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) {
85 ch <- ct.reads
86 ch <- ct.writes
87 ch <- ct.readbytes
88 ch <- ct.writtenbytes
91 func (ct diskStatsMetric) Collect(ch chan<- prometheus.Metric) {
92 diskstats, err := os.Open("/proc/diskstats")
93 if err != nil {
94 return
96 defer diskstats.Close()
98 scanner := bufio.NewScanner(diskstats)
99 for scanner.Scan() {
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
103 var device string
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") {
115 continue
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)
124 func init() {
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.",
131 []string{"mode"},
132 nil),
135 prometheus.MustRegister(&diskStatsMetric{
136 reads: prometheus.NewDesc("system_disk_reads",
137 "Disk reads, per device name (e.g. xvda).",
138 []string{"device"},
139 nil),
141 writes: prometheus.NewDesc("system_disk_writes",
142 "Disk writes, per device name (e.g. xvda).",
143 []string{"device"},
144 nil),
146 readbytes: prometheus.NewDesc("disk_read_bytes",
147 "Bytes read from disk, per device name (e.g. xvda).",
148 []string{"device"},
149 nil),
151 writtenbytes: prometheus.NewDesc("disk_written_bytes",
152 "Bytes written to disk, per device name (e.g. xvda).",
153 []string{"device"},
154 nil),
158 // vim:ts=4:sw=4:noexpandtab