master
go 137 lines 3 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package consul
4
5 import (
6 "context"
7 _ "embed"
8 "errors"
9 "fmt"
10 "net/http"
11 "sync"
12 "time"
13
14 "github.com/blang/semver/v4"
15
16 "github.com/netdata/netdata/go/plugins/pkg/confopt"
17 "github.com/netdata/netdata/go/plugins/pkg/prometheus"
18 "github.com/netdata/netdata/go/plugins/pkg/web"
19 "github.com/netdata/netdata/go/plugins/plugin/framework/collectorapi"
20 )
21
22 //go:embed "config_schema.json"
23 var configSchema string
24
25 func init() {
26 collectorapi.Register("consul", collectorapi.Creator{
27 JobConfigSchema: configSchema,
28 Defaults: collectorapi.Defaults{
29 UpdateEvery: 1,
30 },
31 Create: func() collectorapi.CollectorV1 { return New() },
32 Config: func() any { return &Config{} },
33 })
34 }
35
36 func New() *Collector {
37 return &Collector{
38 Config: Config{
39 HTTPConfig: web.HTTPConfig{
40 RequestConfig: web.RequestConfig{
41 URL: "http://127.0.0.1:8500",
42 },
43 ClientConfig: web.ClientConfig{
44 Timeout: confopt.Duration(time.Second),
45 },
46 },
47 },
48 charts: &collectorapi.Charts{},
49 addGlobalChartsOnce: &sync.Once{},
50 addServerAutopilotChartsOnce: &sync.Once{},
51 checks: make(map[string]bool),
52 }
53 }
54
55 type Config struct {
56 Vnode string `yaml:"vnode,omitempty" json:"vnode"`
57 UpdateEvery int `yaml:"update_every,omitempty" json:"update_every"`
58 AutoDetectionRetry int `yaml:"autodetection_retry,omitempty" json:"autodetection_retry"`
59 web.HTTPConfig `yaml:",inline" json:""`
60 ACLToken string `yaml:"acl_token,omitempty" json:"acl_token"`
61 }
62
63 type Collector struct {
64 collectorapi.Base
65 Config `yaml:",inline" json:""`
66
67 charts *collectorapi.Charts
68 addGlobalChartsOnce *sync.Once
69 addServerAutopilotChartsOnce *sync.Once
70
71 httpClient *http.Client
72 prom prometheus.Prometheus
73
74 cfg *consulConfig
75 version *semver.Version
76 hasLeaderCharts bool
77 hasFollowerCharts bool
78 checks map[string]bool
79 }
80
81 func (c *Collector) Configuration() any {
82 return c.Config
83 }
84
85 func (c *Collector) Init(context.Context) error {
86 if err := c.validateConfig(); err != nil {
87 return fmt.Errorf("config validation: %v", err)
88 }
89
90 httpClient, err := c.initHTTPClient()
91 if err != nil {
92 return fmt.Errorf("init HTTP client: %v", err)
93 }
94 c.httpClient = httpClient
95
96 prom, err := c.initPrometheusClient(httpClient)
97 if err != nil {
98 return fmt.Errorf("init Prometheus client: %v", err)
99 }
100 c.prom = prom
101
102 return nil
103 }
104
105 func (c *Collector) Check(context.Context) error {
106 mx, err := c.collect()
107 if err != nil {
108 return err
109 }
110 if len(mx) == 0 {
111 return errors.New("no metrics collected")
112
113 }
114 return nil
115 }
116
117 func (c *Collector) Charts() *collectorapi.Charts {
118 return c.charts
119 }
120
121 func (c *Collector) Collect(context.Context) map[string]int64 {
122 mx, err := c.collect()
123 if err != nil {
124 c.Error(err)
125 }
126
127 if len(mx) == 0 {
128 return nil
129 }
130 return mx
131 }
132
133 func (c *Collector) Cleanup(context.Context) {
134 if c.httpClient != nil {
135 c.httpClient.CloseIdleConnections()
136 }
137 }