{"record":{"id":"2cab9e9e878ef5a7","repo":"microsoft/aspire","slug":"log-exporter-w","errorCode":null,"errorMessage":"log exporter: %w","messagePattern":"log exporter: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/Aspire.Cli/Templating/Templates/go-starter/api/telemetry.go","lineNumber":88,"sourceCode":"\t\treturn nil, fmt.Errorf(\"metric exporter: %w\", err)\n\t}\n\tmp := sdkmetric.NewMeterProvider(\n\t\tsdkmetric.WithReader(sdkmetric.NewPeriodicReader(metricExp)),\n\t\tsdkmetric.WithResource(res),\n\t)\n\totel.SetMeterProvider(mp)\n\n\tif err := runtime.Start(runtime.WithMeterProvider(mp)); err != nil {\n\t\treturn nil, fmt.Errorf(\"runtime metrics: %w\", err)\n\t}\n\n\tlogOpts := []otlploggrpc.Option{}\n\tif len(headers) > 0 {\n\t\tlogOpts = append(logOpts, otlploggrpc.WithHeaders(headers))\n\t}\n\tlogExp, err := otlploggrpc.New(ctx, logOpts...)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"log exporter: %w\", err)\n\t}\n\tlp := sdklog.NewLoggerProvider(\n\t\tsdklog.WithProcessor(sdklog.NewBatchProcessor(logExp)),\n\t\tsdklog.WithResource(res),\n\t)\n\totellog.SetLoggerProvider(lp)\n\n\t// Route slog to OTel so structured logs appear in the dashboard.\n\tslog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, nil)))\n\n\treturn func(ctx context.Context) error {\n\t\t_ = tp.Shutdown(ctx)\n\t\t_ = mp.Shutdown(ctx)\n\t\t_ = lp.Shutdown(ctx)\n\t\treturn nil\n\t}, nil\n}\n","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Cli/Templating/Templates/go-starter/api/telemetry.go#L70-L106","documentation":"setupOTel wraps the error from otlploggrpc.New, which constructs the gRPC OTLP log exporter. This fails on an invalid endpoint/URL or bad exporter options. The wrap \"log exporter: %w\" retains the underlying cause.","triggerScenarios":"otlploggrpc.New returns an error because the log OTLP endpoint is malformed or the connection options (TLS, headers) are invalid when initializing structured logging.","commonSituations":"Same endpoint misconfiguration as traces/metrics but applied to the logs signal — e.g. dashboard OTLP endpoint not set, wrong port, or mixing http exporter endpoint with the grpc log exporter.","solutions":["Validate the log endpoint URL scheme/host:port before calling setupOTel.","Inspect the unwrapped error for the exact URL or dial failure.","Ensure the OTLP logs endpoint (often a different port than traces) is correct and reachable.","Verify otlploggrpc SDK dependency versions are consistent with go.opentelemetry.io/otel/sdk/log."],"exampleFix":"// before\nlogExp, err := otlploggrpc.New(ctx, logOpts...)\n// after\nif u, perr := url.Parse(os.Getenv(\"OTEL_EXPORTER_OTLP_ENDPOINT\")); perr != nil || u.Host == \"\" {\n    return nil, fmt.Errorf(\"invalid OTLP endpoint for logs: %q\", os.Getenv(\"OTEL_EXPORTER_OTLP_ENDPOINT\"))\n}\nlogExp, err := otlploggrpc.New(ctx, logOpts...)","handlingStrategy":"validation","validationCode":"ep := os.Getenv(\"OTEL_EXPORTER_OTLP_ENDPOINT\")\nif u, err := url.Parse(ep); err != nil || u.Scheme == \"\" {\n    return fmt.Errorf(\"invalid logs OTLP endpoint %q\", ep)\n}","typeGuard":null,"tryCatchPattern":"if err := setupOTel(...); err != nil {\n    log.Printf(\"log exporter setup failed, falling back to stderr logging: %v\", err)\n}","preventionTips":["Validate endpoint before exporter creation.","Verify the logs-specific OTLP port if different from traces.","Keep otlploggrpc and sdk/log versions consistent."],"tags":["go","opentelemetry","grpc","logging","telemetry"],"backgroundTag":"invalid-url-format","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}