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  }