newMeterProvider creates a MeterProvider with dual-mode export: - Pull (Prometheus): always active — exposes metrics via /metrics endpoint for scraping. - Push (OTLP HTTP): opt-in — enabled when OTEL_EXPORTER_OTLP_ENDPOINT is set. Uses the standard OTel env var, so it works automatically with any OT
(ctx context.Context, res *resource.Resource)
| 147 | // - Push (OTLP HTTP): opt-in — enabled when OTEL_EXPORTER_OTLP_ENDPOINT is set. |
| 148 | // Uses the standard OTel env var, so it works automatically with any OTel Collector. |
| 149 | func newMeterProvider(ctx context.Context, res *resource.Resource) (*sdkmetric.MeterProvider, error) { |
| 150 | // Pull exporter: Prometheus scrape endpoint (always active). |
| 151 | promExp, err := promexporter.New() |
| 152 | if err != nil { |
| 153 | return nil, err |
| 154 | } |
| 155 | |
| 156 | metricsHandler = promhttp.Handler() |
| 157 | |
| 158 | opts := []sdkmetric.Option{ |
| 159 | sdkmetric.WithResource(res), |
| 160 | sdkmetric.WithReader(promExp), |
| 161 | } |
| 162 | |
| 163 | // Push exporter: enabled when an OTLP metrics endpoint is configured. |
| 164 | // Checks OTEL_EXPORTER_OTLP_METRICS_ENDPOINT (signal-specific) or |
| 165 | // OTEL_EXPORTER_OTLP_ENDPOINT (generic fallback) per the OTel spec. |
| 166 | if os.Getenv("OTEL_EXPORTER_OTLP_METRICS_ENDPOINT") != "" || os.Getenv("OTEL_EXPORTER_OTLP_ENDPOINT") != "" { |
| 167 | otlpExp, err := otlpmetrichttp.New(ctx, |
| 168 | otlpmetrichttp.WithInsecure(), |
| 169 | ) |
| 170 | if err != nil { |
| 171 | return nil, err |
| 172 | } |
| 173 | opts = append(opts, sdkmetric.WithReader(sdkmetric.NewPeriodicReader(otlpExp, |
| 174 | sdkmetric.WithInterval(60*time.Second), |
| 175 | ))) |
| 176 | } |
| 177 | |
| 178 | meterProvider := sdkmetric.NewMeterProvider(opts...) |
| 179 | return meterProvider, nil |
| 180 | } |
| 181 | |
| 182 | func newLoggerProvider() (*log.LoggerProvider, error) { |
| 183 | logExporter, err := stdoutlog.New() |
no outgoing calls