master
go 69 lines 2.33 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package consul
4
5 import (
6 "net/http"
7 "time"
8
9 "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/oldmetrix"
10 )
11
12 const (
13 // https://developer.hashicorp.com/consul/api-docs/operator/autopilot#read-health
14 urlPathOperationAutopilotHealth = "/v1/operator/autopilot/health"
15 )
16
17 type autopilotHealth struct {
18 Servers []struct {
19 ID string
20 SerfStatus string
21 Leader bool
22 LastContact string
23 Healthy bool
24 Voter bool
25 StableSince time.Time
26 }
27 }
28
29 func (c *Collector) collectAutopilotHealth(mx map[string]int64) error {
30 req, err := c.createRequest(urlPathOperationAutopilotHealth)
31 if err != nil {
32 return err
33 }
34
35 var health autopilotHealth
36
37 // The HTTP status code will indicate the health of the cluster: 200 is healthy, 429 is unhealthy.
38 // https://github.com/hashicorp/consul/blob/c7ef04c5979dbc311ff3c67b7bf3028a93e8b0f1/agent/operator_endpoint.go#L325
39 if err := c.client(http.StatusTooManyRequests).RequestJSON(req, &health); err != nil {
40 return err
41 }
42
43 for _, srv := range health.Servers {
44 if srv.ID == c.cfg.Config.NodeID {
45 // SerfStatus: alive, left, failed or none:
46 // https://github.com/hashicorp/consul/blob/c7ef04c5979dbc311ff3c67b7bf3028a93e8b0f1/agent/consul/operator_autopilot_endpoint.go#L124-L133
47 mx["autopilot_server_sefStatus_alive"] = oldmetrix.Bool(srv.SerfStatus == "alive")
48 mx["autopilot_server_sefStatus_left"] = oldmetrix.Bool(srv.SerfStatus == "left")
49 mx["autopilot_server_sefStatus_failed"] = oldmetrix.Bool(srv.SerfStatus == "failed")
50 mx["autopilot_server_sefStatus_none"] = oldmetrix.Bool(srv.SerfStatus == "none")
51 // https://github.com/hashicorp/raft-autopilot/blob/d936f51c374c3b7902d5e4fdafe9f7d8d199ea53/types.go#L110
52 mx["autopilot_server_healthy_yes"] = oldmetrix.Bool(srv.Healthy)
53 mx["autopilot_server_healthy_no"] = oldmetrix.Bool(!srv.Healthy)
54 mx["autopilot_server_voter_yes"] = oldmetrix.Bool(srv.Voter)
55 mx["autopilot_server_voter_no"] = oldmetrix.Bool(!srv.Voter)
56 mx["autopilot_server_stable_time"] = int64(time.Since(srv.StableSince).Seconds())
57 mx["autopilot_server_stable_time"] = int64(time.Since(srv.StableSince).Seconds())
58 if !srv.Leader {
59 if v, err := time.ParseDuration(srv.LastContact); err == nil {
60 mx["autopilot_server_lastContact_leader"] = v.Milliseconds()
61 }
62 }
63
64 break
65 }
66 }
67
68 return nil
69 }