feat(examples): metrics and StreamMetricExporter in the OTel example - #90
Merged
Merged
Conversation
examples/otel/metrics.py publishes OTel metric collections to a stream, one row per data point. It covers sums, gauges and both histogram kinds, keeps exemplars, and asks for delta temporality for counters and histograms so a window's total is a sum(). The services count orders by outcome and record http.server.request.duration inside their spans. export.py regroups metric rows into MetricsData for OTel's OTLP metric exporter. just demo otel moves to otel-gui 3.0.0, the first release to accept metrics, and warms its metrics decoder too: the lazy-load race that crashes it is unchanged in 3.0.0 (5 of 5 fresh instances died with all three signals at once; none after warming). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FsSDkeb5rVAxA1FSmKKfQi
As the migration demo does: a run this short never fills a log enough to seal it. Its five maintainer processes were still opening the logs when the run ended, so they did nothing but cost time and print tracebacks on SIGTERM. demo.main took 3-11 s with them and about 1 s without, and the OTel test file went from 14.5 s to 4 s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FsSDkeb5rVAxA1FSmKKfQi
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.
Adds metrics to the OTel example: an exporter that publishes OTel metrics to a stream, metrics from the two services, re-export to OTLP, and the dashboard's Metrics tab.
What
examples/otel/metrics.py:StreamMetricExporter, an OTelMetricExporterthat publishes each collection to a stream, one row per data point.value_int/value_double), so an int64 counter never rounds through a double.deltapreference; up-down counters stay cumulative. Each row is then what happened in its own interval, so a window's total is asum(). otel-gui charts sum rates correctly for either temporality.services.py: checkout countsshop.ordersby outcome. Both services recordhttp.server.request.duration(OTel's semantic convention) inside their server spans, so exemplars link to traces. Exported every second.export.py: regroups metric rows every half second intoMetricsData(resource → scope → metric), handed to OTel'sOTLPMetricExporter. Metrics have no batch processor to hand a point to.demo.py: a third stream. The one-shot run reports orders by outcome, mean request duration per service, and the failed order's exemplar, which is the failed request's trace id.gui.py: otel-gui 2.1.0 → 3.0.0, the first release that accepts metrics (2.1.0 answers/v1/metricswith 501).warm()now also warms metrics. The lazy-load crash is unchanged in 3.0.0: with all three signals' first requests at once, a fresh otel-gui died 5 times in 5. Warming in turn: 0 of 5. 3.0.0 loads the metrics decoder into the same shared protobuf root (initProtobufMetrics).examples/README.mdand the CHANGELOG.Second commit: the one-shot demo runs without a maintainer
This matches the migration demo. Profiling showed the one-shot demo's time going to its five maintainer processes:
recover(), printing tracebacks.demo.maintook 3–11 s with them, about 1 s without. The OTel test file went from 14.5 s to 4 s; each demo test is now under 1 s.just demo otel's broker keeps them.Kept as a separate commit so it can be reviewed or dropped on its own.
Tests
metrics_data, encodes to identical OTLP with OTel's own encoder, exemplars included./v1/metricstoo.[0, 1, 0]; the test data is now asymmetric.just demo otelran with otel-gui 3.0.0, and otel-gui's own API listedshop.ordersandhttp.server.request.durationfor both services. No errors in any process or in otel-gui's log.Found, not fixed here
A maintainer that gets SIGTERM while still opening its logs raises
KeyboardInterruptinside litelink'srecover(), mid-SQLite. That's thecannot rollback - no transaction is activemessage. It's pre-existing, and separate from this PR.🤖 Generated with Claude Code
https://claude.ai/code/session_01FsSDkeb5rVAxA1FSmKKfQi