Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/pkg/integrations/cadvisor/cadvisor.go
5340 views
1
//go:build linux
2
3
package cadvisor //nolint:golint
4
5
import (
6
"context"
7
"fmt"
8
"net/http"
9
"strings"
10
"time"
11
12
"github.com/go-kit/log"
13
"github.com/google/cadvisor/cache/memory"
14
"github.com/google/cadvisor/container"
15
v2 "github.com/google/cadvisor/info/v2"
16
"github.com/google/cadvisor/manager"
17
"github.com/google/cadvisor/metrics"
18
"github.com/google/cadvisor/storage"
19
"github.com/google/cadvisor/utils/sysfs"
20
"k8s.io/klog/v2"
21
"k8s.io/utils/clock"
22
23
"github.com/grafana/agent/pkg/integrations"
24
25
// Register container providers
26
27
"github.com/google/cadvisor/container/containerd"
28
_ "github.com/google/cadvisor/container/containerd/install" // register containerd container plugin
29
_ "github.com/google/cadvisor/container/crio/install" // register crio container plugin
30
"github.com/google/cadvisor/container/docker"
31
_ "github.com/google/cadvisor/container/docker/install" // register docker container plugin
32
"github.com/google/cadvisor/container/raw"
33
_ "github.com/google/cadvisor/container/systemd/install" // register systemd container plugin
34
)
35
36
// Matching the default disabled set from cadvisor - https://github.com/google/cadvisor/blob/3c6e3093c5ca65c57368845ddaea2b4ca6bc0da8/cmd/cadvisor.go#L78-L93
37
// Note: This *could* be kept in sync with upstream by using the following. However, that would require importing the github.com/google/cadvisor/cmd package, which introduces some dependency conflicts that weren't worth the hassle IMHO.
38
// var disabledMetrics = *flag.Lookup("disable_metrics").Value.(*container.MetricSet)
39
var disabledMetrics = container.MetricSet{
40
container.MemoryNumaMetrics: struct{}{},
41
container.NetworkTcpUsageMetrics: struct{}{},
42
container.NetworkUdpUsageMetrics: struct{}{},
43
container.NetworkAdvancedTcpUsageMetrics: struct{}{},
44
container.ProcessSchedulerMetrics: struct{}{},
45
container.ProcessMetrics: struct{}{},
46
container.HugetlbUsageMetrics: struct{}{},
47
container.ReferencedMemoryMetrics: struct{}{},
48
container.CPUTopologyMetrics: struct{}{},
49
container.ResctrlMetrics: struct{}{},
50
container.CPUSetMetrics: struct{}{},
51
}
52
53
// GetIncludedMetrics applies some logic to determine the final set of metrics to be scraped and returned by the cAdvisor integration
54
func (c *Config) GetIncludedMetrics() (container.MetricSet, error) {
55
var enabledMetrics, includedMetrics container.MetricSet
56
57
if c.DisabledMetrics != nil {
58
if err := disabledMetrics.Set(strings.Join(c.DisabledMetrics, ",")); err != nil {
59
return includedMetrics, fmt.Errorf("failed to set disabled metrics: %w", err)
60
}
61
}
62
63
if c.EnabledMetrics != nil {
64
if err := enabledMetrics.Set(strings.Join(c.EnabledMetrics, ",")); err != nil {
65
return includedMetrics, fmt.Errorf("failed to set enabled metrics: %w", err)
66
}
67
}
68
69
if len(enabledMetrics) > 0 {
70
includedMetrics = enabledMetrics
71
} else {
72
includedMetrics = container.AllMetrics.Difference(disabledMetrics)
73
}
74
75
return includedMetrics, nil
76
}
77
78
// NewIntegration creates a new cadvisor integration
79
func (c *Config) NewIntegration(logger log.Logger) (integrations.Integration, error) {
80
return New(logger, c)
81
}
82
83
// Integration implements the cadvisor integration
84
type Integration struct {
85
c *Config
86
i *integrations.CollectorIntegration
87
}
88
89
// Run holds all the configuration logic for globals, as well as starting the resource manager and registering the collectors with the collector integration
90
func (i *Integration) Run(ctx context.Context) error {
91
// Do gross global configs. This works, so long as there is only one instance of the cAdvisor integration
92
// per host.
93
94
// klog
95
klog.SetLogger(i.c.logger)
96
97
// Containerd
98
containerd.ArgContainerdEndpoint = &i.c.Containerd
99
containerd.ArgContainerdNamespace = &i.c.ContainerdNamespace
100
101
// Docker
102
docker.ArgDockerEndpoint = &i.c.Docker
103
docker.ArgDockerTLS = &i.c.DockerTLS
104
docker.ArgDockerCert = &i.c.DockerTLSCert
105
docker.ArgDockerKey = &i.c.DockerTLSKey
106
docker.ArgDockerCA = &i.c.DockerTLSCA
107
108
// Raw
109
raw.DockerOnly = &i.c.DockerOnly
110
111
// Only using in-memory storage, with no backup storage for cadvisor stats
112
memoryStorage := memory.New(i.c.StorageDuration, []storage.StorageDriver{})
113
114
sysFs := sysfs.NewRealSysFs()
115
116
var collectorHTTPClient http.Client
117
118
includedMetrics, err := i.c.GetIncludedMetrics()
119
if err != nil {
120
return fmt.Errorf("unable to determine included metrics: %w", err)
121
}
122
123
rm, err := manager.New(memoryStorage, sysFs, manager.HousekeepingConfigFlags, includedMetrics, &collectorHTTPClient, i.c.RawCgroupPrefixAllowlist, i.c.EnvMetadataAllowlist, i.c.PerfEventsConfig, time.Duration(i.c.ResctrlInterval))
124
if err != nil {
125
return fmt.Errorf("failed to create a manager: %w", err)
126
}
127
128
if err := rm.Start(); err != nil {
129
return fmt.Errorf("failed to start manager: %w", err)
130
}
131
132
containerLabelFunc := metrics.DefaultContainerLabels
133
if !i.c.StoreContainerLabels {
134
containerLabelFunc = metrics.BaseContainerLabels(i.c.AllowlistedContainerLabels)
135
}
136
137
machCol := metrics.NewPrometheusMachineCollector(rm, includedMetrics)
138
// This is really just a concatenation of the defaults found at;
139
// https://github.com/google/cadvisor/tree/f89291a53b80b2c3659fff8954c11f1fc3de8a3b/cmd/internal/api/versions.go#L536-L540
140
// https://github.com/google/cadvisor/tree/f89291a53b80b2c3659fff8954c11f1fc3de8a3b/cmd/internal/http/handlers.go#L109-L110
141
// AFAIK all we are ever doing is the "default" metrics request, and we don't need to support the "docker" request type.
142
reqOpts := v2.RequestOptions{
143
IdType: v2.TypeName,
144
Count: 1,
145
Recursive: true,
146
}
147
contCol := metrics.NewPrometheusCollector(rm, containerLabelFunc, includedMetrics, clock.RealClock{}, reqOpts)
148
integrations.WithCollectors(machCol, contCol)(i.i)
149
150
<-ctx.Done()
151
152
if err := rm.Stop(); err != nil {
153
return fmt.Errorf("failed to stop manager: %w", err)
154
}
155
return nil
156
}
157
158
// New creates a new cadvisor integration
159
func New(logger log.Logger, c *Config) (integrations.Integration, error) {
160
c.logger = logger
161
162
ci := integrations.NewCollectorIntegration(c.Name())
163
integration := Integration{
164
c: c,
165
i: ci,
166
}
167
integrations.WithRunner(integration.Run)(ci)
168
return ci, nil
169
}
170
171