feat(openclaw): add event_t JSONL emission for pilot integration#47
Open
fangxiu-wf wants to merge 1 commit into
Open
feat(openclaw): add event_t JSONL emission for pilot integration#47fangxiu-wf wants to merge 1 commit into
fangxiu-wf wants to merge 1 commit into
Conversation
Add an event-level JSONL output channel alongside the existing OTLP trace
exporter so loongsuite-pilot can ingest each LLM/tool event as one line of
event_t schema and fan it out to SLS / JSONL / HTTP sinks.
The two paths are independent:
- endpoint set, log_enabled unset/false -> OTLP-only (existing default)
- endpoint unset, log_enabled true -> JSONL-only (no OTLP)
- endpoint set, log_enabled true -> dual-mode (both paths run)
- both unset -> plugin refuses to activate
Plugin reads ~/.openclaw/otel-config.json (new shared config file, separate
from openclaw.json) for log_enabled / log_dir / log_filename_format /
captureMessageContent. Plugin-config priority: openclaw.json plugins.entries
> otel-config.json > env (OPENCLAW_LOG_ENABLED / OPENCLAW_LOG_DIR /
OPENCLAW_CAPTURE_MESSAGE_CONTENT / OPENCLAW_TELEMETRY_DEBUG) > default.
Output: <log_dir>/openclaw-YYYY-MM-DD.jsonl, appended via fs.appendFileSync,
matching pilot BaseHookInput's hook filename format. Each line carries
required event_t fields: time_unix_nano, event.id, event.name, session.id,
user.id, agent.type ("openclaw"), turn.id, step.id; plus event-specific
fields (gen_ai.provider.name, gen_ai.request.model, gen_ai.usage.*_tokens,
gen_ai.tool.*, response.finish_reasons, error.*).
JSONL listeners are registered in a self-contained module (src/jsonl-hooks.ts)
that maintains its own minimal per-runId state, so the OTLP trace path is
untouched. Write failures are logged at warn level and never propagate.
Tests: 14 unit cases for JsonlEmitter + builders + readSharedOtelConfig;
4 end-to-end cases simulating one LLM turn with tool call, double-fire dedup,
captureMessageContent toggle, and step.id increment across turns. All 129
existing tests still pass.
Bumps version to 0.1.4-beta.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add an event-level JSONL output channel to
opentelemetry-instrumentation-openclawsoloongsuite-pilotcan ingest each LLM/tool event as one line ofevent_tschema and fan it out to SLS / JSONL / HTTP sinks. The two paths (OTLP trace + JSONL) are independent.Modes
endpointlog_enabledShared config:
~/.openclaw/otel-config.jsonNew file (separate from
~/.openclaw/openclaw.json), used as the integration contract with pilot:{ "log_enabled": true, "log_dir": "~/.loongsuite-pilot/logs/openclaw", "log_filename_format": "hook", "captureMessageContent": false }Plugin-config priority for any field:
openclaw.json plugins.entries.config>~/.openclaw/otel-config.json> env (OPENCLAW_LOG_ENABLED/OPENCLAW_LOG_DIR/OPENCLAW_CAPTURE_MESSAGE_CONTENT/OPENCLAW_TELEMETRY_DEBUG) > default.What changes
src/jsonl-emitter.tssrc/jsonl-hooks.tssrc/types.tsArmsTraceConfig(4 new optional fields)src/index.tstest/jsonl-emitter.test.tstest/integration-jsonl.test.tsREADME.mdCHANGELOG.mdpackage.jsonOutput schema
<log_dir>/openclaw-YYYY-MM-DD.jsonl, one JSON object per line. Required fields per record:time_unix_nano,event.id,event.name∈{llm.request, llm.response, tool.call, tool.result},session.id,user.id,agent.type(always"openclaw"),turn.id,step.id. Optional fields per event type carry provider/model/usage/tool/error info. Filename matches pilotBaseHookInput's hook filename format.Why a separate hook module?
The OTLP trace path (
activate()body insrc/index.ts) is large and stateful (per-channel TraceContext, span lifecycles, propagation). Adding JSONL emission inline would either entangle the two paths or require null-guarding every OTLP call site. Instead,registerJsonlHooks()registers its own listeners with minimal per-runId state. In dual-mode, both listener sets fire on the same hook events independently. Write failures are logged at warn-level and never propagate to the gateway.Test plan
npm test— all 129 existing tests still pass + 18 new tests passnpm run build— typecheck cleanagent.type=openclaw, usage tokens preservedtransformRecordfield mapping correctness in pilot CRBackward compat
log_enabledis unset, JSONL hooks are not registered, and the OTLP path runs identically to before.🤖 Generated with Claude Code