github.com/netdata/go.d.plugin@v0.58.1/modules/ntpd/collect.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package ntpd
     4  
     5  import (
     6  	"fmt"
     7  	"net"
     8  	"strconv"
     9  	"time"
    10  )
    11  
    12  const (
    13  	precision = 1000000
    14  )
    15  
    16  func (n *NTPd) collect() (map[string]int64, error) {
    17  	if n.client == nil {
    18  		client, err := n.newClient(n.Config)
    19  		if err != nil {
    20  			return nil, fmt.Errorf("creating NTP client: %v", err)
    21  		}
    22  		n.client = client
    23  	}
    24  
    25  	mx := make(map[string]int64)
    26  
    27  	if err := n.collectInfo(mx); err != nil {
    28  		return nil, err
    29  	}
    30  
    31  	if n.CollectPeers {
    32  		if now := time.Now(); now.Sub(n.findPeersTime) > n.findPeersEvery {
    33  			n.findPeersTime = now
    34  			if err := n.findPeers(); err != nil {
    35  				n.Warning(err)
    36  			}
    37  		}
    38  		n.collectPeersInfo(mx)
    39  	}
    40  
    41  	return mx, nil
    42  }
    43  
    44  func (n *NTPd) collectInfo(mx map[string]int64) error {
    45  	info, err := n.client.systemInfo()
    46  	if err != nil {
    47  		return fmt.Errorf("error on querying system info: %v", err)
    48  	}
    49  
    50  	for k, v := range info {
    51  		switch k {
    52  		case
    53  			"offset",
    54  			"sys_jitter",
    55  			"clk_jitter",
    56  			"frequency",
    57  			"clk_wander",
    58  			"rootdelay",
    59  			"rootdisp",
    60  			"stratum",
    61  			"tc",
    62  			"mintc",
    63  			"precision":
    64  			if val, err := strconv.ParseFloat(v, 64); err == nil {
    65  				mx[k] = int64(val * precision)
    66  			}
    67  		}
    68  	}
    69  	return nil
    70  }
    71  
    72  func (n *NTPd) collectPeersInfo(mx map[string]int64) {
    73  	for _, id := range n.peerIDs {
    74  		info, err := n.client.peerInfo(id)
    75  		if err != nil {
    76  			n.Warningf("error on querying NTP peer info id='%d': %v", id, err)
    77  			continue
    78  		}
    79  
    80  		addr, ok := info["srcadr"]
    81  		if !ok {
    82  			continue
    83  		}
    84  
    85  		for k, v := range info {
    86  			switch k {
    87  			case
    88  				"offset",
    89  				"delay",
    90  				"dispersion",
    91  				"jitter",
    92  				"xleave",
    93  				"rootdelay",
    94  				"rootdisp",
    95  				"stratum",
    96  				"hmode",
    97  				"pmode",
    98  				"hpoll",
    99  				"ppoll",
   100  				"precision":
   101  				if val, err := strconv.ParseFloat(v, 64); err == nil {
   102  					mx["peer_"+addr+"_"+k] = int64(val * precision)
   103  				}
   104  			}
   105  		}
   106  	}
   107  }
   108  
   109  func (n *NTPd) findPeers() error {
   110  	n.peerIDs = n.peerIDs[:0]
   111  
   112  	n.Debug("querying NTP peers")
   113  	peers, err := n.client.peerIDs()
   114  	if err != nil {
   115  		return fmt.Errorf("querying NTP peers: %v", err)
   116  	}
   117  
   118  	n.Debugf("found %d NTP peers (ids: %v)", len(peers), peers)
   119  	seen := make(map[string]bool)
   120  
   121  	for _, id := range peers {
   122  		info, err := n.client.peerInfo(id)
   123  		if err != nil {
   124  			n.Debugf("error on querying NTP peer info id='%d': %v", id, err)
   125  			continue
   126  		}
   127  
   128  		addr, ok := info["srcadr"]
   129  		if ip := net.ParseIP(addr); !ok || ip == nil || n.peerIPAddrFilter.Contains(ip) {
   130  			n.Debugf("skipping NTP peer id='%d', srcadr='%s'", id, addr)
   131  			continue
   132  		}
   133  
   134  		seen[addr] = true
   135  
   136  		if !n.peerAddr[addr] {
   137  			n.peerAddr[addr] = true
   138  			n.Debugf("new NTP peer id='%d', srcadr='%s': creating charts", id, addr)
   139  			n.addPeerCharts(addr)
   140  		}
   141  
   142  		n.peerIDs = append(n.peerIDs, id)
   143  	}
   144  
   145  	for addr := range n.peerAddr {
   146  		if !seen[addr] {
   147  			delete(n.peerAddr, addr)
   148  			n.Debugf("stale NTP peer srcadr='%s': removing charts", addr)
   149  			n.removePeerCharts(addr)
   150  		}
   151  	}
   152  
   153  	return nil
   154  }