Path: blob/main/pkg/integrations/collector_integration.go
5363 views
package integrations12import (3"context"4"fmt"5"net/http"67"github.com/grafana/agent/pkg/build"8"github.com/grafana/agent/pkg/integrations/config"9"github.com/prometheus/client_golang/prometheus"10"github.com/prometheus/client_golang/prometheus/promhttp"11)1213// CollectorIntegration is an integration exposing metrics from one or more Prometheus collectors.14type CollectorIntegration struct {15name string16cs []prometheus.Collector17includeExporterMetrics bool18runner func(context.Context) error19}2021// NewCollectorIntegration creates a basic integration that exposes metrics from multiple prometheus.Collector.22func NewCollectorIntegration(name string, configs ...CollectorIntegrationConfig) *CollectorIntegration {23i := &CollectorIntegration{24name: name,25runner: func(ctx context.Context) error {26// We don't need to do anything by default, so we can just wait for the context to finish.27<-ctx.Done()28return ctx.Err()29},30}31for _, configure := range configs {32configure(i)33}34return i35}3637// CollectorIntegrationConfig defines constructor configuration for NewCollectorIntegration38type CollectorIntegrationConfig func(integration *CollectorIntegration)3940// WithCollectors adds more collectors to the CollectorIntegration being created.41func WithCollectors(cs ...prometheus.Collector) CollectorIntegrationConfig {42return func(i *CollectorIntegration) {43i.cs = append(i.cs, cs...)44}45}4647// WithRunner replaces the runner of the CollectorIntegration.48// The runner function should run while the context provided is not done.49func WithRunner(runner func(context.Context) error) CollectorIntegrationConfig {50return func(i *CollectorIntegration) {51i.runner = runner52}53}5455// WithExporterMetricsIncluded can enable the exporter metrics if the flag provided is enabled.56func WithExporterMetricsIncluded(included bool) CollectorIntegrationConfig {57return func(i *CollectorIntegration) {58i.includeExporterMetrics = included59}60}6162// MetricsHandler returns the HTTP handler for the integration.63func (i *CollectorIntegration) MetricsHandler() (http.Handler, error) {64r := prometheus.NewRegistry()65for _, c := range i.cs {66if err := r.Register(c); err != nil {67return nil, fmt.Errorf("couldn't register %s: %w", i.name, err)68}69}7071// Register <integration name>_build_info metrics, generally useful for72// dashboards that depend on them for discovering targets.73if err := r.Register(build.NewCollector(i.name)); err != nil {74return nil, fmt.Errorf("couldn't register %s: %w", i.name, err)75}7677handler := promhttp.HandlerFor(78r,79promhttp.HandlerOpts{80ErrorHandling: promhttp.ContinueOnError,81},82)8384if i.includeExporterMetrics {85// Note that we have to use reg here to use the same promhttp metrics for86// all expositions.87handler = promhttp.InstrumentMetricHandler(r, handler)88}8990return handler, nil91}9293// ScrapeConfigs satisfies Integration.ScrapeConfigs.94func (i *CollectorIntegration) ScrapeConfigs() []config.ScrapeConfig {95return []config.ScrapeConfig{{96JobName: i.name,97MetricsPath: "/metrics",98}}99}100101// Run satisfies Integration.Run.102func (i *CollectorIntegration) Run(ctx context.Context) error {103return i.runner(ctx)104}105106107