Skip to content

feat(core): v0.3.0 observability release#4

Merged
seanbrar merged 1 commit intomainfrom
release/v0.3
Feb 15, 2026
Merged

feat(core): v0.3.0 observability release#4
seanbrar merged 1 commit intomainfrom
release/v0.3

Conversation

@seanbrar
Copy link
Owner

@seanbrar seanbrar commented Feb 15, 2026

Summary

Add exception tracking in scopes, a LogReporter for structured logging output, and fix three SimpleReporter rendering bugs: parent scope clobbering in the timings tree, gauges incorrectly displayed as counters, and as_dict() returning tuples instead of dicts.

Related issue

None

Test plan

8 new tests in tests/test_core.py covering all changes (23 total, all passing):

  • test_report_shows_nested_and_parent_scopes — verifies parent scopes with own data render as stats lines, not just tree headers (the clobbering bug)
  • test_report_shows_structural_headers — verifies intermediate-only nodes (e.g., a: when only a.b.c recorded) get visual header lines
  • test_as_dict_returns_dicts_with_named_keys — verifies entries use {"duration": ..., **meta} / {"value": ..., **meta} instead of tuples
  • test_report_gauge_shows_last_value — verifies gauge metrics display Last: instead of Total:
  • test_exception_metadata_recorded_on_scope_exit — verifies error, error_type, error_message are captured and exception propagates
  • test_exception_metadata_absent_on_success — verifies zero cost on happy path (no error keys in metadata)
  • test_log_reporter_emits_timing_record — verifies log level, message format, and extra dict structure

Benchmarks show no performance regression — the only hot-path change is a single if exc_type is not None: branch in _Scope.__exit__, not taken on the happy path.

uv run ruff check .           # All checks passed
uv run mypy src tests         # No issues found
uv run pytest -q              # 23 passed
uv run python benchmarks/bench_core.py  # No regression

Notes

  • Flat sorted rendering replaces tree rendering for timings: _build_hierarchy + _format_tree replaced by a single _format_timings method. Sorted scope names naturally put parents before children; structural headers provide visual grouping without the clobbering bug.
  • Scope tags/labels from the v0.3 roadmap was deferred — **metadata already covers the use case.
  • LogReporter uses nullscope.telemetry logger (not nullscope) to avoid colliding with the library's internal logger. Default level is DEBUG since telemetry is high-volume.
  • Exception tracking uses __qualname__ for error_type to correctly handle nested classes.

  • PR title follows the conventional commits style
  • make check passes
  • Tests cover the meaningful cases, not just the happy path
  • Docs updated (if this changes public API or user-facing behavior)

Add exception tracking in scopes, LogReporter for structured logging,
fix SimpleReporter rendering bugs (parent scope clobbering, gauge
display, as_dict tuple output).
@seanbrar seanbrar merged commit 8e7c805 into main Feb 15, 2026
5 checks passed
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