Table of Contents

Building Monitoring Dashboard with Openobserve (2).png

Introduction

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.

Why OpenTelemetry for Logging?

OpenTelemetry offers several advantages for logging in .NET applications:

  • Unified logging standard across different languages and platforms
  • Seamless integration with existing .NET logging infrastructure
  • Ability to correlate logs with traces for better debugging
  • Vendor-neutral approach with support for multiple backends

Prerequisites

Before we begin, ensure you have:

Getting Started

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

Implementing OpenTelemetry Logging in .NET

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

Configuring OpenTelemetry Logging

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:

  1. Add /v1/logs to your OTLP HTTP endpoint
  2. Use your Base64 encoded credentials in the Authorization header

Adding Logs to Your Controllers

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;
        }
    }
}

Testing Your Logging Setup

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

Viewing Logs in OpenObserve

  1. Log into your OpenObserve instance
  2. Navigate to the Logs section
  3. You should see a default logs stream containing:
    • Order creation attempts
    • Successful order creations
    • Warning logs for non-existent orders

Screen Recording 2025-03-11 at 11.30.45 AM.gif

Correlating Logs with Traces

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:

  • Trace ID: Links to the corresponding distributed trace
  • Span ID: Shows which operation generated the log
  • Service name and version

Screenshot 2025-03-11 at 3.13.36 PM.png

Troubleshooting Common Issues

If you're not seeing logs in OpenObserve:

  • Verify the logs endpoint includes /v1/logs
  • Ensure your authentication token is correct
  • Make test requests to generate some logs
  • Check console output for any export errors

Next Steps

Now that you have OpenTelemetry logging set up in your .NET application:

  1. Watch our detailed video guide on correlating logs with traces for better debugging
  2. Follow our .NET tracing guide to implement distributed tracing in your .NET applications.
  3. Set up log-based alerts, explore structured logging patterns, or add custom attributes to your logs. The complete sample code is available in our GitHub repository.

Need help? Join our Slack community for support.

Happy Monitoring! 🚀

About the Author

Manas Sharma

Manas Sharma

TwitterLinkedIn

Manas is a passionate Dev and Cloud Advocate with a strong focus on cloud-native technologies, including observability, cloud, kubernetes, and opensource. building bridges between tech and community.

Latest From Our Blogs

View all posts