Skip to content

Commit 9d61c96

Browse files
rido-minclaude
andcommitted
Add AI/LLM instrumentation section with AIBotWithOTel sample reference
- Add "AI and LLM Instrumentation" section to blog post and in-depth guide - Show UseOpenTelemetry() on IChatClient pipeline and AI/MCP source registration - Add Application Insights AI bot trace screenshot showing chat completions and MCP tool calls - Link to AIBotWithOTel sample Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 5b5d4f5 commit 9d61c96

5 files changed

Lines changed: 86 additions & 0 deletions

File tree

70 KB
Loading

teams.md/blog/2026-06-09-opentelemetry-observability/index.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,31 @@ Here is the same turn in Grafana Tempo — the span waterfall with span attribut
166166

167167
![Grafana Tempo trace view showing 6 spans for a bot turn with expanded span attributes — activity.id, activity.type, bot.id, channel.id, conversation.id, and service.url](./grafana-trace.png)
168168

169+
## AI and LLM Instrumentation
170+
171+
If your bot calls AI models through [`Microsoft.Extensions.AI`](https://learn.microsoft.com/dotnet/ai/ai-extensions), you can trace LLM calls and tool invocations as part of the same turn. Add `.UseOpenTelemetry()` to the `IChatClient` pipeline:
172+
173+
```csharp
174+
IChatClient chatClient = innerClient
175+
.AsBuilder()
176+
.UseFunctionInvocation()
177+
.UseOpenTelemetry(sourceName: "Experimental.Microsoft.Extensions.AI")
178+
.Build();
179+
```
180+
181+
Then register the AI source and meter names alongside the Teams SDK ones:
182+
183+
```csharp
184+
tracing.AddSource(["Experimental.Microsoft.Extensions.AI", "ModelContextProtocol"]);
185+
metrics.AddMeter(["Experimental.Microsoft.Extensions.AI", "ModelContextProtocol"]);
186+
```
187+
188+
Now your traces show the full chain — from the inbound Teams message, through AI model chat completions and MCP tool calls, and back out through the Bot Service response:
189+
190+
![Application Insights end-to-end transaction showing an AI bot turn — handler, orchestrate_tools, two gpt-5.4-mini chat completions, an MCP microsoft_docs_search tool call, and the outbound Bot Service response](./appinsights-aibot-trace.png)
191+
192+
For a complete example, see the [AIBotWithOTel sample](https://github.com/microsoft/teams-agent-accelerator-templates/tree/main/dotnet/AIBotWithOTel).
193+
169194
## Try It
170195

171196
The full [OTelBotWithAspire sample](https://github.com/microsoft/teams-agent-accelerator-templates/tree/main/dotnet/OTelBotWithAspire) is a ready-to-run Aspire solution with three projects:

teams.md/src/components/include/in-depth-guides/observability/opentelemetry/csharp.incl.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,61 @@ dotnet run
113113

114114
Open `http://localhost:3000` (default credentials: `admin` / `admin`) to explore Tempo for traces, Mimir for metrics, and Loki for logs.
115115

116+
<!-- ai-instrumentation -->
117+
118+
### Step 1: Add the OpenTelemetry middleware to the chat client
119+
120+
When building the `IChatClient` pipeline, call `.UseOpenTelemetry()` to emit spans for each chat completion and tool invocation:
121+
122+
```csharp
123+
using Azure.AI.OpenAI;
124+
using Microsoft.Extensions.AI;
125+
126+
IChatClient innerClient = new AzureOpenAIClient(new Uri(endpoint), new Azure.AzureKeyCredential(key))
127+
.GetChatClient(deployment)
128+
.AsIChatClient();
129+
130+
IChatClient chatClient = innerClient
131+
.AsBuilder()
132+
.UseFunctionInvocation()
133+
.UseOpenTelemetry(sourceName: "Experimental.Microsoft.Extensions.AI")
134+
.Build();
135+
```
136+
137+
The `sourceName` parameter determines the `ActivitySource` name used for the emitted spans. If you use [Model Context Protocol (MCP)](https://learn.microsoft.com/dotnet/ai/model-context-protocol) tools, the MCP client also emits its own spans under the `"ModelContextProtocol"` source.
138+
139+
### Step 2: Register the AI source and meter names
140+
141+
Add the AI and MCP source/meter names alongside the Teams SDK ones in your OpenTelemetry configuration:
142+
143+
```csharp
144+
builder.Services.AddOpenTelemetry()
145+
.WithTracing(tracing =>
146+
{
147+
// Teams SDK sources
148+
tracing.AddSource([CoreTelemetryNames.ActivitySourceName,
149+
TeamsBotApplicationTelemetry.ActivitySourceName]);
150+
// AI / MCP sources
151+
tracing.AddSource(["Experimental.Microsoft.Extensions.AI",
152+
"ModelContextProtocol"]);
153+
})
154+
.WithMetrics(metrics =>
155+
{
156+
// Teams SDK meters
157+
metrics.AddMeter([CoreTelemetryNames.MeterName,
158+
TeamsBotApplicationTelemetry.MeterName]);
159+
// AI / MCP meters
160+
metrics.AddMeter(["Experimental.Microsoft.Extensions.AI",
161+
"ModelContextProtocol"]);
162+
});
163+
```
164+
165+
With both steps in place, your traces show the full chain — from the inbound Teams message, through turn and handler processing, into AI model chat completions and tool calls, and back out through the Bot Service response:
166+
167+
![Application Insights end-to-end transaction showing an AI bot turn — handler, orchestrate_tools, two gpt-5.4-mini chat completions, an MCP microsoft_docs_search tool call, and the outbound Bot Service response](/screenshots/appinsights-aibot-trace.png)
168+
169+
For a complete working example, see the [AIBotWithOTel sample](https://github.com/microsoft/teams-agent-accelerator-templates/tree/main/dotnet/AIBotWithOTel).
170+
116171
<!-- resource-config -->
117172

118173
[Resource attributes](https://learn.microsoft.com/azure/azure-monitor/app/opentelemetry-configuration#set-the-cloud-role-name-and-the-cloud-role-instance) identify your service in the backend. At a minimum, set `service.name` so your bot is distinguishable in Application Map and trace views:

teams.md/src/pages/templates/in-depth-guides/observability/opentelemetry.mdx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ Here is the same turn in Grafana Tempo — the span waterfall with span attribut
9292

9393
![Grafana Tempo trace view showing 6 spans for a bot turn with expanded span attributes — activity.id, activity.type, bot.id, channel.id, conversation.id, and service.url](/screenshots/grafana-otel-trace.png)
9494

95+
## AI and LLM Instrumentation
96+
97+
If your bot calls AI models through [`Microsoft.Extensions.AI`](https://learn.microsoft.com/dotnet/ai/ai-extensions), you can add OpenTelemetry instrumentation to capture LLM spans (chat completions, token usage) and tool-call spans (MCP or function invocation) as part of the same trace. These spans appear as children of the bot's `handler` span, giving you end-to-end visibility from the inbound Teams message through AI model calls and back.
98+
99+
<LanguageInclude section="ai-instrumentation" />
100+
95101
## Resource Configuration
96102

97103
<LanguageInclude section="resource-config" />
70 KB
Loading

0 commit comments

Comments
 (0)