Skip to content

Add /otlp/ segment to observability exporter URL paths#225

Open
Copilot wants to merge 1 commit intomainfrom
copilot/implement-changes-from-pr-229
Open

Add /otlp/ segment to observability exporter URL paths#225
Copilot wants to merge 1 commit intomainfrom
copilot/implement-changes-from-pr-229

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 9, 2026

Summary

  • Update Agent365Exporter to include /otlp/ in the trace export URL paths (both standard and S2S endpoints)
  • Aligns exporter routes with the OTLP endpoint naming convention: .../tenants/{tenantId}/otlp/agents/{agentId}/traces
  • Update corresponding test assertions to match the new URL format

Port of microsoft/Agent365-nodejs#229 to Python.

Changes

  • utils.py: Updated build_export_url() URL paths from .../tenants/{tenantId}/agents/{agentId}/traces to .../tenants/{tenantId}/otlp/agents/{agentId}/traces (both standard and S2S)
  • agent365_exporter.py: Updated docstring to reflect new URL format
  • test_agent365_exporter.py: Updated all 11 test assertions to match new URL format

Test plan

  • Updated existing exporter unit tests to validate new URL paths (19/19 passing)
  • Verify export succeeds against the updated service endpoints

Copilot AI requested a review from nikhilNava April 9, 2026 20:08
@nikhilNava nikhilNava marked this pull request as ready for review April 10, 2026 14:06
@nikhilNava nikhilNava requested a review from a team as a code owner April 10, 2026 14:06
Copilot AI review requested due to automatic review settings April 10, 2026 14:06
@github-actions
Copy link
Copy Markdown

⚠️ Deprecation Warning: The deny-licenses option is deprecated for possible removal in the next major release. For more information, see issue 997.

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Snapshot Warnings

⚠️: No snapshots were found for the head SHA 4a38ef6.
Ensure 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 Files

None

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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() concatenates endpoint and endpoint_path directly. If endpoint is configured with a trailing slash (e.g. https://example.com/) or includes a path (allowed today by get_validated_domain_override() for scheme URLs), this will produce URLs like https://example.com//observability/... or https://example.com/foo/observability/..., which can lead to incorrect routing/404s depending on the server. Consider normalizing endpoint (e.g., stripping trailing / and/or rejecting non-empty parsed.path for overrides) or constructing the URL via urllib.parse joins 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"

Comment on lines +49 to +50
* 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
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
* 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

Copilot uses AI. Check for mistakes.
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)

Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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)

Copilot uses AI. Check for mistakes.
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.

3 participants