diff --git a/dotnet/samples/02-agents/AgentOpenTelemetry/Program.cs b/dotnet/samples/02-agents/AgentOpenTelemetry/Program.cs index d83a0cb3f54..c0b2140a802 100644 --- a/dotnet/samples/02-agents/AgentOpenTelemetry/Program.cs +++ b/dotnet/samples/02-agents/AgentOpenTelemetry/Program.cs @@ -122,7 +122,9 @@ static async Task GetWeatherAsync([Description("The location to get the tools: [AIFunctionFactory.Create(GetWeatherAsync)], clientFactory: client => client .AsBuilder() - .UseFunctionInvocation() + // Pass ILoggerFactory so UseFunctionInvocation can log tool-execution exceptions (see #2352 / #2211). + // Alternative: pass the IServiceProvider to Build(serviceProvider) and let the pipeline resolve ILoggerFactory. + .UseFunctionInvocation(loggerFactory) .UseOpenTelemetry(sourceName: SourceName, configure: (cfg) => cfg.EnableSensitiveData = true) // enable telemetry at the chat client level .Build()) .AsBuilder() diff --git a/dotnet/samples/02-agents/AgentOpenTelemetry/README.md b/dotnet/samples/02-agents/AgentOpenTelemetry/README.md index b4852fd9fcb..bc51757b37b 100644 --- a/dotnet/samples/02-agents/AgentOpenTelemetry/README.md +++ b/dotnet/samples/02-agents/AgentOpenTelemetry/README.md @@ -81,7 +81,7 @@ Open your browser to: http://localhost:4318 #### Step 3: Run the Console Application ```powershell -cd dotnet/demos/AgentOpenTelemetry +cd dotnet/samples/02-agents/AgentOpenTelemetry $env:OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317" dotnet run ``` @@ -149,6 +149,39 @@ Open dashboard in Azure portal: Open dashboard in Azure portal: ![Workflow Overview dashboard](https://github.com/Azure/azure-managed-grafana/raw/main/samples/assets/grafana-af-workflow.gif) + +## Providing `ILoggerFactory` for tool-execution logging + +`UseFunctionInvocation` is what logs tool-execution failures (message and stack trace). OpenTelemetry spans alone are not enough to surface the exception details for troubleshooting. + +Provide an `ILoggerFactory` in one of these ways: + +### Option 1: Pass `ILoggerFactory` to `UseFunctionInvocation` + +```csharp +IChatClient instrumentedChatClient = chatClient + .AsBuilder() + .UseFunctionInvocation(loggerFactory) // logs tool failures + .UseOpenTelemetry(sourceName: SourceName, configure: cfg => cfg.EnableSensitiveData = true) + .Build(); +``` + +This sample uses this approach with the `ILoggerFactory` created earlier in `Program.cs`. + +### Option 2: Pass `IServiceProvider` to `Build` + +If logging is registered in DI, pass the service provider into `Build` so every middleware in the chain (including `UseFunctionInvocation`) can resolve `ILoggerFactory`: + +```csharp +IChatClient instrumentedChatClient = chatClient + .AsBuilder() + .UseFunctionInvocation() + .UseOpenTelemetry(sourceName: SourceName, configure: cfg => cfg.EnableSensitiveData = true) + .Build(serviceProvider); // resolves ILoggerFactory from DI +``` + +Without one of these, tool exceptions may be returned to the model as a generic failure string while the detailed exception is never logged. + ## Key Features Demonstrated ### OpenTelemetry Integration @@ -159,7 +192,7 @@ Open dashboard in Azure portal: ### Agent Framework Features - **ChatClientAgent** created from `AIProjectClient` -- **OpenTelemetry wrapper** using `.WithOpenTelemetry()` +- **OpenTelemetry wrapper** using `.UseOpenTelemetry()` on the chat client and agent builders - **Conversation threading** for multi-turn conversations - **Error handling** with telemetry correlation