looks work anyway
@@ -2,6 +2,7 @@ package checkntpoffset
import (
"bufio"
+ "context"
"fmt"
"io"
"math"
@@ -10,7 +11,9 @@ import (
"path/filepath"
"strconv"
"strings"
+ "time"
+ "github.com/beevik/ntp"
"github.com/jessevdk/go-flags"
"github.com/mackerelio/checkers"
)
@@ -18,6 +21,14 @@ import (
var opts struct {
Crit float64 `short:"c" long:"critical" default:"100" description:"Critical threshold of ntp offset(ms)"`
Warn float64 `short:"w" long:"warning" default:"50" description:"Warning threshold of ntp offset(ms)"`
+ NTPServers string `short:"s" long:"ntp-servers" default:"" description:"Use specified NTP Servers(plural servers can be set separated by ,). When set plural servers, use first response. If not set, use local command just like ntpd/chronyd."`
+ NTPTimeout int `short:"t" long:"ntp-timeout" default:"15" description:"Timeout of NTP Server Querying(in seconds)."`
+}
+
+var ntpTimeout int
+
+func init() {
+ ntpTimeout = 15
}
// Do the plugin
@@ -32,8 +43,9 @@ func run(args []string) *checkers.Checker {
if err != nil {
os.Exit(1)
}
+ ntpTimeout = opts.NTPTimeout
- offset, err := getNTPOffset()
+ offset, err := getNTPOffset(opts.NTPServers)
if err != nil {
return checkers.Unknown(err.Error())
}
@@ -103,7 +115,34 @@ func detectNTPDname() (ntpdName string, err error) {
return ntpdName, err
}
-func getNTPOffset() (float64, error) {
+func getNTPOffset(ntpServers string) (float64, error) {
+ if ntpServers != "" {
+ ctx := context.Background()
+ ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
+ defer cancel()
+ resultChan := make(chan float64)
+ for _, ntpServer := range strings.Split(ntpServers, ",") {
+ go func(ntpServer string) error {
+ ntpServer = strings.Trim(ntpServer, " ")
+ options := ntp.QueryOptions{Timeout: time.Duration(ntpTimeout) * time.Second}
+ response, err := ntp.QueryWithOptions(ntpServer, options)
+ if err != nil {
+ return err
+ }
+ resultChan <- float64(response.ClockOffset / time.Millisecond)
+ return nil
+ }(ntpServer)
+ }
+
+ select {
+ case <-ctx.Done():
+ return 0.0, fmt.Errorf("NTP offset cannot get from %q", ntpServers)
+ case offset := <-resultChan:
+ return offset, nil
+ }
+
+ }
+
ntpdName, err := detectNTPDname()
if err != nil {
return 0.0, err
