diff options
Diffstat (limited to '')
-rw-r--r-- | src/go/collectors/go.d.plugin/modules/consul/collect_net_rtt.go | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/go/collectors/go.d.plugin/modules/consul/collect_net_rtt.go b/src/go/collectors/go.d.plugin/modules/consul/collect_net_rtt.go new file mode 100644 index 000000000..1b1853719 --- /dev/null +++ b/src/go/collectors/go.d.plugin/modules/consul/collect_net_rtt.go @@ -0,0 +1,75 @@ +package consul + +import ( + "math" + "time" + + "github.com/netdata/netdata/go/go.d.plugin/pkg/metrics" +) + +const ( + // https://developer.hashicorp.com/consul/api-docs/coordinate#read-lan-coordinates-for-all-nodes + urlPathCoordinateNodes = "/v1/coordinate/nodes" +) + +type nodeCoordinates struct { + Node string + Coord struct { + Vec []float64 + Error float64 + Adjustment float64 + Height float64 + } +} + +func (c *Consul) collectNetworkRTT(mx map[string]int64) error { + var coords []nodeCoordinates + + if err := c.doOKDecode(urlPathCoordinateNodes, &coords); err != nil { + return err + } + + var thisNode nodeCoordinates + var ok bool + + coords, thisNode, ok = removeNodeCoordinates(coords, c.cfg.Config.NodeName) + if !ok || len(coords) == 0 { + return nil + } + + sum := metrics.NewSummary() + for _, v := range coords { + d := calcDistance(thisNode, v) + sum.Observe(d.Seconds()) + } + sum.WriteTo(mx, "network_lan_rtt", 1e9, 1) + + return nil +} + +func calcDistance(a, b nodeCoordinates) time.Duration { + // https://developer.hashicorp.com/consul/docs/architecture/coordinates#working-with-coordinates + sum := 0.0 + for i := 0; i < len(a.Coord.Vec); i++ { + diff := a.Coord.Vec[i] - b.Coord.Vec[i] + sum += diff * diff + } + + rtt := math.Sqrt(sum) + a.Coord.Height + b.Coord.Height + + adjusted := rtt + a.Coord.Adjustment + b.Coord.Adjustment + if adjusted > 0.0 { + rtt = adjusted + } + + return time.Duration(rtt * 1e9) // nanoseconds +} + +func removeNodeCoordinates(coords []nodeCoordinates, node string) ([]nodeCoordinates, nodeCoordinates, bool) { + for i, v := range coords { + if v.Node == node { + return append(coords[:i], coords[i+1:]...), v, true + } + } + return coords, nodeCoordinates{}, false +} |