{"record":{"id":"2f59ed2700c64730","repo":"alibaba/open-code-review","slug":"telemetry-shutdown-v","errorCode":null,"errorMessage":"telemetry shutdown: %v","messagePattern":"telemetry shutdown: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/telemetry/shutdown.go","lineNumber":30,"sourceCode":"\n// Shutdown flushes and shuts down all initialized providers.\n// It should be called before process exit to ensure buffered data is exported.\nfunc Shutdown(ctx context.Context) error {\n\tif len(shutdownFuncs) == 0 {\n\t\treturn nil\n\t}\n\n\tvar errs []error\n\tfor _, fn := range shutdownFuncs {\n\t\tif err := fn(ctx); err != nil {\n\t\t\terrs = append(errs, err)\n\t\t}\n\t}\n\n\tshutdownFuncs = nil\n\n\tif len(errs) > 0 {\n\t\treturn fmt.Errorf(\"telemetry shutdown: %v\", errs)\n\t}\n\treturn nil\n}\n\n// ShutdownWithTimeout creates a timeout context and calls Shutdown.\nfunc ShutdownWithTimeout(ctx context.Context, timeout time.Duration) {\n\tcctx, cancel := context.WithTimeout(ctx, timeout)\n\tdefer cancel()\n\tif err := Shutdown(cctx); err != nil {\n\t\tfmt.Fprintf(os.Stderr, \"[ocr] WARNING: telemetry shutdown error: %v\\n\", err)\n\t}\n}\n","sourceCodeStart":12,"sourceCodeEnd":43,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/telemetry/shutdown.go#L12-L43","documentation":"Aggregated error returned by telemetry.Shutdown when one or more registered telemetry provider shutdown functions (OTLP exporters, etc.) fail while flushing buffered data. All shutdown funcs are executed, every failure is collected, and the combined errors are wrapped into a single 'telemetry shutdown: ...' error. Shutdown funcs are cleared afterwards, so a second Shutdown call is a no-op.","triggerScenarios":"Calling telemetry.Shutdown(ctx) (or ShutdownWithTimeout) at process exit when a provider's shutdown function returns an error — typically a context deadline exceeded while flushing to a remote collector, or an exporter connection failure.","commonSituations":"Network unreachable or telemetry endpoint down at exit; the shutdown timeout (ShutdownWithTimeout) is too short for large buffered batches; the collector rejects the final export.","solutions":["Read the wrapped errors after 'telemetry shutdown:' to identify which exporter failed and why.","Increase the timeout passed to ShutdownWithTimeout so buffered spans/metrics can flush.","Verify the telemetry endpoint/collector is reachable; check proxy and firewall settings.","Treat as non-fatal if the review result itself is fine — the CLI already logs this as a WARNING to stderr in ShutdownWithTimeout."],"exampleFix":"// before\ntelemetry.Shutdown(context.Background())\n// after\ntelemetry.ShutdownWithTimeout(context.Background(), 10*time.Second) // longer window to flush exporters","handlingStrategy":"try-catch","validationCode":"// no pre-call validation possible; optionally check telemetry was initialized\nif len(shutdownFuncs) == 0 { return nil }","typeGuard":null,"tryCatchPattern":"if err := telemetry.Shutdown(ctx); err != nil {\n    // aggregated: 'telemetry shutdown: [err1 err2]'\n    log.Printf(\"telemetry did not flush cleanly (non-fatal): %v\", err)\n}","preventionTips":["Give ShutdownWithTimeout a generous timeout (>=10s) so exporters can flush.","Ensure the telemetry endpoint/collector is reachable before the run.","Call Shutdown exactly once at exit; it is idempotent only as a no-op afterwards.","Monitor collector health; treat this error as observability loss, not run failure."],"tags":["telemetry","shutdown","network","timeout"],"backgroundTag":"telemetry-export-flush-failed","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}