Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/pkg/integrations/v2/metricsutils/metricshandler_integration.go
5365 views
1
package metricsutils
2
3
import (
4
"context"
5
"fmt"
6
"net/http"
7
"path"
8
9
"github.com/go-kit/log"
10
"github.com/gorilla/mux"
11
"github.com/grafana/agent/pkg/integrations/v2"
12
"github.com/grafana/agent/pkg/integrations/v2/autoscrape"
13
"github.com/grafana/agent/pkg/integrations/v2/common"
14
"github.com/prometheus/common/model"
15
"github.com/prometheus/prometheus/config"
16
"github.com/prometheus/prometheus/discovery"
17
"github.com/prometheus/prometheus/discovery/targetgroup"
18
)
19
20
// NewMetricsHandlerIntegration returns a integrations.MetricsIntegration which
21
// will expose a /metrics endpoint for h.
22
func NewMetricsHandlerIntegration(
23
_ log.Logger,
24
c integrations.Config,
25
mc common.MetricsConfig,
26
globals integrations.Globals,
27
h http.Handler,
28
) (integrations.MetricsIntegration, error) {
29
30
id, err := c.Identifier(globals)
31
if err != nil {
32
return nil, err
33
}
34
return &metricsHandlerIntegration{
35
integrationName: c.Name(),
36
instanceID: id,
37
38
common: mc,
39
globals: globals,
40
handler: h,
41
42
targets: []handlerTarget{{MetricsPath: "metrics"}},
43
}, nil
44
}
45
46
type metricsHandlerIntegration struct {
47
integrationName, instanceID string
48
49
common common.MetricsConfig
50
globals integrations.Globals
51
handler http.Handler
52
targets []handlerTarget
53
54
runFunc func(ctx context.Context) error
55
}
56
57
type handlerTarget struct {
58
// Path relative to Handler prefix where metrics are available.
59
MetricsPath string
60
// Extra labels to inject into the target. Labels here that take precedence
61
// over labels with the same name from the generated target group.
62
Labels model.LabelSet
63
}
64
65
// Static typecheck tests
66
var (
67
_ integrations.Integration = (*metricsHandlerIntegration)(nil)
68
_ integrations.HTTPIntegration = (*metricsHandlerIntegration)(nil)
69
_ integrations.MetricsIntegration = (*metricsHandlerIntegration)(nil)
70
)
71
72
// RunIntegration implements Integration.
73
func (i *metricsHandlerIntegration) RunIntegration(ctx context.Context) error {
74
// Call our runFunc if defined (used from integrationShim), otherwise
75
// fallback to no-op.
76
if i.runFunc != nil {
77
return i.runFunc(ctx)
78
}
79
80
<-ctx.Done()
81
return nil
82
}
83
84
// Handler implements HTTPIntegration.
85
func (i *metricsHandlerIntegration) Handler(prefix string) (http.Handler, error) {
86
r := mux.NewRouter()
87
r.Handle(path.Join(prefix, "metrics"), i.handler)
88
return r, nil
89
}
90
91
// Targets implements MetricsIntegration.
92
func (i *metricsHandlerIntegration) Targets(ep integrations.Endpoint) []*targetgroup.Group {
93
integrationNameValue := model.LabelValue("integrations/" + i.integrationName)
94
95
group := &targetgroup.Group{
96
Labels: model.LabelSet{
97
model.InstanceLabel: model.LabelValue(i.instanceID),
98
model.JobLabel: integrationNameValue,
99
"agent_hostname": model.LabelValue(i.globals.AgentIdentifier),
100
101
// Meta labels that can be used during SD.
102
"__meta_agent_integration_name": model.LabelValue(i.integrationName),
103
"__meta_agent_integration_instance": model.LabelValue(i.instanceID),
104
"__meta_agent_integration_autoscrape": model.LabelValue(BoolToString(*i.common.Autoscrape.Enable)),
105
},
106
Source: fmt.Sprintf("%s/%s", i.integrationName, i.instanceID),
107
}
108
109
for _, lbl := range i.common.ExtraLabels {
110
group.Labels[model.LabelName(lbl.Name)] = model.LabelValue(lbl.Value)
111
}
112
113
for _, t := range i.targets {
114
group.Targets = append(group.Targets, model.LabelSet{
115
model.AddressLabel: model.LabelValue(ep.Host),
116
model.MetricsPathLabel: model.LabelValue(path.Join(ep.Prefix, t.MetricsPath)),
117
}.Merge(t.Labels))
118
}
119
120
return []*targetgroup.Group{group}
121
}
122
123
// BoolToString is a helper for converting boolean values to a Prometheus labels-compatible string.
124
func BoolToString(b bool) string {
125
switch b {
126
case true:
127
return "1"
128
default:
129
return "0"
130
}
131
}
132
133
// ScrapeConfigs implements MetricsIntegration.
134
func (i *metricsHandlerIntegration) ScrapeConfigs(sd discovery.Configs) []*autoscrape.ScrapeConfig {
135
if !*i.common.Autoscrape.Enable {
136
return nil
137
}
138
139
cfg := config.DefaultScrapeConfig
140
cfg.JobName = fmt.Sprintf("%s/%s", i.integrationName, i.instanceID)
141
cfg.Scheme = i.globals.AgentBaseURL.Scheme
142
cfg.ServiceDiscoveryConfigs = sd
143
cfg.ScrapeInterval = i.common.Autoscrape.ScrapeInterval
144
cfg.ScrapeTimeout = i.common.Autoscrape.ScrapeTimeout
145
cfg.RelabelConfigs = i.common.Autoscrape.RelabelConfigs
146
cfg.MetricRelabelConfigs = i.common.Autoscrape.MetricRelabelConfigs
147
148
return []*autoscrape.ScrapeConfig{{
149
Instance: i.common.Autoscrape.MetricsInstance,
150
Config: cfg,
151
}}
152
}
153
154