feat(observability): default-on OTLP export beside JSONL traces - #93
Conversation
🤖 CodeAnt AI — Review Status
|
Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
|
@greptileai please review |
Greptile SummaryThe PR adds default-on OTLP/HTTP export alongside the durable JSONL trace and wires each session through a composite tracer.
Confidence Score: 4/5The partial-entry cleanup defect should be fixed before merging because an OTel span-start failure can mask its cause, leave the JSONL span unclosed, and abort the session. CompositeTracer tracks successful entries separately but unwinds the full manager list, so a later child entry failure invokes cleanup on an unentered context manager before the successfully entered JSONL manager can be closed. Files Needing Attention: src/dream/observability/_composite.py
|
| Filename | Overview |
|---|---|
| src/dream/observability/_composite.py | Adds multi-sink span and event fan-out, but its partial-entry exception cleanup exits unentered managers and can leave entered spans unclosed. |
| src/dream/observability/_otel_provider.py | Adds lazy process-wide provider construction, batch export, caching, and atexit shutdown. |
| src/dream/observability/_otel_tracer.py | Adapts Dream tracer spans and events to OTel spans with nesting, attributes, and error status. |
| src/dream/observability/_factory.py | Builds JSONL-only or composite session tracers according to the OTel opt-out configuration. |
| src/dream/_factory.py | Replaces direct JSONL tracer construction with the new session tracer factory. |
| src/dream/observability/_otel_config.py | Implements default-on environment configuration with standard SDK disable handling and endpoint defaults. |
| evals/otel/eval_cross_repo.py | Adds a manually invoked cross-repository evaluation runner with configurable repository roots. |
| pyproject.toml | Promotes the OpenTelemetry API, SDK, and OTLP HTTP exporter to core dependencies. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
S[Session engine] --> C[CompositeTracer]
C --> J[JsonlTracer]
C --> O[OtelTracer]
J --> F[Durable JSONL trace]
O --> B[BatchSpanProcessor]
B --> E[OTLP HTTP endpoint]
Prompt To Fix All With AI
### Issue 1
src/dream/observability/_composite.py:42-45
**Unentered span managers are exited**
When a later tracer raises during `__enter__`, this branch calls `__exit__` on every manager, including those that never entered. The resulting context-manager error masks the original failure and prevents the already-entered JSONL span from closing, leaving an incomplete trace and aborting the session.
```suggestion
except BaseException as exc:
for manager in reversed(managers[: len(spans)]):
manager.__exit__(type(exc), exc, exc.__traceback__)
raise
```
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "fix(otel): make cross-repo eval paths po..." | Re-trigger Greptile
| except BaseException as exc: | ||
| for manager in reversed(managers): | ||
| manager.__exit__(type(exc), exc, exc.__traceback__) | ||
| raise |
There was a problem hiding this comment.
Unentered span managers are exited
When a later tracer raises during __enter__, this branch calls __exit__ on every manager, including those that never entered. The resulting context-manager error masks the original failure and prevents the already-entered JSONL span from closing, leaving an incomplete trace and aborting the session.
| except BaseException as exc: | |
| for manager in reversed(managers): | |
| manager.__exit__(type(exc), exc, exc.__traceback__) | |
| raise | |
| except BaseException as exc: | |
| for manager in reversed(managers[: len(spans)]): | |
| manager.__exit__(type(exc), exc, exc.__traceback__) | |
| raise |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/dream/observability/_composite.py
Line: 42-45
Comment:
**Unentered span managers are exited**
When a later tracer raises during `__enter__`, this branch calls `__exit__` on every manager, including those that never entered. The resulting context-manager error masks the original failure and prevents the already-entered JSONL span from closing, leaving an incomplete trace and aborting the session.
```suggestion
except BaseException as exc:
for manager in reversed(managers[: len(spans)]):
manager.__exit__(type(exc), exc, exc.__traceback__)
raise
```
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Add bounded default-on OTLP export as an additive typed sink while preserving JSONL durability and explicit collector-free opt-out. Co-authored-by: Cursor <cursoragent@cursor.com>
59937ea to
9652a21
Compare
Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
There was a problem hiding this comment.
divo12 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
User description
Summary
OpenTelemetry OTLP/HTTP export is default-on, not opt-in: the SDK ships in core
dependenciesand every session fans its Spec 12a JSONL trace to OTel throughCompositeTracer+BatchSpanProcessor. JSONL stays the durable substrate; OTel is the additive sink.Opt out with
OTEL_SDK_DISABLED=true(no provider, no exporter, JSONL only). Two consequences a reader should know, both measured on this branch with no collector listening on:4318:Failed to export span batch due to timeout, max retries or shutdown, adding ~6 s per process. SetOTEL_SDK_DISABLED=truewhere no collector exists.A missing/broken OTel provider degrades to JSONL-only and warns exactly once per process via
warnings.warn—loggingis banned insrc/by an invariant test, so this path deliberately useswarnings, not a logger.Gap analysis vs hermes-otel / Paperclip / chorus §4 lives in
docs/specs/divo/otel-architecture-gap.md; the cross-repo eval resolves its repo roots fromDREAM_REPO_ROOT/CHORUS_REPO_ROOT(defaulting to this checkout and its../chorussibling) rather than hard-coded developer paths.Type
Checklist
tests/test_public_api.pyupdated if the public API changedCHANGELOG.mdupdated for user-visible changes.env.local, or credentials in the diffdream(org/company features belong in sibling repos)Test plan
uv sync --all-extrasuv run pytest tests/test_observability/ -q— 76 passeduv run python evals/otel/eval_step1_foundation.pyuv run ruff check src tests/uv run mypyLink to Devin session: https://app.devin.ai/sessions/4f7deb4af0914056a24a4d660a661713
Requested by: @divo12
CodeAnt-AI Description
Export session traces to OpenTelemetry by default while preserving JSONL traces
What Changed
http://localhost:4318by default and supports custom endpoints and service metadata through environment settings.OTEL_SDK_DISABLED=trueto keep JSONL-only tracing; if the OTel provider cannot start, sessions continue with JSONL and emit one warning.Impact
✅ Traces available in OpenTelemetry collectors by default✅ JSONL traces remain available when OTLP is disabled or unavailable✅ Fewer shutdown hangs from unavailable collectors💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.