master
go 148 lines 4.4 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package prometheus
4
5 import (
6 "context"
7 _ "embed"
8 "fmt"
9 "time"
10
11 "github.com/netdata/netdata/go/plugins/pkg/confopt"
12 "github.com/netdata/netdata/go/plugins/pkg/metrix"
13 "github.com/netdata/netdata/go/plugins/pkg/prometheus"
14 "github.com/netdata/netdata/go/plugins/pkg/prometheus/selector"
15 "github.com/netdata/netdata/go/plugins/pkg/web"
16 "github.com/netdata/netdata/go/plugins/plugin/framework/collectorapi"
17 "github.com/netdata/netdata/go/plugins/plugin/go.d/collector/prometheus/relabel"
18 )
19
20 //go:embed "config_schema.json"
21 var configSchema string
22
23 func init() {
24 collectorapi.Register("prometheus", collectorapi.Creator{
25 JobConfigSchema: configSchema,
26 Defaults: collectorapi.Defaults{
27 UpdateEvery: 10,
28 },
29 CreateV2: func() collectorapi.CollectorV2 { return New() },
30 Config: func() any { return &Config{} },
31 })
32 }
33
34 func New() *Collector {
35 return &Collector{
36 Config: Config{
37 HTTPConfig: web.HTTPConfig{
38 ClientConfig: web.ClientConfig{
39 Timeout: confopt.Duration(time.Second * 10),
40 },
41 },
42 MaxTS: 2000,
43 MaxTSPerMetric: 200,
44 },
45 store: metrix.NewCollectorStore(),
46 }
47 }
48
49 type Config struct {
50 Vnode string `yaml:"vnode,omitempty" json:"vnode"`
51 UpdateEvery int `yaml:"update_every,omitempty" json:"update_every"`
52 AutoDetectionRetry int `yaml:"autodetection_retry,omitempty" json:"autodetection_retry"`
53 web.HTTPConfig `yaml:",inline" json:""`
54 Name string `yaml:"name,omitempty" json:"name"`
55 Application string `yaml:"app,omitempty" json:"app"`
56 LabelPrefix string `yaml:"label_prefix,omitempty" json:"label_prefix"`
57 Selector selector.Expr `yaml:"selector,omitempty" json:"selector"`
58 ExpectedPrefix string `yaml:"expected_prefix,omitempty" json:"expected_prefix"`
59 MaxTS int `yaml:"max_time_series" json:"max_time_series"`
60 MaxTSPerMetric int `yaml:"max_time_series_per_metric" json:"max_time_series_per_metric"`
61 FallbackType struct {
62 Gauge []string `yaml:"gauge,omitempty" json:"gauge"`
63 Counter []string `yaml:"counter,omitempty" json:"counter"`
64 } `yaml:"fallback_type,omitempty" json:"fallback_type"`
65 }
66
67 type Collector struct {
68 collectorapi.Base
69 Config `yaml:",inline" json:""`
70
71 prom prometheus.Prometheus
72 relabelConfigs []relabel.Config
73 relabelTransform prometheus.SampleTransform
74 store metrix.CollectorStore
75 writer *metricFamilyWriter
76 chartTemplate string
77 }
78
79 func (c *Collector) Configuration() any {
80 return c.Config
81 }
82
83 func (c *Collector) Init(context.Context) error {
84 if err := c.validateConfig(); err != nil {
85 return fmt.Errorf("validating config: %v", err)
86 }
87
88 prom, err := c.initPrometheusClient()
89 if err != nil {
90 return fmt.Errorf("init prometheus client: %v", err)
91 }
92 c.prom = prom
93
94 // relabelConfigs are empty in this PR (rules are set by tests; profiles populate
95 // them later), so NewTransform returns a nil transform and Scrape keeps its
96 // no-transform fast path. A non-empty, invalid rule set fails Init here.
97 transform, err := relabel.NewTransform(c.relabelConfigs, c.onRelabelDrop)
98 if err != nil {
99 return fmt.Errorf("init relabel: %v", err)
100 }
101 c.relabelTransform = transform
102
103 gaugeFallback, err := c.initFallbackTypeMatcher(c.FallbackType.Gauge)
104 if err != nil {
105 return fmt.Errorf("init gauge fallback type matcher: %v", err)
106 }
107 counterFallback, err := c.initFallbackTypeMatcher(c.FallbackType.Counter)
108 if err != nil {
109 return fmt.Errorf("init counter fallback type matcher: %v", err)
110 }
111
112 c.writer = newMetricFamilyWriter(c.store, metricFamilyWriterPolicy{
113 labelPrefix: c.LabelPrefix,
114 maxTSPerMetric: c.MaxTSPerMetric,
115 isFallbackTypeGauge: gaugeFallback,
116 isFallbackTypeCounter: counterFallback,
117 }, c.Logger)
118
119 tmpl, err := buildChartTemplate(c.application())
120 if err != nil {
121 return fmt.Errorf("build chart template: %v", err)
122 }
123 c.chartTemplate = tmpl
124
125 return nil
126 }
127
128 func (c *Collector) Check(ctx context.Context) error {
129 return c.check(ctx)
130 }
131
132 func (c *Collector) Collect(ctx context.Context) error {
133 return c.collect(ctx)
134 }
135
136 func (c *Collector) Cleanup(context.Context) {
137 if c.prom != nil && c.prom.HTTPClient() != nil {
138 c.prom.HTTPClient().CloseIdleConnections()
139 }
140 }
141
142 func (c *Collector) MetricStore() metrix.CollectorStore {
143 return c.store
144 }
145
146 func (c *Collector) ChartTemplateYAML() string {
147 return c.chartTemplate
148 }