Centralize Microsoft.Extensions.Logging Data with Loupe

Loupe was designed to be the best way to record messages from Microsoft.Extensions.Logging (MEL) in production; capturing everything you’re already sending to MEL and extending it with Loupe’s additional data.

Basic Logging with Microsoft.Extensions.Logging

The MEL API provides a well-rounded set of logging methods that is easy to extend for your custom scenarios. It supports structured logging to make good looking contextual messages with accompanying data for analysis.

A basic informational message (used to note the progress of your application) looks like this:

_logger.LogInformation("Starting to process order {Order}, " +
    "Quantity: {OrderQuantity:N0}, queued at: {OrderTimestamp:g}",
    firstVal, secondVal, thirdVal);

When catching an exception, it’s recommended you log it and explain what it means to your application, like this:

try
{

} 
catch (Exception ex)
{
    _logger.LogError(ex, "Unable to complete the action we were performing due to an {Exception}\r\n" +
        "Now describe why it's safe to catch the exception and what the code assumes it means.\r\n" + 
        "Now that we're on the second line, here's more information we can share " +
        "that won't cause an overly-unique message: " +
        "{Order}, {OrderQuantity:N0}, {OrderTimestamp:g}", ex.GetType().Name,
        firstVal, secondVal, thirdVal);    
}

You can add data about the current context your application is operating in by using logging scopes. This will add a collection of name/value pairs to each log message so you don’t have to repeat the data within each log message. Loupe will show this in the Details section of the message as JSON:

using (_logger.BeginScope(new Dictionary<string, object>
{
    {"Order", firstVal},
    {"OrderQuantity", secondVal},
    {"OrderTimestamp", thirdVal}
}))
{
    _logger.LogInformation("This log message will have three scope " +
        "elements associated with it.");
}

_logger.LogDebug("This log message will have not have any scope elements " +
    "associated with it.");

You can see more examples of how to use MEL in our unit tests for the Loupe provider, published on GitHub

How the Loupe Agent works with Microsoft.Extensions.Logging

Loupe has a Logging Provider that records messages as calls are made to Microsoft.Extensions.Logging. Adding the Loupe Provider means Loupe will capture anything written not just by your application but also by other libraries and the .NET Core frameworks (like ASP.NET Core and Entity Framework Core).

To use the Loupe Logging Provider:

  1. Add the Loupe.Extensions.Logging NuGet Package to your project. This adds the provider itself and other required Loupe packages.

  2. Register the Loupe provider in your logging configuration

For projects that use Generic Host (like ASP.NET Core), just add a call to AddLoupeLogging like this:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .AddLoupe() //Add the Loupe Agent (you may have more here for your scenario)
        .AddLoupeLogging() //creates a default log config and adds Loupe to it.
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

If you need to provide more detail to set up your logging, you can also add Loupe in your log builder, like this

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .AddLoupe() //Add the Loupe Agent (you may have more here for your scenario)
        .ConfigureLogging(builder =>
        {
            //this line adds Loupe to the configuration builder
            builder.AddLoupe();
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

In a non-host app (like a console application) make the call while creating your LoggerFactory, like this:

//Create a logging factory, typically once per application.
var loggerFactory = LoggerFactory.Create(builder =>
{
    builder
        .AddFilter("Microsoft", LogLevel.Warning)
        .AddFilter("System", LogLevel.Warning)
        .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
        .AddLoupe(); //this line adds Loupe
});

//Having set up the factory, use it to create the logger for your class
ILogger logger = loggerFactory.CreateLogger<Program>();
logger.LogInformation("This message will be sent to Loupe (and any other logging provider you configure above)");

Centralized Logging, Error Management, and More

By adding Loupe with your existing .NET Core application, all of the custom messages you’ve created will be merged with the additional data Loupe captures and can be viewed locally or sent to a Loupe Server for centralized storage and analysis.

Within minutes you can be getting notifications of each unique error reported in your application, with all the tools you need to manage those issues and support your users.

Rock solid centralized logging

Unlimited applications, unlimited errors, scalable from solo startup to enterprise.