feat(agent): ship cloud agent logs to PostHog Logs via OTEL#2566
Draft
pauldambra wants to merge 2 commits into
Draft
feat(agent): ship cloud agent logs to PostHog Logs via OTEL#2566pauldambra wants to merge 2 commits into
pauldambra wants to merge 2 commits into
Conversation
The cloud AgentServer previously shipped nothing to PostHog — its logs only went to console and S3, so cloud runs were hard to debug. Wire the (previously unused) OtelLogWriter into AgentServer: - Add OtelLogWriter.emitLog(level, scope, message, data) that maps the agent's log level to an OTEL severity and stores the scope as a log.scope attribute, mirroring the desktop electron-log OTEL transport. - Route every server log line through a single onLog choke point that emits to OTEL (and still mirrors to the SSE console stream). - Flush on fatal error and shut down on stop so buffered logs are exported before the process exits. - Default the endpoint to /i/v1/logs (matches desktop and the existing OtelTransportConfig; the old /i/v1/agent-logs default was never used). - Add service.version to the resource attributes. Export is enabled only when the sandbox injects POSTHOG_OTEL_LOGS_HOST and POSTHOG_OTEL_LOGS_API_KEY; otherwise it is a no-op, exactly like the desktop transport. This keeps customer task logs out of customer projects until infra provides a dedicated internal logs host + key. Generated-By: PostHog Code Task-Id: 70cb1c35-2d0e-4f15-a0d5-052f1e9e3572
|
React Doctor found no issues in the changed files. 🎉 Reviewed by React Doctor for commit |
Contributor
Prompt To Fix All With AIFix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
packages/agent/src/otel-log-writer.test.ts:49-72
**Non-parameterised severity/body tests**
The two new `emitLog` tests only exercise `warn` (with data) and `error` (without data), leaving `debug` and `info` untested. The team's convention is to prefer parameterised tests: an `it.each` over all four levels (`debug`/`info`/`warn`/`error`) would cover the mapping table exhaustively in a single block, and a second `it.each` for the body-formatting cases (data present vs. absent) would remove the duplication between the two tests.
Reviews (1): Last reviewed commit: "feat(agent): ship cloud agent logs to Po..." | Re-trigger Greptile |
Wiring onLog onto the constructor logger routed every pre-session log line through emitConsoleLog, which calls session.logWriter.appendRawLine. Tests that inject a session with a partial logWriter mock then crashed with "appendRawLine is not a function" (13 unit-test failures). Send pre-session logs to OTEL only (emitOtelLog, which never touches session state) and keep the full handleLog (OTEL + SSE console) on the post-init logger, exactly where emitConsoleLog ran before this PR. Also parameterise the emitLog tests (it.each over all four levels and both body-formatting cases) per review feedback. Generated-By: PostHog Code Task-Id: 70cb1c35-2d0e-4f15-a0d5-052f1e9e3572
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.
Problem
The cloud
AgentServer(the process that runs each task in a sandbox) shipped no telemetry to PostHog — its logs only went to stdout and S3. When something goes wrong with a cloud run (e.g. the recent Slack reports), there's no way to query what happened byrun_id/task_id. TheOtelLogWriterandotelTransportconfig existed but were never wired to anything.This makes the desktop's existing pattern (logs → PostHog Logs via OTEL, indexed by service/run) work for the cloud agent too.
Changes
OtelLogWriter.emitLog(level, scope, message, data)— maps the agent log level to an OTEL severity and stores the scope as alog.scopeattribute, mirroring the desktop electron-log OTEL transport. Addsservice.versionto the resource attributes and defaults the endpoint to/i/v1/logs(matches desktop + the existingOtelTransportConfig; the old/i/v1/agent-logsdefault was never used).AgentServerroutes every server log line through oneonLogchoke point that emits to OTEL and still mirrors to the SSE console stream; flushes on fatal error and shuts down on stop.POSTHOG_OTEL_LOGS_HOST/POSTHOG_OTEL_LOGS_API_KEY/POSTHOG_OTEL_LOGS_PATHenv vars (plumbed viabin.ts→AgentServerConfig.otelLogs).Export is disabled (no-op) unless the sandbox injects the host + key — same behavior as the desktop transport. This is deliberate: the sandbox only has the customer's API URL + personal key, so exporting there would dump customer task logs into customer projects (and a personal key may not even authorize log ingest). A follow-up on the infra side needs to inject a dedicated PostHog-internal logs host + ingest key to turn this on.
Scope note: this is logs-only. Errors land in PostHog Logs as
ERROR-severity records; wiring exceptions into the dedicated Error Tracking product (posthog-node) is a deliberate follow-up.How did you test this?
pnpm --filter @posthog/agent typecheck— passes.pnpm --filter @posthog/agent test otel-log-writer— 5/5 pass (added tests foremitLogseverity/scope/body mapping and the/i/v1/logsdefault endpoint).biome checkon all changed files — clean.agent-server.test.tshas 55 pre-existing failures in this environment (mswbeforeAllcascade) — identical on a cleanmaincheckout, unrelated to this change.Automatic notifications
Created with PostHog Code from a Slack thread