// Package tracerconfig provides a bridge to eliminate circular dependencies between // the logger and tracing packages. It stores tracer configuration and provides // factory functions that can be used by the logger package without importing tracing. package tracerconfig import ( "context" "crypto/tls" "crypto/x509" "sync" sdklog "go.opentelemetry.io/otel/sdk/log" ) // GetClientCertificate defines a function type for providing client certificates for mutual TLS. // This is used when exporting telemetry data to secured OTLP endpoints that require // client certificate authentication. type GetClientCertificate func(*tls.CertificateRequestInfo) (*tls.Certificate, error) // Config provides configuration options for OpenTelemetry tracing setup. // It supplements standard OpenTelemetry environment variables with additional // NTP Pool-specific configuration including TLS settings for secure OTLP export. type Config struct { ServiceName string // Service name for resource identification (overrides OTEL_SERVICE_NAME) Environment string // Deployment environment (development, staging, production) Endpoint string // OTLP endpoint hostname/port (e.g., "otlp.example.com:4317") EndpointURL string // Complete OTLP endpoint URL (e.g., "https://otlp.example.com:4317/v1/traces") CertificateProvider GetClientCertificate // Client certificate provider for mutual TLS RootCAs *x509.CertPool // CA certificate pool for server verification } // ExporterFactory creates an OTLP log exporter using the provided configuration. // This allows the logger package to create exporters without importing the tracing package. type ExporterFactory func(context.Context, *Config) (sdklog.Exporter, error) // Global state for sharing configuration between packages var ( globalConfig *Config globalContext context.Context exporterFactory ExporterFactory configMu sync.RWMutex ) // Store saves the tracer configuration and exporter factory for use by other packages. // This should be called by the tracing package during initialization. func Store(ctx context.Context, cfg *Config, factory ExporterFactory) { configMu.Lock() defer configMu.Unlock() globalConfig = cfg globalContext = ctx exporterFactory = factory } // Get returns the stored tracer configuration, context, and exporter factory. // Returns nil values if no configuration has been stored yet. func Get() (*Config, context.Context, ExporterFactory) { configMu.RLock() defer configMu.RUnlock() return globalConfig, globalContext, exporterFactory } // IsConfigured returns true if tracer configuration has been stored. func IsConfigured() bool { configMu.RLock() defer configMu.RUnlock() return globalConfig != nil && globalContext != nil && exporterFactory != nil } // Clear removes the stored configuration. This is primarily useful for testing. func Clear() { configMu.Lock() defer configMu.Unlock() globalConfig = nil globalContext = nil exporterFactory = nil }