Implementing OpenTelemetry Logging in .NET Applications with OpenObserve

Effective logging is crucial for understanding and troubleshooting application behavior. In .NET applications, OpenTelemetry provides a standardized way to collect and export logs alongside traces and metrics.
In this comprehensive guide, you'll learn how to implement OpenTelemetry logging in a .NET 6+ Web API application and visualize logs using OpenObserve.
OpenTelemetry offers several advantages for logging in .NET applications:
Before we begin, ensure you have:
We'll use our order processing API to demonstrate logging implementation. The application already has tracing configured, and we'll add logging to provide more detailed insights into its operation.
git clone https://github.com/openobserve/dotnet-opentelemetry-tracing-application
cd dotnet-opentelemetry-tracing-application
Add the OpenTelemetry logging packages to your project:
dotnet add package OpenTelemetry.Extensions.Logging --version 1.7.0
dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol --version 1.7.0
Configure OpenTelemetry logging in your Program.cs
:
builder.Logging.ClearProviders();
var resourceBuilder = ResourceBuilder.CreateDefault()
.AddService("OrderProcessingService")
.AddAttributes(new Dictionary<string, object>
{
["environment"] = "development",
["service.version"] = "1.0.0"
});
builder.Logging.AddOpenTelemetry(logging => {
logging.IncludeFormattedMessage = true;
logging.SetResourceBuilder(resourceBuilder)
.AddConsoleExporter()
.AddOtlpExporter(otlpOptions => {
otlpOptions.Endpoint = new Uri("your_openobserve_url/v1/logs");
otlpOptions.Headers = "Authorization=Basic YOUR_AUTH_TOKEN";
otlpOptions.Protocol = OpenTelemetry.Exporter.OtlpExportProtocol.HttpProtobuf;
});
});
Note: Replace the placeholder values with your OpenObserve details:
- Add
/v1/logs
to your OTLP HTTP endpoint- Use your Base64 encoded credentials in the Authorization header
Example of logging in an API controller:
[ApiController]
[Route("[controller]")]
public class OrderController : ControllerBase
{
private readonly ILogger<OrderController> _logger;
public OrderController(ILogger<OrderController> logger)
{
_logger = logger;
}
[HttpPost]
public async Task<IActionResult> CreateOrder(Order order)
{
_logger.LogInformation(
"Creating order for customer: {CustomerName} with amount: {Amount}",
order.CustomerName,
order.Amount
);
try
{
// Order processing logic...
return Ok(order);
}
catch (Exception ex)
{
_logger.LogError(
ex,
"Failed to create order for customer {CustomerName}",
order.CustomerName
);
throw;
}
}
}
Run your application:
dotnet run
Send some test requests to generate logs:
# Create an order
curl -X POST http://localhost:5069/order \
-H "Content-Type: application/json" \
-d '{"customerName":"Test User","amount":150.00}'
# Try to get a non-existent order (generates warning logs)
curl http://localhost:5069/order/999
default
logs stream containing:OpenTelemetry automatically correlates logs with traces in your application. When you make a request:
[HttpPost]
public async Task<IActionResult> CreateOrder(Order order)
{
_logger.LogInformation(
"Creating order for customer: {CustomerName} with amount: {Amount}",
order.CustomerName,
order.Amount
);
using var activity = TracingInstrumentation.ActivitySource.StartActivity("CreateOrder");
}
Each log entry includes:
If you're not seeing logs in OpenObserve:
/v1/logs
Now that you have OpenTelemetry logging set up in your .NET application:
Need help? Join our Slack community for support.
Happy Monitoring! 🚀