Getting started with logs - Console

Learn how to use OpenTelemetry Logs in a .NET Console application

This guide will show you how to get started with OpenTelemetry .NET Logs in a console application in just a few minutes.

Prerequisites

Creating a console application

Create a new console application and run it:

dotnet new console --output getting-started
cd getting-started
dotnet run

You should see the following output:

Hello World!

Adding OpenTelemetry logs

Install the OpenTelemetry Console Exporter package:

dotnet add package OpenTelemetry.Exporter.Console

Update the Program.cs file with the following code:

using Microsoft.Extensions.Logging;
using OpenTelemetry;
using OpenTelemetry.Logs;

// Create a logger factory with OpenTelemetry
using var loggerFactory = LoggerFactory.Create(builder =>
{
    builder.AddOpenTelemetry(options =>
    {
        options.AddConsoleExporter();
    });
});

// Get a logger instance
var logger = loggerFactory.CreateLogger<Program>();

// Log a simple message
logger.LogInformation("Hello from OpenTelemetry .NET Logs!");

// Log with structured data
logger.FoodPriceChanged("artichoke", 9.99);

// Log a more complex example
logger.FoodRecallNotice(
    "Food & Beverages",
    "Contoso",
    "Salads",
    "Contoso Fresh Vegetables, Inc.",
    "due to a possible health risk from Listeria monocytogenes");

// Define extension methods for structured logging
internal static partial class LoggerExtensions
{
    [LoggerMessage(LogLevel.Information, "Food `{name}` price changed to `{price}`.")]
    public static partial void FoodPriceChanged(this ILogger logger, string name, double price);

    [LoggerMessage(LogLevel.Critical, "A `{productType}` recall notice was published for `{brandName} {productDescription}` produced by `{companyName}` ({recallReasonDescription}).")]
    public static partial void FoodRecallNotice(
        this ILogger logger,
        string productType,
        string brandName,
        string productDescription,
        string companyName,
        string recallReasonDescription);
}

Run the application again (using dotnet run) and you should see the log output on the console:

LogRecord.Timestamp:               2023-09-15T06:07:03.5502083Z
LogRecord.CategoryName:            Program
LogRecord.Severity:                Info
LogRecord.SeverityText:            Information
LogRecord.Body:                    Food `{name}` price changed to `{price}`.
LogRecord.Attributes (Key:Value):
    name: artichoke
    price: 9.99
    OriginalFormat (a.k.a Body): Food `{name}` price changed to `{price}`.
LogRecord.EventId:                 344095174
LogRecord.EventName:               FoodPriceChanged

...

LogRecord.Timestamp:               2023-09-15T06:07:03.5683511Z
LogRecord.CategoryName:            Program
LogRecord.Severity:                Fatal
LogRecord.SeverityText:            Critical
LogRecord.Body:                    A `{productType}` recall notice was published for `{brandName} {productDescription}` produced by `{companyName}` ({recallReasonDescription}).
LogRecord.Attributes (Key:Value):
    brandName: Contoso
    productDescription: Salads
    productType: Food & Beverages
    recallReasonDescription: due to a possible health risk from Listeria monocytogenes
    companyName: Contoso Fresh Vegetables, Inc.
    OriginalFormat (a.k.a Body): A `{productType}` recall notice was published for `{brandName} {productDescription}` produced by `{companyName}` ({recallReasonDescription}).
LogRecord.EventId:                 1338249384
LogRecord.EventName:               FoodRecallNotice

Congratulations! You are now collecting logs using OpenTelemetry.

How it works

The program creates a logging pipeline by instantiating a LoggerFactory instance, with OpenTelemetry added as a logging provider.

OpenTelemetry SDK is configured with a ConsoleExporter to export the logs to the console for demonstration purposes. For production usage, other exporters such as OTLP Exporter should be used instead.

The LoggerFactory instance is used to create an ILogger instance, which is used to do the actual logging.

Following the .NET logging best practice, compile-time logging source generation has been used, which delivers high performance, structured logging, and type-checked parameters.

Using with dependency injection

For applications which use ILogger with dependency injection (DI) (for example, ASP.NET Core and .NET Worker), the common practice is to add OpenTelemetry as a logging provider to the DI logging pipeline, rather than set up a completely new logging pipeline by creating a new LoggerFactory instance.

Refer to the Getting Started with ASP.NET Core tutorial to learn more.

Learn more