Add HyperDX OTel integration test path#110
Merged
Merged
Conversation
Wire an opt-in integration test against a live HyperDX endpoint via the OTLP-HTTP exporter, plus a "Production swap" section in example 03's docstring showing the same setup. The integration test (``tests/integration/test_otel_hyperdx_export.py``) is env-gated on ``HYPERDX_API_KEY`` + ``HYPERDX_OTLP_ENDPOINT`` and ``@pytest.mark.integration``; skipped by default. Verifies that the ``BatchSpanProcessor`` + ``OTLPSpanExporter`` pipeline drains cleanly within a 15s deadline. HyperDX-side acceptance is verified by the UI, not the test, because the OTel SDK swallows exporter errors silently. ``opentelemetry-exporter-otlp-proto-http`` lands in the dev dependency group only, capped ``<3`` for parity with the ``[otel]`` extras' SDK pins. Not promoted to a public extras group yet; revisit when more than one downstream user wants OTLP-HTTP export packaged.
There was a problem hiding this comment.
Pull request overview
Adds an opt-in OpenTelemetry integration test path for exporting spans to a live HyperDX (OTLP-HTTP) endpoint, plus documentation in example 03 showing how to swap the demo console exporter for a real OTLP exporter in production-like usage.
Changes:
- Add an env-gated,
@pytest.mark.integrationtest that exercisesOTelObserver+BatchSpanProcessor+OTLPSpanExporteragainst a live OTLP-HTTP endpoint. - Add dev-only dependency on
opentelemetry-exporter-otlp-proto-http(pinned>=1.27,<3) to support the integration test. - Extend example 03’s module docstring with a “Production swap” section for OTLP-HTTP exporters (e.g., HyperDX).
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| uv.lock | Adds opentelemetry-exporter-otlp-proto-http to dev dependencies in the lockfile. |
| pyproject.toml | Adds dev-only dependency pin for opentelemetry-exporter-otlp-proto-http. |
| tests/integration/test_otel_hyperdx_export.py | New env-gated integration test for OTLP-HTTP export to HyperDX. |
| examples/03-observer-hooks/main.py | Docstring update with a production exporter swap example. |
| CHANGELOG.md | Documents the new integration test path and example docs under Unreleased/Added. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The OTLPSpanExporter uses the ``endpoint`` kwarg verbatim and does not append ``/v1/traces`` itself (that auto-append is only for the host-only ``OTEL_EXPORTER_OTLP_ENDPOINT`` env-var convention this test doesn't use). A host-only URL POSTs to ``/`` and HyperDX 404s, which the OTel SDK swallows silently while ``force_flush`` still returns True — the failure mode this test calls out. Note the path-suffix requirement explicitly in the module docstring and the pytestmark skip reason so future readers don't lose half an hour to a silent failure that wasn't surfaced.
Two CoPilot findings on PR #110: 1. Integration test missed ``await graph.drain()`` between ``invoke()`` and ``observer.force_flush()``. ``invoke()`` returns when the graph reaches END, but observer events sit on a per- invocation queue until the background worker delivers them, so a span that hasn't seen its ``completed`` event yet is still open when ``force_flush`` runs. The live HyperDX run worked only because the queue drained inside the 15s flush window; under load the test could ship only ``started`` halves. 2. Example docstring suggested ``await otel_observer.force_flush()``. ``force_flush`` is synchronous (returns bool, wraps ``TracerProvider.force_flush``); the await would raise ``TypeError`` at runtime. Replaced with the canonical short-lived-process pattern: ``await graph.drain()`` then ``otel_observer.force_flush()`` (sync).
The documented requirement (env var MUST include ``/v1/traces``) was only enforced through docs, not the test itself. Because the OTel SDK swallows exporter-side errors and ``force_flush`` returns True regardless of the HTTP response, a host-only URL would POST to ``/``, HyperDX would 404, and the test would still report green. This is the silent-failure mode the test's docstring already warned about and the one we hit on this PR's manual validation. Assert the endpoint ends with ``/v1/traces`` before constructing the exporter; the assert raises with a pointer to the expected shape if the env var is misconfigured.
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.
Summary
Wire an opt-in integration test against a live HyperDX endpoint via the OTLP-HTTP exporter, plus a "Production swap" section in example 03's docstring showing the same setup.
The integration test (
tests/integration/test_otel_hyperdx_export.py) is env-gated onHYPERDX_API_KEY+HYPERDX_OTLP_ENDPOINTand@pytest.mark.integration; skipped by default. Verifies that theBatchSpanProcessor+OTLPSpanExporterpipeline drains cleanly within a 15s deadline. HyperDX-side acceptance is verified by the UI, not the test, because the OTel SDK swallows exporter errors silently.opentelemetry-exporter-otlp-proto-httplands in the dev dependency group only, capped<3for parity with the[otel]extras' SDK pins. Not promoted to a public extras group yet; revisit when more than one downstream user wants OTLP-HTTP export packaged.Closes the post-v0.10.0 follow-on item for the HyperDX integration test path.
Test plan
addopts = ["-m", "not integration"])uv run pytest tests/integration/test_otel_hyperdx_export.py -m integration -vskips on missing env varspingunder serviceopenarmature-hyperdx-integrationappears in the HyperDX UI[Unreleased]entry under### Added