pomerium/internal/zero/reporter/reporter.go
2023-12-20 14:53:06 -05:00

61 lines
1.6 KiB
Go

// Package reporter periodically submits metrics back to the cloud.
package reporter
import (
"context"
"fmt"
"time"
export_grpc "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
metric_sdk "go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/resource"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
"google.golang.org/grpc"
"github.com/pomerium/pomerium/internal/log"
"github.com/pomerium/pomerium/internal/version"
)
// Run starts loop that pushes metrics via OTEL protocol until ctx is canceled
func Run(
ctx context.Context,
conn *grpc.ClientConn,
opts ...Option,
) error {
cfg := getConfig(opts...)
exporter, err := export_grpc.New(ctx, export_grpc.WithGRPCConn(conn))
if err != nil {
return fmt.Errorf("starting OTEL exporter: %w", err)
}
defer shutdown(exporter.Shutdown, cfg.shutdownTimeout)
provider := metric_sdk.NewMeterProvider(
metric_sdk.WithResource(resource.NewSchemaless(
semconv.ServiceNameKey.String("pomerium-managed-core"),
semconv.ServiceVersionKey.String(version.FullVersion()),
)),
metric_sdk.WithReader(
metric_sdk.NewPeriodicReader(
exporter,
metric_sdk.WithInterval(cfg.collectInterval),
)))
defer shutdown(provider.Shutdown, cfg.shutdownTimeout)
meter := provider.Meter("pomerium-managed-core")
for _, fn := range cfg.metrics {
err := fn(meter)
if err != nil {
log.Ctx(ctx).Error().Err(err).Msg("error registering metric")
}
}
<-ctx.Done()
return ctx.Err()
}
func shutdown(fn func(ctx context.Context) error, timeout time.Duration) {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
_ = fn(ctx)
}