summaryrefslogtreecommitdiffstats
path: root/src/go/collectors/go.d.plugin/modules/consul/collect_net_rtt.go
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/go/collectors/go.d.plugin/modules/consul/collect_net_rtt.go75
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
+}