Path: blob/main/pkg/integrations/cadvisor/cadvisor.go
5340 views
//go:build linux12package cadvisor //nolint:golint34import (5"context"6"fmt"7"net/http"8"strings"9"time"1011"github.com/go-kit/log"12"github.com/google/cadvisor/cache/memory"13"github.com/google/cadvisor/container"14v2 "github.com/google/cadvisor/info/v2"15"github.com/google/cadvisor/manager"16"github.com/google/cadvisor/metrics"17"github.com/google/cadvisor/storage"18"github.com/google/cadvisor/utils/sysfs"19"k8s.io/klog/v2"20"k8s.io/utils/clock"2122"github.com/grafana/agent/pkg/integrations"2324// Register container providers2526"github.com/google/cadvisor/container/containerd"27_ "github.com/google/cadvisor/container/containerd/install" // register containerd container plugin28_ "github.com/google/cadvisor/container/crio/install" // register crio container plugin29"github.com/google/cadvisor/container/docker"30_ "github.com/google/cadvisor/container/docker/install" // register docker container plugin31"github.com/google/cadvisor/container/raw"32_ "github.com/google/cadvisor/container/systemd/install" // register systemd container plugin33)3435// Matching the default disabled set from cadvisor - https://github.com/google/cadvisor/blob/3c6e3093c5ca65c57368845ddaea2b4ca6bc0da8/cmd/cadvisor.go#L78-L9336// 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.37// var disabledMetrics = *flag.Lookup("disable_metrics").Value.(*container.MetricSet)38var disabledMetrics = container.MetricSet{39container.MemoryNumaMetrics: struct{}{},40container.NetworkTcpUsageMetrics: struct{}{},41container.NetworkUdpUsageMetrics: struct{}{},42container.NetworkAdvancedTcpUsageMetrics: struct{}{},43container.ProcessSchedulerMetrics: struct{}{},44container.ProcessMetrics: struct{}{},45container.HugetlbUsageMetrics: struct{}{},46container.ReferencedMemoryMetrics: struct{}{},47container.CPUTopologyMetrics: struct{}{},48container.ResctrlMetrics: struct{}{},49container.CPUSetMetrics: struct{}{},50}5152// GetIncludedMetrics applies some logic to determine the final set of metrics to be scraped and returned by the cAdvisor integration53func (c *Config) GetIncludedMetrics() (container.MetricSet, error) {54var enabledMetrics, includedMetrics container.MetricSet5556if c.DisabledMetrics != nil {57if err := disabledMetrics.Set(strings.Join(c.DisabledMetrics, ",")); err != nil {58return includedMetrics, fmt.Errorf("failed to set disabled metrics: %w", err)59}60}6162if c.EnabledMetrics != nil {63if err := enabledMetrics.Set(strings.Join(c.EnabledMetrics, ",")); err != nil {64return includedMetrics, fmt.Errorf("failed to set enabled metrics: %w", err)65}66}6768if len(enabledMetrics) > 0 {69includedMetrics = enabledMetrics70} else {71includedMetrics = container.AllMetrics.Difference(disabledMetrics)72}7374return includedMetrics, nil75}7677// NewIntegration creates a new cadvisor integration78func (c *Config) NewIntegration(logger log.Logger) (integrations.Integration, error) {79return New(logger, c)80}8182// Integration implements the cadvisor integration83type Integration struct {84c *Config85i *integrations.CollectorIntegration86}8788// Run holds all the configuration logic for globals, as well as starting the resource manager and registering the collectors with the collector integration89func (i *Integration) Run(ctx context.Context) error {90// Do gross global configs. This works, so long as there is only one instance of the cAdvisor integration91// per host.9293// klog94klog.SetLogger(i.c.logger)9596// Containerd97containerd.ArgContainerdEndpoint = &i.c.Containerd98containerd.ArgContainerdNamespace = &i.c.ContainerdNamespace99100// Docker101docker.ArgDockerEndpoint = &i.c.Docker102docker.ArgDockerTLS = &i.c.DockerTLS103docker.ArgDockerCert = &i.c.DockerTLSCert104docker.ArgDockerKey = &i.c.DockerTLSKey105docker.ArgDockerCA = &i.c.DockerTLSCA106107// Raw108raw.DockerOnly = &i.c.DockerOnly109110// Only using in-memory storage, with no backup storage for cadvisor stats111memoryStorage := memory.New(i.c.StorageDuration, []storage.StorageDriver{})112113sysFs := sysfs.NewRealSysFs()114115var collectorHTTPClient http.Client116117includedMetrics, err := i.c.GetIncludedMetrics()118if err != nil {119return fmt.Errorf("unable to determine included metrics: %w", err)120}121122rm, err := manager.New(memoryStorage, sysFs, manager.HousekeepingConfigFlags, includedMetrics, &collectorHTTPClient, i.c.RawCgroupPrefixAllowlist, i.c.EnvMetadataAllowlist, i.c.PerfEventsConfig, time.Duration(i.c.ResctrlInterval))123if err != nil {124return fmt.Errorf("failed to create a manager: %w", err)125}126127if err := rm.Start(); err != nil {128return fmt.Errorf("failed to start manager: %w", err)129}130131containerLabelFunc := metrics.DefaultContainerLabels132if !i.c.StoreContainerLabels {133containerLabelFunc = metrics.BaseContainerLabels(i.c.AllowlistedContainerLabels)134}135136machCol := metrics.NewPrometheusMachineCollector(rm, includedMetrics)137// This is really just a concatenation of the defaults found at;138// https://github.com/google/cadvisor/tree/f89291a53b80b2c3659fff8954c11f1fc3de8a3b/cmd/internal/api/versions.go#L536-L540139// https://github.com/google/cadvisor/tree/f89291a53b80b2c3659fff8954c11f1fc3de8a3b/cmd/internal/http/handlers.go#L109-L110140// AFAIK all we are ever doing is the "default" metrics request, and we don't need to support the "docker" request type.141reqOpts := v2.RequestOptions{142IdType: v2.TypeName,143Count: 1,144Recursive: true,145}146contCol := metrics.NewPrometheusCollector(rm, containerLabelFunc, includedMetrics, clock.RealClock{}, reqOpts)147integrations.WithCollectors(machCol, contCol)(i.i)148149<-ctx.Done()150151if err := rm.Stop(); err != nil {152return fmt.Errorf("failed to stop manager: %w", err)153}154return nil155}156157// New creates a new cadvisor integration158func New(logger log.Logger, c *Config) (integrations.Integration, error) {159c.logger = logger160161ci := integrations.NewCollectorIntegration(c.Name())162integration := Integration{163c: c,164i: ci,165}166integrations.WithRunner(integration.Run)(ci)167return ci, nil168}169170171