Modern AI-powered applications rarely consist of a single service. A typical enterprise solution may include an API Gateway, authentication service, retrieval service, vector database, AI orchestration layer, Large Language Model (LLM), caching layer, and multiple downstream business services. When an AI request fails or experiences high latency, identifying the root cause can be challenging without end-to-end observability.
Traditional logging provides isolated events, but it doesn't show how a request travels across distributed systems. This is where OpenTelemetry becomes invaluable.
OpenTelemetry enables distributed tracing by assigning a unique trace to each request, allowing developers to follow an AI request from the client to every service it touches. This article explores how to implement AI request tracing in ASP.NET Core microservices using OpenTelemetry, along with practical production considerations.
Why AI Workloads Need Distributed Tracing
Unlike standard REST APIs, AI requests often involve multiple components before a response is generated.
For example:
Client
│
API Gateway
│
Authentication Service
│
Prompt Builder
│
Vector Database
│
LLM Provider
│
Business Service
│
Response
A delay in any of these components can increase the overall response time. Distributed tracing helps identify where time is spent and where failures occur.
What Is OpenTelemetry?
OpenTelemetry is an open standard for collecting:
Traces
Metrics
Logs
It provides vendor-neutral instrumentation, allowing telemetry to be exported to different observability platforms.
The three primary telemetry signals are:
| Signal | Purpose |
|---|---|
| Traces | Track requests across services |
| Metrics | Measure application performance |
| Logs | Capture application events |
Together, these signals provide a comprehensive view of application behavior.
Understanding Trace Hierarchy
Each distributed request consists of:
One Trace
Multiple Spans
Trace
│
├── API Gateway
│
├── Authentication
│
├── Prompt Builder
│
├── Vector Search
│
├── AI Provider
│
└── Response Formatter
Each span represents an operation performed during the request lifecycle.
Adding OpenTelemetry to ASP.NET Core
Register OpenTelemetry during application startup.
builder.Services.AddOpenTelemetry()
.WithTracing(builder =>
{
builder.AddAspNetCoreInstrumentation();
builder.AddHttpClientInstrumentation();
});
This automatically captures incoming ASP.NET Core requests and outgoing HTTP calls.
Creating Custom Activities
AI-specific operations often deserve their own spans.
private static readonly ActivitySource ActivitySource =
new("Enterprise.AI");
using var activity = ActivitySource.StartActivity(
"VectorSearch");
Custom activities make traces easier to understand by highlighting important business operations.
Tracing AI Provider Calls
Suppose your application sends prompts to an AI provider.
using var activity = ActivitySource.StartActivity(
"LLMCompletion");
activity?.SetTag("ai.provider", "AzureOpenAI");
activity?.SetTag("ai.operation", "ChatCompletion");
Adding descriptive tags makes traces more useful during diagnostics.
Avoid storing sensitive prompts or personally identifiable information as trace attributes unless organizational policies explicitly allow it.
Instrumenting Vector Search
Vector retrieval is often a significant part of AI latency.
using var activity =
ActivitySource.StartActivity("VectorSearch");
await vectorStore.SearchAsync(query);
Tracing this step separately helps distinguish retrieval delays from model inference delays.
Propagating Trace Context
Distributed tracing depends on passing trace context between services.
Gateway
│
Trace Context
│
Search Service
│
Trace Context
│
AI Service
When services propagate the trace context correctly, observability platforms can reconstruct the complete request path.
Useful AI Trace Attributes
Consider enriching spans with metadata that supports diagnostics without exposing sensitive content.
| Attribute | Example |
|---|---|
| ai.provider | Azure OpenAI |
| ai.operation | Chat Completion |
| ai.model | Deployment or model identifier |
| ai.request.id | Correlation identifier |
| retrieval.source | Vector Database |
| response.status | Success or Failure |
Join the conversation! Your thoughts help the community grow.