Skip to content

Add GenAI main agent attribution processors for spans and logs#59368

Merged
rajkumar-rangaraj merged 7 commits into
mainfrom
feature/genai-main-agent-attribution
May 20, 2026
Merged

Add GenAI main agent attribution processors for spans and logs#59368
rajkumar-rangaraj merged 7 commits into
mainfrom
feature/genai-main-agent-attribution

Conversation

@rajkumar-rangaraj

Copy link
Copy Markdown
Member

Implement automatic propagation of microsoft.gen_ai.main_agent.* attributes from parent spans to child spans and from active spans to log records, enabling end-to-end tracing of AI agent orchestration.

  • MainAgentAttributionSpanProcessor: propagates main agent attributes from parent to child spans on OnStart, and copies gen_ai.agent.* to microsoft.gen_ai.main_agent.* on invoke_agent spans in OnEnd
  • MainAgentAttributionLogProcessor: propagates main agent attributes from Activity.Current to log records
  • Registered in both DI (UseAzureMonitorExporter) and non-DI (AddAzureMonitorTraceExporter/AddAzureMonitorLogExporter) paths
  • Switch AspNetCore distro to ProjectReference for local dev
  • 12 unit tests + 16 integration tests passing

Contributing to the Azure SDK

Please see our CONTRIBUTING.md if you are not familiar with contributing to this repository or have questions.

For specific information about pull request etiquette and best practices, see this section.

Copilot AI review requested due to automatic review settings May 20, 2026 19:02
Implement automatic propagation of microsoft.gen_ai.main_agent.*
attributes from parent spans to child spans and from active spans
to log records, enabling end-to-end tracing of AI agent orchestration.

- MainAgentAttributionSpanProcessor: propagates main agent attributes
  from parent to child spans on OnStart, and copies gen_ai.agent.*
  to microsoft.gen_ai.main_agent.* on invoke_agent spans in OnEnd
- MainAgentAttributionLogProcessor: propagates main agent attributes
  from Activity.Current to log records
- Registered in both DI (UseAzureMonitorExporter) and non-DI
  (AddAzureMonitorTraceExporter/AddAzureMonitorLogExporter) paths
- Switch AspNetCore distro to ProjectReference for local dev
- 12 unit tests + 16 integration tests passing
@rajkumar-rangaraj rajkumar-rangaraj force-pushed the feature/genai-main-agent-attribution branch from ac3de7b to b4fc25b Compare May 20, 2026 19:04
@github-actions github-actions Bot added Monitor - Distro Monitor OpenTelemetry Distro Monitor - Exporter Monitor OpenTelemetry Exporter labels May 20, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds GenAI “main agent” attribution enrichment to Azure Monitor’s OpenTelemetry exporter so microsoft.gen_ai.main_agent.* context propagates across spans and is attached to logs, enabling end-to-end correlation for multi-agent orchestration scenarios.

Changes:

  • Introduces MainAgentAttributionSpanProcessor (parent→child propagation on start + invoke_agent tag copy on end) and MainAgentAttributionLogProcessor (Activity.Current→log attributes).
  • Wires the new processors into both DI (UseAzureMonitorExporter) and non-DI (AddAzureMonitorTraceExporter / AddAzureMonitorLogExporter) registration paths, and updates distro initialization validation.
  • Adds unit tests for the new processors and updates the exporter changelog.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Internals/GenAI/MainAgentAttributeConstants.cs Defines constants for main-agent and fallback GenAI attribute keys.
sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Internals/GenAI/MainAgentAttributionSpanProcessor.cs Implements span attribute propagation and invoke_agent self-copy behavior.
sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Internals/GenAI/MainAgentAttributionLogProcessor.cs Implements copying main-agent attributes from the current Activity onto log records.
sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/ExporterRegistrationHostedService.cs Registers the new processors in the DI initialization path.
sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/AzureMonitorExporterExtensions.cs Registers the new processors in the non-DI extension methods.
sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/tests/Azure.Monitor.OpenTelemetry.Exporter.Tests/MainAgentAttributionSpanProcessorTests.cs Adds unit coverage for span propagation and invoke_agent behavior.
sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/tests/Azure.Monitor.OpenTelemetry.Exporter.Tests/MainAgentAttributionLogProcessorTests.cs Adds unit coverage for log enrichment from Activity.Current.
sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/CHANGELOG.md Documents the new GenAI main agent attribution feature.
sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/tests/Azure.Monitor.OpenTelemetry.AspNetCore.Tests/InitializationTests.cs Updates initialization assertions to detect the new processors.
sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/src/Azure.Monitor.OpenTelemetry.AspNetCore.csproj Switches distro dependency from PackageReference to ProjectReference.
Comments suppressed due to low confidence (2)

sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Internals/GenAI/MainAgentAttributionLogProcessor.cs:45

  • The comment says this is a "stack-friendly" buffer, but new KeyValuePair<string, object?>[...] allocates on the heap and is created for every log record. This doesn’t avoid allocations (a List is still allocated later) and the comment is misleading. Consider simplifying by directly adding to the merged list with a known capacity, or using a pooling approach if allocation reduction is required.
            // Collect values into a stack-friendly fixed-size buffer to avoid
            // unnecessary List allocations on every log record.
            var values = new KeyValuePair<string, object?>[s_mainAgentAttributes.Length];
            int count = 0;

sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Internals/GenAI/MainAgentAttributionLogProcessor.cs:67

  • This merges existing attributes and appends main-agent KVPs without checking for duplicates. If the log record already contains microsoft.gen_ai.main_agent.* keys, this will create duplicate keys; downstream conversion code typically keeps the first occurrence, so the appended values may be ignored. Consider only adding keys that aren’t already present, or replacing existing entries deterministically.
            var existingAttributes = logRecord.Attributes;
            var merged = new List<KeyValuePair<string, object?>>(
                (existingAttributes?.Count ?? 0) + count);

            if (existingAttributes != null)
            {
                merged.AddRange(existingAttributes);

… OnEnd

- OnStart: skip propagation if child already has the target attribute
- OnEnd: per-attribute check instead of all-or-nothing skip
- Log processor: deduplicate against existing log record attributes
- Add 3 new tests: child attr preservation, partial OnEnd fill, log dedup
- Add rationale comments for quick-check heuristic (Name/Id suffice)
- InMemoryLogRecordProcessor: actually use the attribute snapshot to
  protect against LogRecord recycling (was dead code)
- Fix misleading 'stack-friendly' comment on heap-allocated buffer
HashSet<T>(int capacity) is not available in netstandard2.0.
Per spec: if span already has ANY microsoft.gen_ai.main_agent.*
attribute, return without modifying. Reverts per-attribute OnEnd
to match spec requirements. Updates test accordingly.
Spec says 'copy it onto span' without a child-guard qualifier.
Remove the per-attribute skip in OnStart to match spec exactly.
This was referenced Jun 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Monitor - Distro Monitor OpenTelemetry Distro Monitor - Exporter Monitor OpenTelemetry Exporter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants