package auth
import (
"context"
"os"
"github.com/grafana/agent/component"
"github.com/grafana/agent/component/otelcol/internal/lazycollector"
"github.com/grafana/agent/component/otelcol/internal/scheduler"
"github.com/grafana/agent/pkg/build"
"github.com/grafana/agent/pkg/river"
"github.com/grafana/agent/pkg/util/zapadapter"
"github.com/prometheus/client_golang/prometheus"
otelcomponent "go.opentelemetry.io/collector/component"
otelconfig "go.opentelemetry.io/collector/config"
sdkprometheus "go.opentelemetry.io/otel/exporters/prometheus"
"go.opentelemetry.io/otel/sdk/metric"
_ "github.com/grafana/agent/component/otelcol/internal/featuregate"
)
type Arguments interface {
component.Arguments
Convert() (otelconfig.Extension, error)
Extensions() map[otelconfig.ComponentID]otelcomponent.Extension
Exporters() map[otelconfig.DataType]map[otelconfig.ComponentID]otelcomponent.Exporter
}
type Exports struct {
Handler Handler `river:"handler,attr"`
}
type Handler struct {
ID otelconfig.ComponentID
Extension otelcomponent.Extension
}
var _ river.Capsule = Handler{}
func (Handler) RiverCapsule() {}
type Auth struct {
ctx context.Context
cancel context.CancelFunc
opts component.Options
factory otelcomponent.ExtensionFactory
sched *scheduler.Scheduler
collector *lazycollector.Collector
}
var (
_ component.Component = (*Auth)(nil)
_ component.HealthComponent = (*Auth)(nil)
)
func New(opts component.Options, f otelcomponent.ExtensionFactory, args Arguments) (*Auth, error) {
ctx, cancel := context.WithCancel(context.Background())
collector := lazycollector.New()
opts.Registerer.MustRegister(collector)
r := &Auth{
ctx: ctx,
cancel: cancel,
opts: opts,
factory: f,
sched: scheduler.New(opts.Logger),
collector: collector,
}
if err := r.Update(args); err != nil {
return nil, err
}
return r, nil
}
func (a *Auth) Run(ctx context.Context) error {
defer a.cancel()
return a.sched.Run(ctx)
}
func (a *Auth) Update(args component.Arguments) error {
rargs := args.(Arguments)
host := scheduler.NewHost(
a.opts.Logger,
scheduler.WithHostExtensions(rargs.Extensions()),
scheduler.WithHostExporters(rargs.Exporters()),
)
reg := prometheus.NewRegistry()
a.collector.Set(reg)
promExporter, err := sdkprometheus.New(sdkprometheus.WithRegisterer(reg), sdkprometheus.WithoutTargetInfo())
if err != nil {
return err
}
settings := otelcomponent.ExtensionCreateSettings{
TelemetrySettings: otelcomponent.TelemetrySettings{
Logger: zapadapter.New(a.opts.Logger),
TracerProvider: a.opts.Tracer,
MeterProvider: metric.NewMeterProvider(metric.WithReader(promExporter)),
},
BuildInfo: otelcomponent.BuildInfo{
Command: os.Args[0],
Description: "Grafana Agent",
Version: build.Version,
},
}
extensionConfig, err := rargs.Convert()
if err != nil {
return err
}
var components []otelcomponent.Component
ext, err := a.factory.CreateExtension(a.ctx, settings, extensionConfig)
if err != nil {
return err
} else if ext != nil {
components = append(components, ext)
}
a.opts.OnStateChange(Exports{
Handler: Handler{
ID: otelconfig.NewComponentID(otelconfig.Type(a.opts.ID)),
Extension: ext,
},
})
a.sched.Schedule(host, components...)
return nil
}
func (a *Auth) CurrentHealth() component.Health {
return a.sched.CurrentHealth()
}