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