Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/pkg/integrations/node_exporter/config.go
5304 views
1
package node_exporter //nolint:golint
2
3
import (
4
"fmt"
5
"os"
6
"runtime"
7
"strings"
8
"time"
9
10
"github.com/go-kit/log"
11
"github.com/grafana/agent/pkg/integrations"
12
integrations_v2 "github.com/grafana/agent/pkg/integrations/v2"
13
"github.com/grafana/agent/pkg/integrations/v2/metricsutils"
14
"github.com/grafana/dskit/flagext"
15
"github.com/prometheus/procfs"
16
"gopkg.in/alecthomas/kingpin.v2"
17
)
18
19
var (
20
// DefaultConfig holds non-zero default options for the Config when it is
21
// unmarshaled from YAML.
22
//
23
// DefaultConfig's defaults are populated from init functions in this package.
24
// See the init function here and in node_exporter_linux.go.
25
DefaultConfig = Config{
26
ProcFSPath: procfs.DefaultMountPoint,
27
RootFSPath: "/",
28
29
DiskStatsDeviceExclude: "^(ram|loop|fd|(h|s|v|xv)d[a-z]|nvme\\d+n\\d+p)\\d+$",
30
31
EthtoolMetricsInclude: ".*",
32
33
FilesystemMountTimeout: 5 * time.Second,
34
35
NTPIPTTL: 1,
36
NTPLocalOffsetTolerance: time.Millisecond,
37
NTPMaxDistance: time.Microsecond * 3466080,
38
NTPProtocolVersion: 4,
39
NTPServer: "127.0.0.1",
40
41
NetclassIgnoredDevices: "^$",
42
NetstatFields: "^(.*_(InErrors|InErrs)|Ip_Forwarding|Ip(6|Ext)_(InOctets|OutOctets)|Icmp6?_(InMsgs|OutMsgs)|TcpExt_(Listen.*|Syncookies.*|TCPSynRetrans|TCPTimeouts)|Tcp_(ActiveOpens|InSegs|OutSegs|OutRsts|PassiveOpens|RetransSegs|CurrEstab)|Udp6?_(InDatagrams|OutDatagrams|NoPorts|RcvbufErrors|SndbufErrors))$",
43
44
PowersupplyIgnoredSupplies: "^$",
45
46
RunitServiceDir: "/etc/service",
47
48
SupervisordURL: "http://localhost:9001/RPC2",
49
50
SystemdUnitExclude: ".+\\.(automount|device|mount|scope|slice)",
51
SystemdUnitInclude: ".+",
52
53
TapestatsIgnoredDevices: "^$",
54
55
VMStatFields: "^(oom_kill|pgpg|pswp|pg.*fault).*",
56
}
57
)
58
59
func init() {
60
// The default values for the filesystem collector are to ignore everything,
61
// but some platforms have specific defaults. We'll fill these in below at
62
// initialization time, but the values can still be overridden via the config
63
// file.
64
switch runtime.GOOS {
65
case "linux":
66
DefaultConfig.FilesystemMountPointsExclude = "^/(dev|proc|run/credentials/.+|sys|var/lib/docker/.+)($|/)"
67
DefaultConfig.FilesystemFSTypesExclude = "^(autofs|binfmt_misc|bpf|cgroup2?|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|iso9660|mqueue|nsfs|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|selinuxfs|squashfs|sysfs|tracefs)$"
68
case "darwin":
69
DefaultConfig.FilesystemMountPointsExclude = "^/(dev)($|/)"
70
DefaultConfig.FilesystemFSTypesExclude = "^(autofs|devfs)$"
71
case "freebsd", "netbsd", "openbsd":
72
DefaultConfig.FilesystemMountPointsExclude = "^/(dev)($|/)"
73
DefaultConfig.FilesystemFSTypesExclude = "^devfs$"
74
}
75
76
if url := os.Getenv("SUPERVISORD_URL"); url != "" {
77
DefaultConfig.SupervisordURL = url
78
}
79
}
80
81
// Config controls the node_exporter integration.
82
type Config struct {
83
IncludeExporterMetrics bool `yaml:"include_exporter_metrics,omitempty"`
84
85
ProcFSPath string `yaml:"procfs_path,omitempty"`
86
SysFSPath string `yaml:"sysfs_path,omitempty"`
87
RootFSPath string `yaml:"rootfs_path,omitempty"`
88
89
// Collectors to mark as enabled
90
EnableCollectors flagext.StringSlice `yaml:"enable_collectors,omitempty"`
91
92
// Collectors to mark as disabled
93
DisableCollectors flagext.StringSlice `yaml:"disable_collectors,omitempty"`
94
95
// Overrides the default set of enabled collectors with the collectors
96
// listed.
97
SetCollectors flagext.StringSlice `yaml:"set_collectors,omitempty"`
98
99
// Collector-specific config options
100
BcachePriorityStats bool `yaml:"enable_bcache_priority_stats,omitempty"`
101
CPUBugsInclude string `yaml:"cpu_bugs_include,omitempty"`
102
CPUEnableCPUGuest bool `yaml:"enable_cpu_guest_seconds_metric,omitempty"`
103
CPUEnableCPUInfo bool `yaml:"enable_cpu_info_metric,omitempty"`
104
CPUFlagsInclude string `yaml:"cpu_flags_include,omitempty"`
105
DiskStatsDeviceExclude string `yaml:"diskstats_device_exclude,omitempty"`
106
DiskStatsDeviceInclude string `yaml:"diskstats_device_include,omitempty"`
107
EthtoolDeviceExclude string `yaml:"ethtool_device_exclude,omitempty"`
108
EthtoolDeviceInclude string `yaml:"ethtool_device_include,omitempty"`
109
EthtoolMetricsInclude string `yaml:"ethtool_metrics_include,omitempty"`
110
FilesystemFSTypesExclude string `yaml:"filesystem_fs_types_exclude,omitempty"`
111
FilesystemMountPointsExclude string `yaml:"filesystem_mount_points_exclude,omitempty"`
112
FilesystemMountTimeout time.Duration `yaml:"filesystem_mount_timeout,omitempty"`
113
IPVSBackendLabels []string `yaml:"ipvs_backend_labels,omitempty"`
114
NTPIPTTL int `yaml:"ntp_ip_ttl,omitempty"`
115
NTPLocalOffsetTolerance time.Duration `yaml:"ntp_local_offset_tolerance,omitempty"`
116
NTPMaxDistance time.Duration `yaml:"ntp_max_distance,omitempty"`
117
NTPProtocolVersion int `yaml:"ntp_protocol_version,omitempty"`
118
NTPServer string `yaml:"ntp_server,omitempty"`
119
NTPServerIsLocal bool `yaml:"ntp_server_is_local,omitempty"`
120
NetclassIgnoreInvalidSpeedDevice bool `yaml:"netclass_ignore_invalid_speed_device,omitempty"`
121
NetclassIgnoredDevices string `yaml:"netclass_ignored_devices,omitempty"`
122
NetdevAddressInfo bool `yaml:"netdev_address_info,omitempty"`
123
NetdevDeviceExclude string `yaml:"netdev_device_exclude,omitempty"`
124
NetdevDeviceInclude string `yaml:"netdev_device_include,omitempty"`
125
NetstatFields string `yaml:"netstat_fields,omitempty"`
126
PerfCPUS string `yaml:"perf_cpus,omitempty"`
127
PerfTracepoint flagext.StringSlice `yaml:"perf_tracepoint,omitempty"`
128
PowersupplyIgnoredSupplies string `yaml:"powersupply_ignored_supplies,omitempty"`
129
RunitServiceDir string `yaml:"runit_service_dir,omitempty"`
130
SupervisordURL string `yaml:"supervisord_url,omitempty"`
131
SysctlInclude flagext.StringSlice `yaml:"sysctl_include,omitempty"`
132
SysctlIncludeInfo flagext.StringSlice `yaml:"sysctl_include_info,omitempty"`
133
SystemdEnableRestartsMetrics bool `yaml:"systemd_enable_restarts_metrics,omitempty"`
134
SystemdEnableStartTimeMetrics bool `yaml:"systemd_enable_start_time_metrics,omitempty"`
135
SystemdEnableTaskMetrics bool `yaml:"systemd_enable_task_metrics,omitempty"`
136
SystemdUnitExclude string `yaml:"systemd_unit_exclude,omitempty"`
137
SystemdUnitInclude string `yaml:"systemd_unit_include,omitempty"`
138
TapestatsIgnoredDevices string `yaml:"tapestats_ignored_devices,omitempty"`
139
TextfileDirectory string `yaml:"textfile_directory,omitempty"`
140
VMStatFields string `yaml:"vmstat_fields,omitempty"`
141
142
UnmarshalWarnings []string `yaml:"-"`
143
}
144
145
// UnmarshalYAML implements yaml.Unmarshaler for Config.
146
func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error {
147
*c = DefaultConfig
148
149
type baseConfig Config
150
type config struct {
151
baseConfig `yaml:",inline"`
152
153
// Deprecated field names:
154
NetdevDeviceWhitelist string `yaml:"netdev_device_whitelist,omitempty"`
155
NetdevDeviceBlacklist string `yaml:"netdev_device_blacklist,omitempty"`
156
SystemdUnitWhitelist string `yaml:"systemd_unit_whitelist,omitempty"`
157
SystemdUnitBlacklist string `yaml:"systemd_unit_blacklist,omitempty"`
158
FilesystemIgnoredMountPoints string `yaml:"filesystem_ignored_mount_points,omitempty"`
159
FilesystemIgnoredFSTypes string `yaml:"filesystem_ignored_fs_types,omitempty"`
160
DiskStatsIgnoredDevices string `yaml:"diskstats_ignored_devices,omitempty"`
161
}
162
163
var fc config // our full config (schema + deprecated names)
164
fc.baseConfig = baseConfig(*c)
165
166
type migratedField struct {
167
OldName, NewName string
168
OldValue, NewValue *string
169
170
defaultValue string
171
}
172
migratedFields := []*migratedField{
173
{
174
OldName: "netdev_device_whitelist", NewName: "netdev_device_include",
175
OldValue: &fc.NetdevDeviceWhitelist, NewValue: &fc.NetdevDeviceInclude,
176
},
177
{
178
OldName: "netdev_device_blacklist", NewName: "netdev_device_exclude",
179
OldValue: &fc.NetdevDeviceBlacklist, NewValue: &fc.NetdevDeviceExclude,
180
},
181
{
182
OldName: "systemd_unit_whitelist", NewName: "systemd_unit_include",
183
OldValue: &fc.SystemdUnitWhitelist, NewValue: &fc.SystemdUnitInclude,
184
},
185
{
186
OldName: "systemd_unit_blacklist", NewName: "systemd_unit_exclude",
187
OldValue: &fc.SystemdUnitBlacklist, NewValue: &fc.SystemdUnitExclude,
188
},
189
{
190
OldName: "filesystem_ignored_mount_points", NewName: "filesystem_mount_points_exclude",
191
OldValue: &fc.FilesystemIgnoredMountPoints, NewValue: &fc.FilesystemMountPointsExclude,
192
},
193
{
194
OldName: "filesystem_ignored_fs_types", NewName: "filesystem_fs_types_exclude",
195
OldValue: &fc.FilesystemIgnoredFSTypes, NewValue: &fc.FilesystemFSTypesExclude,
196
},
197
{
198
OldName: "diskstats_ignored_devices", NewName: "diskstats_device_exclude",
199
OldValue: &fc.DiskStatsIgnoredDevices, NewValue: &fc.DiskStatsDeviceExclude,
200
},
201
}
202
203
// We don't know when fields are unmarshaled unless they have non-zero
204
// values. Defaults stop us from being able to check, so we'll temporarily
205
// cache the default and make sure both the old and new migrated fields are
206
// zero.
207
for _, mf := range migratedFields {
208
mf.defaultValue = *mf.NewValue
209
*mf.NewValue = ""
210
}
211
212
if err := unmarshal(&fc); err != nil {
213
return err
214
}
215
216
for _, mf := range migratedFields {
217
switch {
218
case *mf.OldValue != "" && *mf.NewValue != "": // New set, old set
219
return fmt.Errorf("only one of %q and %q may be specified", mf.OldName, mf.NewName)
220
221
case *mf.NewValue == "" && *mf.OldValue != "": // New unset, old set
222
*mf.NewValue = *mf.OldValue
223
224
warning := fmt.Sprintf("%q is deprecated by %q and will be removed in a future version", mf.OldName, mf.NewName)
225
fc.UnmarshalWarnings = append(fc.UnmarshalWarnings, warning)
226
227
case *mf.NewValue == "" && *mf.OldValue == "": // Neither set.
228
// Copy the default back to mf.NewValue.
229
*mf.NewValue = mf.defaultValue
230
231
case *mf.NewValue != "" && *mf.OldValue == "": // New set, old unset
232
// Nothing to do
233
}
234
}
235
236
*c = (Config)(fc.baseConfig)
237
return nil
238
}
239
240
// Name returns the name of the integration that this config represents.
241
func (c *Config) Name() string {
242
return "node_exporter"
243
}
244
245
// InstanceKey returns the hostname:port of the agent process.
246
func (c *Config) InstanceKey(agentKey string) (string, error) {
247
return agentKey, nil
248
}
249
250
// NewIntegration converts this config into an instance of an integration.
251
func (c *Config) NewIntegration(l log.Logger) (integrations.Integration, error) {
252
return New(l, c)
253
}
254
255
func init() {
256
integrations.RegisterIntegration(&Config{})
257
integrations_v2.RegisterLegacy(&Config{}, integrations_v2.TypeSingleton, metricsutils.Shim)
258
}
259
260
// MapConfigToNodeExporterFlags takes in a node_exporter Config and converts
261
// it to the set of flags that node_exporter usually expects when running as a
262
// separate binary.
263
func MapConfigToNodeExporterFlags(c *Config) (accepted []string, ignored []string) {
264
collectors := make(map[string]CollectorState, len(Collectors))
265
for k, v := range Collectors {
266
collectors[k] = v
267
}
268
269
// Override the set of defaults with the provided set of collectors if
270
// set_collectors has at least one element in it.
271
if len(c.SetCollectors) != 0 {
272
customDefaults := map[string]struct{}{}
273
for _, c := range c.SetCollectors {
274
customDefaults[c] = struct{}{}
275
}
276
277
for k := range collectors {
278
_, shouldEnable := customDefaults[k]
279
if shouldEnable {
280
collectors[k] = CollectorStateEnabled
281
} else {
282
collectors[k] = CollectorStateDisabled
283
}
284
}
285
}
286
287
// Explicitly disable/enable specific collectors
288
for _, c := range c.DisableCollectors {
289
collectors[c] = CollectorStateDisabled
290
}
291
for _, c := range c.EnableCollectors {
292
collectors[c] = CollectorStateEnabled
293
}
294
295
DisableUnavailableCollectors(collectors)
296
297
var flags flags
298
flags.accepted = append(flags.accepted, MapCollectorsToFlags(collectors)...)
299
300
flags.add(
301
"--path.procfs", c.ProcFSPath,
302
"--path.sysfs", c.SysFSPath,
303
"--path.rootfs", c.RootFSPath,
304
)
305
306
if collectors[CollectorBCache] {
307
flags.addBools(map[*bool]string{
308
&c.BcachePriorityStats: "collector.bcache.priorityStats",
309
})
310
}
311
312
if collectors[CollectorCPU] {
313
flags.addBools(map[*bool]string{
314
&c.CPUEnableCPUGuest: "collector.cpu.guest",
315
&c.CPUEnableCPUInfo: "collector.cpu.info",
316
})
317
flags.add("--collector.cpu.info.flags-include", c.CPUFlagsInclude)
318
flags.add("--collector.cpu.info.bugs-include", c.CPUBugsInclude)
319
}
320
321
if collectors[CollectorDiskstats] {
322
if c.DiskStatsDeviceInclude != "" {
323
flags.add("--collector.diskstats.device-include", c.DiskStatsDeviceInclude)
324
} else {
325
flags.add("--collector.diskstats.device-exclude", c.DiskStatsDeviceExclude)
326
}
327
}
328
329
if collectors[CollectorEthtool] {
330
flags.add("--collector.ethtool.device-include", c.EthtoolDeviceInclude)
331
flags.add("--collector.ethtool.device-exclude", c.EthtoolDeviceExclude)
332
flags.add("--collector.ethtool.metrics-include", c.EthtoolMetricsInclude)
333
}
334
335
if collectors[CollectorFilesystem] {
336
flags.add(
337
"--collector.filesystem.mount-timeout", c.FilesystemMountTimeout.String(),
338
"--collector.filesystem.mount-points-exclude", c.FilesystemMountPointsExclude,
339
"--collector.filesystem.fs-types-exclude", c.FilesystemFSTypesExclude,
340
)
341
}
342
343
if collectors[CollectorIPVS] {
344
flags.add("--collector.ipvs.backend-labels", strings.Join(c.IPVSBackendLabels, ","))
345
}
346
347
if collectors[CollectorNetclass] {
348
flags.addBools(map[*bool]string{
349
&c.NetclassIgnoreInvalidSpeedDevice: "collector.netclass.ignore-invalid-speed",
350
})
351
352
flags.add("--collector.netclass.ignored-devices", c.NetclassIgnoredDevices)
353
}
354
355
if collectors[CollectorNetdev] {
356
flags.addBools(map[*bool]string{
357
&c.NetdevAddressInfo: "collector.netdev.address-info",
358
})
359
360
flags.add(
361
"--collector.netdev.device-include", c.NetdevDeviceInclude,
362
"--collector.netdev.device-exclude", c.NetdevDeviceExclude,
363
)
364
}
365
366
if collectors[CollectorNetstat] {
367
flags.add("--collector.netstat.fields", c.NetstatFields)
368
}
369
370
if collectors[CollectorNTP] {
371
flags.add(
372
"--collector.ntp.server", c.NTPServer,
373
"--collector.ntp.protocol-version", fmt.Sprintf("%d", c.NTPProtocolVersion),
374
"--collector.ntp.ip-ttl", fmt.Sprintf("%d", c.NTPIPTTL),
375
"--collector.ntp.max-distance", c.NTPMaxDistance.String(),
376
"--collector.ntp.local-offset-tolerance", c.NTPLocalOffsetTolerance.String(),
377
)
378
379
flags.addBools(map[*bool]string{
380
&c.NTPServerIsLocal: "collector.ntp.server-is-local",
381
})
382
}
383
384
if collectors[CollectorPerf] {
385
flags.add("--collector.perf.cpus", c.PerfCPUS)
386
387
for _, tp := range c.PerfTracepoint {
388
flags.add("--collector.perf.tracepoint", tp)
389
}
390
}
391
392
if collectors[CollectorPowersuppply] {
393
flags.add("--collector.powersupply.ignored-supplies", c.PowersupplyIgnoredSupplies)
394
}
395
396
if collectors[CollectorRunit] {
397
flags.add("--collector.runit.servicedir", c.RunitServiceDir)
398
}
399
400
if collectors[CollectorSupervisord] {
401
flags.add("--collector.supervisord.url", c.SupervisordURL)
402
}
403
404
if collectors[CollectorSysctl] {
405
for _, numValue := range c.SysctlInclude {
406
flags.add("--collector.sysctl.include", numValue)
407
}
408
409
for _, stringValue := range c.SysctlIncludeInfo {
410
flags.add("--collector.sysctl.include-info", stringValue)
411
}
412
}
413
414
if collectors[CollectorSystemd] {
415
flags.add(
416
"--collector.systemd.unit-include", c.SystemdUnitInclude,
417
"--collector.systemd.unit-exclude", c.SystemdUnitExclude,
418
)
419
420
flags.addBools(map[*bool]string{
421
&c.SystemdEnableTaskMetrics: "collector.systemd.enable-task-metrics",
422
&c.SystemdEnableRestartsMetrics: "collector.systemd.enable-restarts-metrics",
423
&c.SystemdEnableStartTimeMetrics: "collector.systemd.enable-start-time-metrics",
424
})
425
}
426
427
if collectors[CollectorTapestats] {
428
flags.add("--collector.tapestats.ignored-devices", c.TapestatsIgnoredDevices)
429
}
430
431
if collectors[CollectorTextfile] {
432
flags.add("--collector.textfile.directory", c.TextfileDirectory)
433
}
434
435
if collectors[CollectorVMStat] {
436
flags.add("--collector.vmstat.fields", c.VMStatFields)
437
}
438
439
return flags.accepted, flags.ignored
440
}
441
442
type flags struct {
443
accepted []string
444
ignored []string
445
}
446
447
// add pushes new flags as key value pairs. If the flag isn't registered with kingpin,
448
// it will be ignored.
449
func (f *flags) add(kvp ...string) {
450
if (len(kvp) % 2) != 0 {
451
panic("missing value for added flag")
452
}
453
454
for i := 0; i < len(kvp); i += 2 {
455
key := kvp[i+0]
456
value := kvp[i+1]
457
458
rawFlag := strings.TrimPrefix(key, "--")
459
if kingpin.CommandLine.GetFlag(rawFlag) == nil {
460
f.ignored = append(f.ignored, rawFlag)
461
continue
462
}
463
464
f.accepted = append(f.accepted, key, value)
465
}
466
}
467
468
func (f *flags) addBools(m map[*bool]string) {
469
for setting, key := range m {
470
// The flag might not exist on this platform, so skip it if it's not
471
// defined.
472
if kingpin.CommandLine.GetFlag(key) == nil {
473
f.ignored = append(f.ignored, key)
474
continue
475
}
476
477
if *setting {
478
f.accepted = append(f.accepted, "--"+key)
479
} else {
480
f.accepted = append(f.accepted, "--no-"+key)
481
}
482
}
483
}
484
485