Path: blob/main/component/otelcol/exporter/prometheus/prometheus.go
4096 views
// Package prometheus provides an otelcol.exporter.prometheus component.1package prometheus23import (4"context"5"fmt"6"sync"7"time"89"github.com/go-kit/log"10"github.com/grafana/agent/component"11"github.com/grafana/agent/component/otelcol"12"github.com/grafana/agent/component/otelcol/exporter/prometheus/internal/convert"13"github.com/grafana/agent/component/otelcol/internal/lazyconsumer"14"github.com/grafana/agent/component/prometheus"15"github.com/grafana/agent/pkg/river"16"github.com/prometheus/prometheus/storage"17)1819func init() {20component.Register(component.Registration{21Name: "otelcol.exporter.prometheus",22Args: Arguments{},23Exports: otelcol.ConsumerExports{},2425Build: func(o component.Options, a component.Arguments) (component.Component, error) {26return New(o, a.(Arguments))27},28})29}3031// Arguments configures the otelcol.exporter.prometheus component.32type Arguments struct {33IncludeTargetInfo bool `river:"include_target_info,attr,optional"`34IncludeScopeInfo bool `river:"include_scope_info,attr,optional"`35GCFrequency time.Duration `river:"gc_frequency,attr,optional"`36ForwardTo []storage.Appendable `river:"forward_to,attr"`37}3839var _ river.Unmarshaler = (*Arguments)(nil)4041// DefaultArguments holds defaults values.42var DefaultArguments = Arguments{43IncludeTargetInfo: true,44IncludeScopeInfo: true,45GCFrequency: 5 * time.Minute,46}4748// UnmarshalRiver implements river.Unmarshaler and applies defaults.49func (args *Arguments) UnmarshalRiver(f func(interface{}) error) error {50*args = DefaultArguments5152type arguments Arguments53if err := f((*arguments)(args)); err != nil {54return err55}5657if args.GCFrequency == 0 {58return fmt.Errorf("gc_frequency must be greater than 0")59}6061return nil62}6364// Component is the otelcol.exporter.prometheus component.65type Component struct {66log log.Logger67opts component.Options6869fanout *prometheus.Fanout70converter *convert.Converter7172mut sync.RWMutex73cfg Arguments74}7576var _ component.Component = (*Component)(nil)7778// New creates a new otelcol.exporter.prometheus component.79func New(o component.Options, c Arguments) (*Component, error) {80fanout := prometheus.NewFanout(nil, o.ID, o.Registerer)8182converter := convert.New(o.Logger, fanout, convert.Options{83IncludeTargetInfo: true,84IncludeScopeInfo: true,85})8687res := &Component{88log: o.Logger,89opts: o,9091fanout: fanout,92converter: converter,93}94if err := res.Update(c); err != nil {95return nil, err96}9798// Construct a consumer based on our converter and export it. This will99// remain the same throughout the component's lifetime, so we do this during100// component construction.101export := lazyconsumer.New(context.Background())102export.SetConsumers(nil, converter, nil)103o.OnStateChange(otelcol.ConsumerExports{Input: export})104105return res, nil106}107108// Run implements Component.109func (c *Component) Run(ctx context.Context) error {110for {111select {112case <-ctx.Done():113return nil114case <-time.After(c.nextGC()):115// TODO(rfratto): we may want to consider making this an option in the116// future, but hard-coding to 5 minutes is a reasonable default to start117// with.118c.converter.GC(5 * time.Minute)119}120}121}122123func (c *Component) nextGC() time.Duration {124c.mut.RLock()125defer c.mut.RUnlock()126return c.cfg.GCFrequency127}128129// Update implements Component.130func (c *Component) Update(newConfig component.Arguments) error {131c.mut.Lock()132defer c.mut.Unlock()133134cfg := newConfig.(Arguments)135c.cfg = cfg136137c.fanout.UpdateChildren(cfg.ForwardTo)138c.converter.UpdateOptions(convert.Options{139IncludeTargetInfo: cfg.IncludeTargetInfo,140IncludeScopeInfo: cfg.IncludeScopeInfo,141})142143// If our forward_to argument changed, we need to flush the metadata cache to144// ensure the new children have all the metadata they need.145//146// For now, we always flush whenever we update, but we could do something147// more intelligent here in the future.148c.converter.FlushMetadata()149return nil150}151152153