Skip to content

Add OTLP logs signal (Python) correlated to traces#69

Open
brentrager wants to merge 1 commit into
mainfrom
py-otlp-logs
Open

Add OTLP logs signal (Python) correlated to traces#69
brentrager wants to merge 1 commit into
mainfrom
py-otlp-logs

Conversation

@brentrager

Copy link
Copy Markdown
Contributor

Problem

The Python observability SDK exported traces + metrics over OTLP but not logs, so nothing lands in the product /v1/logs endpoint and logs can't be correlated to traces. (Pearl th-5dca7d; matches ADR-100.)

Solution

Adds the logs signal to setup_otel_sdk, reusing the exact traces/metrics setup as the template:

  • LoggerProvider + BatchLogRecordProcessor + OTLPLogExporter (HTTP — matches the traces/metrics exporter protocol), plus a stdlib LoggingHandler attached to the root logger so ordinary logging calls become OTel log records.
  • Same endpoint (/v1/logs), auth (static token or M2M via new AuthInjectingLogExporter), and enable/skip_start path as traces. No new config keys, no new dependencies — the log exporter ships in the existing otlp extra and the logs SDK in opentelemetry-sdk.
  • bootstrap derives /v1/logs from SMOOAI_OBSERVABILITY_ENDPOINT.

Correlation (verified)

The LoggingHandler reads the active span context per record, so logs emitted inside a span carry the real W3C trace_id/span_id. Verified with an in-memory log exporter against the exact handler class the setup attaches (tests/test_otel_logs.py) — not just a compile. Disabled/skip_start is a graceful no-op that leaves the root logger untouched.

Tests

python/tests/test_otel_logs.py — wiring, root-logger-untouched-when-skipped, log-in-span carries real ids, log-outside-span has no trace context. Full Python suite: 70 passed, ruff lint + format clean.

🤖 Generated with Claude Code

Adds the logs signal alongside the existing traces + metrics OTLP setup in
setup_otel_sdk: a LoggerProvider + BatchLogRecordProcessor + OTLPLogExporter
(HTTP, matching the traces/metrics exporter protocol) plus a stdlib
LoggingHandler attached to the root logger so ordinary `logging` calls become
OTel log records. Reuses the SAME endpoint (/v1/logs), auth (static token or
M2M AuthInjectingLogExporter), and enable/skip_start path as traces — no new
config keys and no new dependencies (the log exporter ships in the existing
otlp extra, the logs SDK in opentelemetry-sdk).

The LoggingHandler reads the ACTIVE span context per record, so logs emitted
inside a span carry the real W3C trace_id/span_id — verified with an in-memory
exporter against the exact handler class the setup attaches. Disabled/skip_start
is a graceful no-op that leaves the root logger untouched.

bootstrap derives the /v1/logs endpoint from SMOOAI_OBSERVABILITY_ENDPOINT.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S2bM94GAnVjYSSv1x7HKRB
@changeset-bot

changeset-bot Bot commented Jul 20, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 19b3079

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant