func NewNTPStats()

in cmd/ntpcheck/checker/stats.go [39:102]


func NewNTPStats(r *NTPCheckResult) (*NTPStats, error) {
	if r.SysVars == nil {
		return nil, errors.New("no system variables to output stats")
	}
	syspeer, err := r.FindSysPeer()
	var delay, jitter, offset float64
	var poll uint
	var stratum int
	if err != nil {
		log.Warningf("Can't get system peer: %v", err)
		// calculate averages like ntp_stats_ods.py did
		total := len(r.Peers)
		if total == 0 {
			return nil, errors.New("no peers detected to output stats")
		}
		goodPeers, err := r.FindGoodPeers()
		if err != nil {
			return nil, errors.Wrap(err, "nothing to calculate stats from")
		}
		totalDelay := 0.0
		totalJitter := 0.0
		totalOffset := 0.0
		bestPPoll := 0
		bestHPoll := 0
		bestStratum := 0
		for _, p := range goodPeers {
			totalDelay += p.Delay
			totalJitter += p.Jitter
			totalOffset += p.Offset
			if bestPPoll != 0 && p.PPoll < bestPPoll {
				bestPPoll = p.PPoll
			}
			if bestHPoll != 0 && p.HPoll < bestHPoll {
				bestHPoll = p.HPoll
			}
			if bestStratum != 0 && p.Stratum < bestStratum {
				bestStratum = p.Stratum
			}
		}
		delay = totalDelay / float64(total)
		jitter = totalJitter / float64(total)
		offset = totalOffset / float64(total)
		stratum = bestStratum
		poll = uint(math.Min(float64(bestPPoll), float64(bestHPoll)))
	} else {
		delay = syspeer.Delay
		jitter = syspeer.Jitter
		poll = uint(math.Min(float64(syspeer.PPoll), float64(syspeer.HPoll)))
		stratum = syspeer.Stratum
		offset = syspeer.Offset
	}
	output := NTPStats{
		PeerDelay:   delay,
		PeerPoll:    1 << poll, // hpoll and ppoll are stored in seconds as a power of two
		PeerJitter:  jitter,
		PeerOffset:  offset,
		PeerStratum: stratum,
		Frequency:   r.SysVars.Frequency,
		Correction:  r.Correction,
		// that's how ntpstat defines unsynchronized
		StatError: r.LI == 3,
	}
	return &output, nil
}