Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/pkg/config/integrations.go
4094 views
1
package config
2
3
import (
4
"fmt"
5
"reflect"
6
7
"github.com/go-kit/log"
8
"github.com/gorilla/mux"
9
v1 "github.com/grafana/agent/pkg/integrations"
10
v2 "github.com/grafana/agent/pkg/integrations/v2"
11
"github.com/grafana/agent/pkg/metrics"
12
"github.com/grafana/agent/pkg/server"
13
"github.com/grafana/agent/pkg/util"
14
"github.com/prometheus/statsd_exporter/pkg/level"
15
"golang.org/x/exp/maps"
16
"gopkg.in/yaml.v2"
17
)
18
19
type integrationsVersion int
20
21
const (
22
integrationsVersion1 integrationsVersion = iota
23
integrationsVersion2
24
)
25
26
// DefaultVersionedIntegrations is the default config for integrations.
27
func DefaultVersionedIntegrations() VersionedIntegrations {
28
configV1 := v1.DefaultManagerConfig()
29
return VersionedIntegrations{
30
version: integrationsVersion1,
31
configV1: &configV1,
32
}
33
}
34
35
// VersionedIntegrations abstracts the subsystem configs for integrations v1
36
// and v2. VersionedIntegrations can only be unmarshaled as part of Load.
37
type VersionedIntegrations struct {
38
version integrationsVersion
39
raw util.RawYAML
40
41
configV1 *v1.ManagerConfig
42
configV2 *v2.SubsystemOptions
43
44
// ExtraIntegrations is used when adding any integrations NOT in the default agent configuration
45
ExtraIntegrations []v2.Config
46
}
47
48
var (
49
_ yaml.Unmarshaler = (*VersionedIntegrations)(nil)
50
_ yaml.Marshaler = (*VersionedIntegrations)(nil)
51
)
52
53
// UnmarshalYAML implements yaml.Unmarshaler. Full unmarshaling is deferred until
54
// setVersion is invoked.
55
func (c *VersionedIntegrations) UnmarshalYAML(unmarshal func(interface{}) error) error {
56
c.configV1 = nil
57
c.configV2 = nil
58
return unmarshal(&c.raw)
59
}
60
61
// MarshalYAML implements yaml.Marshaler.
62
func (c VersionedIntegrations) MarshalYAML() (interface{}, error) {
63
switch {
64
case c.configV1 != nil:
65
return c.configV1, nil
66
case c.configV2 != nil:
67
return c.configV2, nil
68
default:
69
// A pointer is needed for the yaml.Marshaler implementation to work.
70
return &c.raw, nil
71
}
72
}
73
74
// IsZero implements yaml.IsZeroer.
75
func (c VersionedIntegrations) IsZero() bool {
76
switch {
77
case c.configV1 != nil:
78
return reflect.ValueOf(*c.configV1).IsZero()
79
case c.configV2 != nil:
80
return reflect.ValueOf(*c.configV2).IsZero()
81
default:
82
return len(c.raw) == 0
83
}
84
}
85
86
// ApplyDefaults applies defaults to the subsystem based on globals.
87
func (c *VersionedIntegrations) ApplyDefaults(sflags *server.Flags, mcfg *metrics.Config) error {
88
if c.version != integrationsVersion2 {
89
return c.configV1.ApplyDefaults(sflags, mcfg)
90
}
91
return c.configV2.ApplyDefaults(mcfg)
92
}
93
94
// setVersion completes the deferred unmarshal and unmarshals the raw YAML into
95
// the subsystem config for version v.
96
func (c *VersionedIntegrations) setVersion(v integrationsVersion) error {
97
c.version = v
98
99
switch c.version {
100
case integrationsVersion1:
101
// Do not overwrite the config if it's already been set. This is relevant for
102
// cases where the config has already been loaded via other means (example: Agent
103
// Management snippets).
104
if c.configV1 != nil {
105
return nil
106
}
107
108
cfg := v1.DefaultManagerConfig()
109
c.configV1 = &cfg
110
return yaml.UnmarshalStrict(c.raw, c.configV1)
111
case integrationsVersion2:
112
cfg := v2.DefaultSubsystemOptions
113
// this is needed for dynamic configuration, the unmarshal doesn't work correctly if
114
// this is not nil.
115
c.configV1 = nil
116
c.configV2 = &cfg
117
err := yaml.UnmarshalStrict(c.raw, c.configV2)
118
if err != nil {
119
return err
120
}
121
c.configV2.Configs = append(c.configV2.Configs, c.ExtraIntegrations...)
122
return nil
123
default:
124
panic(fmt.Sprintf("unknown integrations version %d", c.version))
125
}
126
}
127
128
// EnabledIntegrations returns a slice of enabled integrations
129
func (c *VersionedIntegrations) EnabledIntegrations() []string {
130
integrations := map[string]struct{}{}
131
if c.configV1 != nil {
132
for _, integration := range c.configV1.Integrations {
133
integrations[integration.Name()] = struct{}{}
134
}
135
}
136
if c.configV2 != nil {
137
for _, integration := range c.configV2.Configs {
138
integrations[integration.Name()] = struct{}{}
139
}
140
}
141
return maps.Keys(integrations)
142
}
143
144
// IntegrationsGlobals is a global struct shared across integrations.
145
type IntegrationsGlobals = v2.Globals
146
147
// Integrations is an abstraction over both the v1 and v2 systems.
148
type Integrations interface {
149
ApplyConfig(*VersionedIntegrations, IntegrationsGlobals) error
150
WireAPI(*mux.Router)
151
Stop()
152
}
153
154
// NewIntegrations creates a new subsystem. globals should be provided regardless
155
// of useV2. globals.SubsystemOptions will be automatically set if cfg.Version
156
// is set to IntegrationsVersion2.
157
func NewIntegrations(logger log.Logger, cfg *VersionedIntegrations, globals IntegrationsGlobals) (Integrations, error) {
158
if cfg.version != integrationsVersion2 {
159
instance, err := v1.NewManager(*cfg.configV1, logger, globals.Metrics.InstanceManager(), globals.Metrics.Validate)
160
if err != nil {
161
return nil, err
162
}
163
return &v1Integrations{Manager: instance}, nil
164
}
165
166
level.Warn(logger).Log("msg", "integrations-next is enabled. integrations-next is subject to change")
167
168
globals.SubsystemOpts = *cfg.configV2
169
instance, err := v2.NewSubsystem(logger, globals)
170
if err != nil {
171
return nil, err
172
}
173
return &v2Integrations{Subsystem: instance}, nil
174
}
175
176
type v1Integrations struct{ *v1.Manager }
177
178
func (s *v1Integrations) ApplyConfig(cfg *VersionedIntegrations, _ IntegrationsGlobals) error {
179
return s.Manager.ApplyConfig(*cfg.configV1)
180
}
181
182
type v2Integrations struct{ *v2.Subsystem }
183
184
func (s *v2Integrations) ApplyConfig(cfg *VersionedIntegrations, globals IntegrationsGlobals) error {
185
globals.SubsystemOpts = *cfg.configV2
186
return s.Subsystem.ApplyConfig(globals)
187
}
188
189