Path: blob/main/pkg/integrations/v2/metricsutils/metricshandler_integration.go
5365 views
package metricsutils12import (3"context"4"fmt"5"net/http"6"path"78"github.com/go-kit/log"9"github.com/gorilla/mux"10"github.com/grafana/agent/pkg/integrations/v2"11"github.com/grafana/agent/pkg/integrations/v2/autoscrape"12"github.com/grafana/agent/pkg/integrations/v2/common"13"github.com/prometheus/common/model"14"github.com/prometheus/prometheus/config"15"github.com/prometheus/prometheus/discovery"16"github.com/prometheus/prometheus/discovery/targetgroup"17)1819// NewMetricsHandlerIntegration returns a integrations.MetricsIntegration which20// will expose a /metrics endpoint for h.21func NewMetricsHandlerIntegration(22_ log.Logger,23c integrations.Config,24mc common.MetricsConfig,25globals integrations.Globals,26h http.Handler,27) (integrations.MetricsIntegration, error) {2829id, err := c.Identifier(globals)30if err != nil {31return nil, err32}33return &metricsHandlerIntegration{34integrationName: c.Name(),35instanceID: id,3637common: mc,38globals: globals,39handler: h,4041targets: []handlerTarget{{MetricsPath: "metrics"}},42}, nil43}4445type metricsHandlerIntegration struct {46integrationName, instanceID string4748common common.MetricsConfig49globals integrations.Globals50handler http.Handler51targets []handlerTarget5253runFunc func(ctx context.Context) error54}5556type handlerTarget struct {57// Path relative to Handler prefix where metrics are available.58MetricsPath string59// Extra labels to inject into the target. Labels here that take precedence60// over labels with the same name from the generated target group.61Labels model.LabelSet62}6364// Static typecheck tests65var (66_ integrations.Integration = (*metricsHandlerIntegration)(nil)67_ integrations.HTTPIntegration = (*metricsHandlerIntegration)(nil)68_ integrations.MetricsIntegration = (*metricsHandlerIntegration)(nil)69)7071// RunIntegration implements Integration.72func (i *metricsHandlerIntegration) RunIntegration(ctx context.Context) error {73// Call our runFunc if defined (used from integrationShim), otherwise74// fallback to no-op.75if i.runFunc != nil {76return i.runFunc(ctx)77}7879<-ctx.Done()80return nil81}8283// Handler implements HTTPIntegration.84func (i *metricsHandlerIntegration) Handler(prefix string) (http.Handler, error) {85r := mux.NewRouter()86r.Handle(path.Join(prefix, "metrics"), i.handler)87return r, nil88}8990// Targets implements MetricsIntegration.91func (i *metricsHandlerIntegration) Targets(ep integrations.Endpoint) []*targetgroup.Group {92integrationNameValue := model.LabelValue("integrations/" + i.integrationName)9394group := &targetgroup.Group{95Labels: model.LabelSet{96model.InstanceLabel: model.LabelValue(i.instanceID),97model.JobLabel: integrationNameValue,98"agent_hostname": model.LabelValue(i.globals.AgentIdentifier),99100// Meta labels that can be used during SD.101"__meta_agent_integration_name": model.LabelValue(i.integrationName),102"__meta_agent_integration_instance": model.LabelValue(i.instanceID),103"__meta_agent_integration_autoscrape": model.LabelValue(BoolToString(*i.common.Autoscrape.Enable)),104},105Source: fmt.Sprintf("%s/%s", i.integrationName, i.instanceID),106}107108for _, lbl := range i.common.ExtraLabels {109group.Labels[model.LabelName(lbl.Name)] = model.LabelValue(lbl.Value)110}111112for _, t := range i.targets {113group.Targets = append(group.Targets, model.LabelSet{114model.AddressLabel: model.LabelValue(ep.Host),115model.MetricsPathLabel: model.LabelValue(path.Join(ep.Prefix, t.MetricsPath)),116}.Merge(t.Labels))117}118119return []*targetgroup.Group{group}120}121122// BoolToString is a helper for converting boolean values to a Prometheus labels-compatible string.123func BoolToString(b bool) string {124switch b {125case true:126return "1"127default:128return "0"129}130}131132// ScrapeConfigs implements MetricsIntegration.133func (i *metricsHandlerIntegration) ScrapeConfigs(sd discovery.Configs) []*autoscrape.ScrapeConfig {134if !*i.common.Autoscrape.Enable {135return nil136}137138cfg := config.DefaultScrapeConfig139cfg.JobName = fmt.Sprintf("%s/%s", i.integrationName, i.instanceID)140cfg.Scheme = i.globals.AgentBaseURL.Scheme141cfg.ServiceDiscoveryConfigs = sd142cfg.ScrapeInterval = i.common.Autoscrape.ScrapeInterval143cfg.ScrapeTimeout = i.common.Autoscrape.ScrapeTimeout144cfg.RelabelConfigs = i.common.Autoscrape.RelabelConfigs145cfg.MetricRelabelConfigs = i.common.Autoscrape.MetricRelabelConfigs146147return []*autoscrape.ScrapeConfig{{148Instance: i.common.Autoscrape.MetricsInstance,149Config: cfg,150}}151}152153154