Add /otlp/ segment to observability exporter URL paths#225
Add /otlp/ segment to observability exporter URL paths#225
Conversation
Agent-Logs-Url: https://github.com/microsoft/Agent365-python/sessions/15f00c02-8b53-473e-857f-ad6ba3a9e1bb Co-authored-by: nikhilNava <211831449+nikhilNava@users.noreply.github.com>
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Snapshot WarningsEnsure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice. Scanned FilesNone |
There was a problem hiding this comment.
Pull request overview
Updates the Agent365 observability HTTP exporter URL routing to include an /otlp/ path segment, aligning Python’s exporter endpoints with the service’s OTLP-style route naming.
Changes:
- Update
build_export_url()to emit.../tenants/{tenantId}/otlp/agents/{agentId}/traces(standard + S2S). - Refresh exporter docstring endpoint examples to reflect the new URL format.
- Update unit test assertions to match the new URL paths.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| libraries/microsoft-agents-a365-observability-core/microsoft_agents_a365/observability/core/exporters/utils.py | Adds /otlp/ segment to constructed export paths. |
| libraries/microsoft-agents-a365-observability-core/microsoft_agents_a365/observability/core/exporters/agent365_exporter.py | Updates docstring to reflect new endpoint routes. |
| tests/observability/core/test_agent365_exporter.py | Updates expected URL strings in exporter tests for the new route format. |
Comments suppressed due to low confidence (1)
libraries/microsoft-agents-a365-observability-core/microsoft_agents_a365/observability/core/exporters/utils.py:232
build_export_url()concatenatesendpointandendpoint_pathdirectly. Ifendpointis configured with a trailing slash (e.g.https://example.com/) or includes a path (allowed today byget_validated_domain_override()for scheme URLs), this will produce URLs likehttps://example.com//observability/...orhttps://example.com/foo/observability/..., which can lead to incorrect routing/404s depending on the server. Consider normalizingendpoint(e.g., stripping trailing/and/or rejecting non-emptyparsed.pathfor overrides) or constructing the URL viaurllib.parsejoins to avoid accidental double slashes/path stacking.
endpoint_path = (
f"/observabilityService/tenants/{tenant_id}/otlp/agents/{agent_id}/traces"
if use_s2s_endpoint
else f"/observability/tenants/{tenant_id}/otlp/agents/{agent_id}/traces"
)
parsed = urlparse(endpoint)
if parsed.scheme and "://" in endpoint:
return f"{endpoint}{endpoint_path}?api-version=1"
return f"https://{endpoint}{endpoint_path}?api-version=1"
| * POSTs per group to https://{endpoint}/observability/tenants/{tenantId}/otlp/agents/{agentId}/traces?api-version=1 | ||
| * or, when use_s2s_endpoint is True, https://{endpoint}/observabilityService/tenants/{tenantId}/otlp/agents/{agentId}/traces?api-version=1 |
There was a problem hiding this comment.
The docstring examples use https://{endpoint}/..., but in practice endpoint may already include the scheme (e.g. default DEFAULT_ENDPOINT_URL is https://...). To avoid confusion for maintainers and consumers, consider rewording the example to indicate endpoint can be a full base URL (including scheme) or a bare domain, matching build_export_url() behavior.
| * POSTs per group to https://{endpoint}/observability/tenants/{tenantId}/otlp/agents/{agentId}/traces?api-version=1 | |
| * or, when use_s2s_endpoint is True, https://{endpoint}/observabilityService/tenants/{tenantId}/otlp/agents/{agentId}/traces?api-version=1 | |
| * POSTs per group to {base_url}/observability/tenants/{tenantId}/otlp/agents/{agentId}/traces?api-version=1 | |
| * or, when use_s2s_endpoint is True, {base_url}/observabilityService/tenants/{tenantId}/otlp/agents/{agentId}/traces?api-version=1 | |
| * where base_url may be a full URL including scheme (for example, https://agent365.svc.cloud.microsoft) | |
| * or a bare domain, matching build_export_url() behavior |
| expected_url = "http://localhost:8080/observability/tenants/test-tenant-123/agents/test-agent-456/traces?api-version=1" | ||
| expected_url = "http://localhost:8080/observability/tenants/test-tenant-123/otlp/agents/test-agent-456/traces?api-version=1" | ||
| self.assertEqual(url, expected_url) | ||
|
|
There was a problem hiding this comment.
Given build_export_url() currently allows A365_OBSERVABILITY_DOMAIN_OVERRIDE values with a scheme to include a trailing / or path segment, it would be valuable to add a unit test covering an override like https://override.example.com/ (and/or https://override.example.com/base) to lock in the expected behavior (either normalization or rejection). This will prevent regressions where a common configuration style results in a malformed export URL.
| def test_export_uses_valid_url_override_with_trailing_slash(self): | |
| """Test that domain override with https:// and trailing slash is normalized correctly.""" | |
| # Arrange | |
| os.environ["A365_OBSERVABILITY_DOMAIN_OVERRIDE"] = "https://override.example.com/" | |
| # Create exporter after setting environment variable | |
| exporter = _Agent365Exporter( | |
| token_resolver=self.mock_token_resolver, cluster_category="test" | |
| ) | |
| spans = [self._create_mock_span("test_span")] | |
| # Mock the _post_with_retries method | |
| with patch.object(exporter, "_post_with_retries", return_value=True) as mock_post: | |
| # Act | |
| result = exporter.export(spans) | |
| # Assert | |
| self.assertEqual(result, SpanExportResult.SUCCESS) | |
| mock_post.assert_called_once() | |
| # Verify the call arguments - should not introduce a double slash | |
| args, kwargs = mock_post.call_args | |
| url, body, headers = args | |
| expected_url = "https://override.example.com/observability/tenants/test-tenant-123/otlp/agents/test-agent-456/traces?api-version=1" | |
| self.assertEqual(url, expected_url) |
Summary
Agent365Exporterto include/otlp/in the trace export URL paths (both standard and S2S endpoints).../tenants/{tenantId}/otlp/agents/{agentId}/tracesPort of microsoft/Agent365-nodejs#229 to Python.
Changes
utils.py: Updatedbuild_export_url()URL paths from.../tenants/{tenantId}/agents/{agentId}/tracesto.../tenants/{tenantId}/otlp/agents/{agentId}/traces(both standard and S2S)agent365_exporter.py: Updated docstring to reflect new URL formattest_agent365_exporter.py: Updated all 11 test assertions to match new URL formatTest plan