mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-30 07:40:06 +01:00
c06e7a142c
Cache sanitized label names and return them next time. This reduces the number of allocations and speeds up the SanitizeLabelName() function for common case when the number of unique label names is smaller than 100k
89 lines
2.5 KiB
Go
89 lines
2.5 KiB
Go
package dockerswarm
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promscrape/discoveryutils"
|
|
)
|
|
|
|
// See https://docs.docker.com/engine/api/v1.40/#tag/Node
|
|
type node struct {
|
|
ID string
|
|
Spec struct {
|
|
Labels map[string]string
|
|
Role string
|
|
Availability string
|
|
}
|
|
Description struct {
|
|
Hostname string
|
|
Platform struct {
|
|
Architecture string
|
|
OS string
|
|
}
|
|
Engine struct {
|
|
EngineVersion string
|
|
}
|
|
}
|
|
Status struct {
|
|
State string
|
|
Message string
|
|
Addr string
|
|
}
|
|
ManagerStatus struct {
|
|
Leader bool
|
|
Reachability string
|
|
Addr string
|
|
}
|
|
}
|
|
|
|
func getNodesLabels(cfg *apiConfig) ([]map[string]string, error) {
|
|
nodes, err := getNodes(cfg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return addNodeLabels(nodes, cfg.port), nil
|
|
}
|
|
|
|
func getNodes(cfg *apiConfig) ([]node, error) {
|
|
resp, err := cfg.getAPIResponse("/nodes")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("cannot query dockerswarm api for nodes: %w", err)
|
|
}
|
|
return parseNodes(resp)
|
|
}
|
|
|
|
func parseNodes(data []byte) ([]node, error) {
|
|
var nodes []node
|
|
if err := json.Unmarshal(data, &nodes); err != nil {
|
|
return nil, fmt.Errorf("cannot parse nodes: %w", err)
|
|
}
|
|
return nodes, nil
|
|
}
|
|
|
|
func addNodeLabels(nodes []node, port int) []map[string]string {
|
|
var ms []map[string]string
|
|
for _, node := range nodes {
|
|
m := map[string]string{
|
|
"__address__": discoveryutils.JoinHostPort(node.Status.Addr, port),
|
|
"__meta_dockerswarm_node_address": node.Status.Addr,
|
|
"__meta_dockerswarm_node_availability": node.Spec.Availability,
|
|
"__meta_dockerswarm_node_engine_version": node.Description.Engine.EngineVersion,
|
|
"__meta_dockerswarm_node_hostname": node.Description.Hostname,
|
|
"__meta_dockerswarm_node_id": node.ID,
|
|
"__meta_dockerswarm_node_manager_address": node.ManagerStatus.Addr,
|
|
"__meta_dockerswarm_node_manager_leader": fmt.Sprintf("%t", node.ManagerStatus.Leader),
|
|
"__meta_dockerswarm_node_manager_reachability": node.ManagerStatus.Reachability,
|
|
"__meta_dockerswarm_node_platform_architecture": node.Description.Platform.Architecture,
|
|
"__meta_dockerswarm_node_platform_os": node.Description.Platform.OS,
|
|
"__meta_dockerswarm_node_role": node.Spec.Role,
|
|
"__meta_dockerswarm_node_status": node.Status.State,
|
|
}
|
|
for k, v := range node.Spec.Labels {
|
|
m[discoveryutils.SanitizeLabelName("__meta_dockerswarm_node_label_"+k)] = v
|
|
}
|
|
ms = append(ms, m)
|
|
}
|
|
return ms
|
|
}
|