← Back to PRs

#22478: fix(diagnostics-otel): wire OTLP exporter to emit traffic to configured endpoint #18794

by LuffySama-Dev open 2026-02-21 06:43 View on GitHub →
size: S
**PR Title:** Fix logger singleton split across bundles and harden global logging state validation ## Summary Describe the problem and fix in 2–5 bullets: - Problem: `registerLogTransport` and logger cache/state could live in different bundled module copies, so transports registered from plugin-sdk were not reliably attached to the active logger. - Why it matters: extension log exporters (for example OTEL log transport) could silently miss runtime logs even when configured correctly. - What changed: moved logging singletons to process-global storage with `Symbol.for(...)` and added runtime validation/self-healing for both shared objects. - What did NOT change (scope boundary): no config schema changes, no new CLI flags, no diagnostics event-bus or OTEL metrics/traces logic changes; only logging state/transport storage logic in `/Users/saurabh/Downloads/finalSetup/TheFixedVerion0/openclaw/src/logging/state.ts` and `/Users/saurabh/Downloads/finalSetup/TheFixedVerion0/openclaw/src/logging/logger.ts`. ## Change Type (select all) - [x] Bug fix - [ ] Feature - [ ] Refactor - [ ] Docs - [x] Security hardening - [ ] Chore/infra ## Scope (select all touched areas) - [x] Gateway / orchestration - [ ] Skills / tool execution - [ ] Auth / tokens - [ ] Memory / storage - [ ] Integrations - [ ] API / contracts - [ ] UI / DX - [ ] CI/CD / infra ## Linked Issue/PR - Closes #18794 ## User-visible / Behavior Changes - Log transports registered via plugin-sdk now reliably attach to the active logger in bundled/runtime-split builds. - Invalid/poisoned global logging singleton values are repaired automatically at startup. - No user-facing config/default changes. ## Security Impact (required) - New permissions/capabilities? (`Yes/No`): No - Secrets/tokens handling changed? (`Yes/No`): No - New/changed network calls? (`Yes/No`): No - Command/tool execution surface changed? (`Yes/No`): No - Data access scope changed? (`Yes/No`): No - If any `Yes`, explain risk + mitigation: N/A ## Repro + Verification ### Environment - OS: macOS + Linux VPS - Runtime/container: Node.js 22+ - Model/provider: N/A (logging transport path) - Integration/channel (if any): plugin-sdk log transport path (diagnostics exporter scenario) - Relevant config (redacted): logging + diagnostics enabled (standard) ### Steps 1. Build/install OpenClaw from source and enable a plugin transport registration path. 2. Start gateway/runtime where logger is initialized from one bundled entry. 3. Register transport from plugin-sdk path and generate logs. ### Expected - Registered transport receives runtime logs consistently. ### Actual - Before fix: transport could miss logs due to split singleton state. - After fix: transport attaches and receives logs. ## Evidence Attach at least one: - [ ] Failing test/log before + passing after - [x] Trace/log snippets - [ ] Screenshot/recording - [ ] Perf numbers (if relevant) ## Human Verification (required) What you personally verified (not just CI), and how: - Verified scenarios: plugin-sdk transport registration path receives logs after logger is already initialized. - Edge cases checked: invalid existing global singleton value is rejected and replaced with a valid shape. - What you did **not** verify: no additional changes outside `/Users/saurabh/Downloads/finalSetup/TheFixedVerion0/openclaw/src/logging/state.ts` and `/Users/saurabh/Downloads/finalSetup/TheFixedVerion0/openclaw/src/logging/logger.ts`. ## Compatibility / Migration - Backward compatible? (`Yes/No`): Yes - Config/env changes? (`Yes/No`): No - Migration needed? (`Yes/No`): No - If yes, exact upgrade steps: N/A ## Failure Recovery (if this breaks) - How to disable/revert this change quickly: revert `/Users/saurabh/Downloads/finalSetup/TheFixedVerion0/openclaw/src/logging/state.ts` and `/Users/saurabh/Downloads/finalSetup/TheFixedVerion0/openclaw/src/logging/logger.ts` to previous module-local singleton behavior. - Files/config to restore: only those two files. - Known bad symptoms reviewers should watch for: duplicate logger state across chunks, transports not receiving logs, or missing file-log export hooks. ## Risks and Mitigations List only real risks for this PR. Add/remove entries as needed. If none, write `None`. - Risk: shared global singleton could be pre-populated with malformed data by in-process code. - Mitigation: runtime shape validation and self-healing replacement logic. - Risk: stale invalid transport set entries could break transport iteration. - Mitigation: transport-set validation plus preserving only valid function entries during repair. <!-- greptile_comment --> <h3>Greptile Summary</h3> Moved logging singleton state and external transports to process-global storage using `Symbol.for(...)` to fix issues with logger state being split across bundled modules. Key changes: - Replaced module-local `externalTransports` Set with global singleton accessed via `Symbol.for("openclaw.externalLogTransports")` in `src/logging/logger.ts:38` - Replaced module-local `loggingState` object with global singleton accessed via `Symbol.for("openclaw.loggingState")` in `src/logging/state.ts:1` - Added runtime validation and self-healing for both singletons to detect and repair invalid global state - Simplified `createRequire` usage by removing unnecessary `resolveNodeRequire` function This ensures log transports registered via plugin-sdk reliably attach to the active logger even when multiple bundled copies exist. <h3>Confidence Score: 4/5</h3> - This PR is safe to merge with minimal risk - The changes are well-structured and follow a clear pattern for moving singletons to global storage. The validation logic includes self-healing for invalid state. However, the validation in `isLoggingState` doesn't check for the existence of `cachedLogger`, `cachedSettings`, `cachedConsoleSettings`, and `overrideSettings` properties, which could theoretically cause issues if the global object is malformed (though the code appears resilient to this). The removal of `resolveNodeRequire` in favor of direct `createRequire` import is safe and simplifies the code. - No files require special attention <sub>Last reviewed commit: a4dc9f5</sub> <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> <!-- /greptile_comment -->

Most Similar PRs