go.undefinedlabs.com/scopeagent@v0.4.2/agent/ntp.go (about) 1 package agent 2 3 import ( 4 "github.com/beevik/ntp" 5 "sync" 6 "time" 7 ) 8 9 const ( 10 server = "pool.ntp.org" 11 retries = 5 12 timeout = 2 * time.Second 13 backoff = 1 * time.Second 14 ) 15 16 var ( 17 ntpOffset time.Duration 18 once sync.Once 19 ) 20 21 // Gets the NTP offset from the ntp server pool 22 func getNTPOffset() (time.Duration, error) { 23 var ntpError error = nil 24 for i := 1; i <= retries; i++ { 25 r, err := ntp.QueryWithOptions(server, ntp.QueryOptions{Timeout: timeout}) 26 if err == nil { 27 return r.ClockOffset, nil 28 } 29 ntpError = err 30 time.Sleep(backoff) 31 } 32 return 0, ntpError 33 } 34 35 // Applies the NTP offset to the given time 36 func (r *SpanRecorder) applyNTPOffset(t time.Time) time.Time { 37 once.Do(func() { 38 if r.debugMode { 39 r.logger.Println("calculating ntp offset.") 40 } 41 offset := r.cache.GetOrSet("ntp", true, func(d interface{}, s string) interface{} { 42 oSet, err := getNTPOffset() 43 if err != nil { 44 r.logger.Printf("error calculating the ntp offset: %v\n", err) 45 return nil 46 } 47 return float64(oSet) 48 }) 49 if offset != nil { 50 ntpOffset = time.Duration(offset.(float64)) 51 r.logger.Printf("ntp offset: %v\n", ntpOffset) 52 } 53 }) 54 return t.Add(ntpOffset) 55 }