Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/pkg/integrations/v2/integrations.go
5308 views
1
// Package integrations provides a way to run and manage Grafana Agent
2
// "integrations," which integrate some external system (such as MySQL) to
3
// Grafana Agent's existing metrics, logging, and tracing subsystems.
4
//
5
// Integrations are implemented in sub-packages. Every integration must
6
// have an implementation of Config that configures the integration. The Config
7
// interface is then used to instantiate an instance of the Integration
8
// interface.
9
//
10
// Implementations of integrations implement extra functionality by
11
// implementing interface extensions. The Integration interface is the most
12
// basic interface that all integrations must implement. Extensions like
13
// the MetricsIntegration interface define an integration that supports
14
// metrics.
15
//
16
// Extension interfaces are used by the integrations subsystem to enable
17
// common use cases. New behaviors can be implemented by manually using
18
// the other subsystems of the agent provided in IntegrationOptions.
19
package integrations
20
21
import (
22
"context"
23
"fmt"
24
"net/http"
25
"net/url"
26
27
"github.com/go-kit/log"
28
"github.com/grafana/agent/pkg/integrations/v2/autoscrape"
29
"github.com/grafana/agent/pkg/logs"
30
"github.com/grafana/agent/pkg/metrics"
31
"github.com/grafana/agent/pkg/server"
32
"github.com/grafana/agent/pkg/traces"
33
"github.com/prometheus/prometheus/discovery"
34
"github.com/prometheus/prometheus/discovery/targetgroup"
35
)
36
37
var (
38
// ErrInvalidUpdate is returned by ApplyConfig when the config cannot
39
// be dynamically applied.
40
ErrInvalidUpdate = fmt.Errorf("invalid dynamic update")
41
)
42
43
// Config provides a configuration and constructor for an integration.
44
type Config interface {
45
// Name returns the YAML field name of the integration. Name is used
46
// when unmarshaling the Config from YAML.
47
Name() string
48
49
// ApplyDefaults should apply default settings to Config.
50
ApplyDefaults(Globals) error
51
52
// Identifier returns a string to uniquely identify the integration created
53
// by this Config. Identifier must be unique for each integration that shares
54
// the same Name.
55
//
56
// If there is no reasonable identifier to use for an integration,
57
// Globals.AgentIdentifier may be used by default.
58
Identifier(Globals) (string, error)
59
60
// NewIntegration should return a new Integration using the provided
61
// Globals to help initialize the Integration.
62
//
63
// NewIntegration must be idempotent for a Config. Use
64
// Integration.RunIntegration to do anything with side effects, such as
65
// opening a port.
66
NewIntegration(log.Logger, Globals) (Integration, error)
67
}
68
69
// ComparableConfig extends Config with an ConfigEquals method.
70
type ComparableConfig interface {
71
Config
72
73
// ConfigEquals should return true if c is equal to the ComparableConfig.
74
ConfigEquals(c Config) bool
75
}
76
77
// Globals are used to pass around subsystem-wide settings that integrations
78
// can take advantage of.
79
type Globals struct {
80
// AgentIdentifier provides an identifier for the running agent. This can
81
// be used for labelling whenever appropriate.
82
//
83
// AgentIdentifier will be set to the hostname:port of the running agent.
84
// TODO(rfratto): flag to override identifier at agent level?
85
AgentIdentifier string
86
87
// Some integrations may wish to interact with various subsystems for their
88
// implementation if the desired behavior is not supported natively by the
89
// integration manager.
90
91
Metrics *metrics.Agent // Metrics subsystem
92
Logs *logs.Logs // Logs subsystem
93
Tracing *traces.Traces // Traces subsystem
94
95
// Options the integrations subsystem is using.
96
SubsystemOpts SubsystemOptions
97
// BaseURL to use to invoke methods against the embedded HTTP server.
98
AgentBaseURL *url.URL
99
// Dialer to use for making connections. May be nil.
100
DialContextFunc server.DialContextFunc
101
}
102
103
// CloneAgentBaseURL returns a copy of AgentBaseURL that can be modified.
104
func (g Globals) CloneAgentBaseURL() *url.URL {
105
if g.AgentBaseURL == nil {
106
return nil
107
}
108
rawURL := g.AgentBaseURL.String()
109
u, err := url.Parse(rawURL)
110
if err != nil {
111
// The URL shouldn't be invalid at this point
112
panic(err)
113
}
114
return u
115
}
116
117
// An Integration integrates some external system with Grafana Agent's existing
118
// subsystems.
119
//
120
// All integrations must at least implement this interface. More behaviors
121
// can be added by implementing additional *Integration interfaces, such
122
// as HTTPIntegration.
123
type Integration interface {
124
// RunIntegration starts the integration and performs background tasks. It
125
// must not return until ctx is canceled, even if there is no work to do.
126
//
127
// An error will be returned if the integration failed. Integrations will
128
// never return the ctx error.
129
RunIntegration(ctx context.Context) error
130
}
131
132
// UpdateIntegration is an Integration whose config can be updated
133
// dynamically. Integrations that do not implement this interface will be shut
134
// down and re-instantiated with the new Config.
135
type UpdateIntegration interface {
136
Integration
137
138
// ApplyConfig should apply the config c to the integration. An error can be
139
// returned if the Config is invalid. When this happens, the old config will
140
// continue to run.
141
//
142
// If ApplyConfig returns ErrInvalidUpdate, the integration will be
143
// recreated.
144
ApplyConfig(c Config, g Globals) error
145
}
146
147
// HTTPIntegration is an integration that exposes an HTTP handler.
148
//
149
// Integrations are given a unique base path prefix where HTTP requests will be
150
// routed. The prefix chosen for an integration is not guaranteed to be
151
// predictable.
152
type HTTPIntegration interface {
153
Integration
154
155
// Handler returns an http.Handler. Handler will be invoked for any endpoint
156
// under prefix. If Handler returns nil, nothing will be called. Handler
157
// may be called multiple times.
158
//
159
// prefix will not be removed from the HTTP request by default.
160
Handler(prefix string) (http.Handler, error)
161
}
162
163
// MetricsIntegration is an integration that exposes Prometheus scrape targets.
164
//
165
// It is assumed, but not required, that HTTPIntegration is also implemented
166
// to expose metrics. See HTTPIntegration for more information about how
167
// HTTP works with integrations.
168
type MetricsIntegration interface {
169
HTTPIntegration
170
171
// Targets should return the current set of active targets exposed by this
172
// integration. Targets may be called multiple times throughout the lifecycle
173
// of the integration. Targets will not be called when the integration is not
174
// running.
175
//
176
// prefix will be the same prefixed passed to HTTPIntegration.Handler and
177
// can be used to update __metrics_path__ for targets.
178
Targets(ep Endpoint) []*targetgroup.Group
179
180
// ScrapeConfigs configures automatic scraping of targets. ScrapeConfigs
181
// is optional if an integration should not scrape itself.
182
//
183
// Unlike Targets, ScrapeConfigs is only called once per config load, and may be
184
// called before the integration runs. Use the provided discovery.Configs to
185
// discover the targets exposed by this integration.
186
ScrapeConfigs(discovery.Configs) []*autoscrape.ScrapeConfig
187
}
188
189
// Endpoint is a location where something is exposed.
190
type Endpoint struct {
191
// Hostname (and optional port) where endpoint is exposed.
192
Host string
193
// Base prefix of the endpoint.
194
Prefix string
195
}
196
197