-
Notifications
You must be signed in to change notification settings - Fork 57
Native instrumentation with OpenTelemetry #329
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
168bad8
62e9eb1
b4d8e60
8cc8757
d17a161
8d2266a
e306fa8
d0acb1d
d7fad12
d75395f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,137 @@ | ||||||||||
| import pytest | ||||||||||
|
|
||||||||||
| from opentelemetry import trace, metrics | ||||||||||
| from opentelemetry.sdk.trace import TracerProvider | ||||||||||
| from opentelemetry.sdk.trace.export import SimpleSpanProcessor | ||||||||||
| from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter | ||||||||||
| from opentelemetry.sdk.metrics import MeterProvider | ||||||||||
| from opentelemetry.sdk.metrics.export import InMemoryMetricReader | ||||||||||
|
|
||||||||||
| from ...scenarios import load_scenario | ||||||||||
|
|
||||||||||
| _SCENARIO = load_scenario("quickstart", use_jwt_middleware=False) | ||||||||||
|
|
||||||||||
| @pytest.fixture(scope="module") | ||||||||||
| def test_telemetry(): | ||||||||||
| """Set up fresh in-memory exporter for testing.""" | ||||||||||
| exporter = InMemorySpanExporter() | ||||||||||
| metric_reader = InMemoryMetricReader() | ||||||||||
|
|
||||||||||
| tracer_provider = TracerProvider() | ||||||||||
| tracer_provider.add_span_processor(SimpleSpanProcessor(exporter)) | ||||||||||
| trace.set_tracer_provider(tracer_provider) | ||||||||||
|
|
||||||||||
| meter_provider = MeterProvider([metric_reader]) | ||||||||||
|
|
||||||||||
| metrics.set_meter_provider(meter_provider) | ||||||||||
|
|
||||||||||
| yield exporter, metric_reader | ||||||||||
|
|
||||||||||
| exporter.clear() | ||||||||||
| tracer_provider.shutdown() | ||||||||||
| meter_provider.shutdown() | ||||||||||
|
|
||||||||||
| @pytest.fixture(scope="function") | ||||||||||
| def test_exporter(test_telemetry): | ||||||||||
| """Provide the in-memory span exporter for each test.""" | ||||||||||
| exporter, _ = test_telemetry | ||||||||||
| return exporter | ||||||||||
|
|
||||||||||
| @pytest.fixture(scope="function") | ||||||||||
| def test_metric_reader(test_telemetry): | ||||||||||
| """Provide the in-memory metric reader for each test.""" | ||||||||||
| _, metric_reader = test_telemetry | ||||||||||
| return metric_reader | ||||||||||
|
|
||||||||||
| @pytest.fixture(autouse=True, scope="function") | ||||||||||
| def clear(test_exporter, test_metric_reader): | ||||||||||
| """Clear spans before each test to ensure test isolation.""" | ||||||||||
| test_exporter.clear() | ||||||||||
| test_metric_reader.force_flush() | ||||||||||
|
|
||||||||||
| @pytest.mark.asyncio | ||||||||||
| @pytest.mark.agent_test(_SCENARIO) | ||||||||||
| async def test_basic(test_exporter, agent_client): | ||||||||||
| """Test that spans are created for a simple scenario.""" | ||||||||||
|
|
||||||||||
| await agent_client.send_expect_replies("Hello!") | ||||||||||
|
|
||||||||||
|
||||||||||
Copilot
AI
Feb 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inefficient list comprehension: Lines 123-124 use list comprehensions that include all spans (with None for non-matching ones) instead of filtering. This is inefficient and incorrect. Replace with: [span for span in spans if span.name == "agent turn"] and similarly for "adapter process".
| assert len([ span if span.name == "agent turn" else None for span in spans ]) == 2 | |
| assert len([ span if span.name == "adapter process" else None for span in spans ]) == 2 | |
| assert len([span for span in spans if span.name == "agent turn"]) == 2 | |
| assert len([span for span in spans if span.name == "adapter process"]) == 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused import: The 'base' module from email.mime is imported on line 13 but never used. Remove this import.