forked from bosun-monitor/bosun
/
ntp_unix.go
97 lines (90 loc) · 2.4 KB
/
ntp_unix.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// +build !windows
package collectors
import (
"fmt"
"strconv"
"strings"
"bosun.org/metadata"
"bosun.org/opentsdb"
"bosun.org/util"
"time"
)
func init() {
collectors = append(collectors, &IntervalCollector{F: c_ntp_peers_unix, Interval: time.Minute})
}
var ntpNtpqPeerFields = []string{
"remote",
"refid",
"st",
"t",
"when",
"poll",
"reach",
"delay",
"offset",
"jitter",
}
// ntUnPretty reverses human formating for poll and when, see prettyinterval in ntpq/ntpq-subs.c
func ntpUnPretty(s string) (int64, error) {
if len(s) < 1 {
return 0, fmt.Errorf("Zero length string passed to ntpUnPretty")
}
var multiplier int64 = 1
shift := 1
switch s[len(s)-1] {
case 'm':
multiplier = 60
case 'h':
multiplier = 60 * 60
case 'd':
multiplier = 60 * 60 * 24
default:
shift = 0
}
i, err := strconv.ParseInt(s[0:len(s)-shift], 10, 64)
return i * multiplier, err
}
func c_ntp_peers_unix() (opentsdb.MultiDataPoint, error) {
var md opentsdb.MultiDataPoint
const metric = "ntp."
_ = util.ReadCommand(func(line string) error {
fields := strings.Fields(line)
if len(fields) != len(ntpNtpqPeerFields) || fields[0] == "remote" {
return nil
}
r := []rune(line)
if len(r) < 2 {
return fmt.Errorf("unexpected length of line")
}
fl := string(r[0])
rest := string(r[1:])
fields = strings.Fields(rest)
if len(fields) != len(ntpNtpqPeerFields) {
return fmt.Errorf("unexpected length of fields")
}
remote := fields[0]
tags := opentsdb.TagSet{"remote": remote, "refid": fields[1]}
var current_source int
if fl == "*" {
current_source = 1
}
Add(&md, metric+"current_source", current_source, tags, metadata.Gauge, metadata.Bool, "")
Add(&md, metric+"stratum", fields[2], tags, metadata.Gauge, "Stratum", "")
when, err := ntpUnPretty(fields[4])
if err != nil {
return err
}
Add(&md, metric+"when", when, tags, metadata.Gauge, metadata.Second, "")
poll, err := ntpUnPretty(fields[5])
if err != nil {
return err
}
Add(&md, metric+"poll", poll, tags, metadata.Gauge, metadata.Second, "")
Add(&md, metric+"reach", fields[6], tags, metadata.Gauge, "Code", "")
Add(&md, metric+"delay", fields[7], tags, metadata.Gauge, metadata.MilliSecond, "")
Add(&md, metric+"offset", fields[8], tags, metadata.Gauge, metadata.MilliSecond, "")
Add(&md, metric+"jitter", fields[9], tags, metadata.Gauge, metadata.MilliSecond, "")
return nil
}, "ntpq", "-pn")
return md, nil
}