Using Loupe With .NET Core Logging Frameworks

Recently, I’ve been updating our documentation and in-app directions for Loupe 5. With the launch of Loupe 5, our new “Getting Started” directions will include step-by-step Serilog and NLog integrations, along with instructions on using Loupe as a Microsoft.Extensions.Logging provider for .NET Core applications.

Our current documentation prioritizes the .NET technology, like ASP.NET or WPF. This allows users to find directions that work no matter what logging systems they use. They can even adopt our own framework.

However, many .NET Developers work on projects with a dedicated logging framework. That’s a good thing! The more developers that care about logging, the better. But our documentation doesn’t serve them as well as it should. These users would likely prefer to integrate Loupe with their current logging system, and it’s our job to show them how.

So in this article, I’ll go over the Loupe integrations for some .NET Core logging frameworks and discuss which integrations we recommend for our users. For the blog, the directions are more verbose than those we’ll use in-app. I appreciate that many developers prefer streamlined information, and we can accommodate that. But those less familiar with .NET can benefit from some explanation. With that in mind, I over-explain some of the steps.

Using Loupe as a Serilog Sink

Loupe is relatively simple to add as a Serilog Sink, only requiring two packages. As far as edits, a single line in the Serilog config, a line for the host builder, and a section in the appsettings.json file are all it takes.

Step 1: Add the following NuGet Packages

  1. Loupe.Serilog.Core: Serilog Sink for Loupe for .NET Standard. Add Loupe.Serilog.Core to your project to route Serilog messages to Loupe.
  2. Loupe.Agent.Core.Services: Shared configuration library for technology-specific agents built on the Loupe Agent for .NET Core.

To use these packages, we only require two using statements in the program.cs file.

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Serilog;
using Loupe.Agent.Core.Services;
using Loupe.Serilog;

namespace Serilog_Loupe_Sink_Test_Net_5
{
//...rest of file...
}

As Loupe is simply acting as a sink, the rest of the app shouldn’t require using statements for the Loupe packages. Everywhere else you write to Serilog won’t need any edits.

Step 2: Add Loupe to the Logger Configuration

Generally, the Serilog Logger Configuration is found in the program.cs file. Occasionally you may see configurations in the startup.cs when using the generic hosting model. Either way, you are looking to add Loupe as a new sink. Just insert .WriteTo.Loupe() in the configuration on its own or alongside other sinks you use.

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .WriteTo.Loupe() //add this line
    .CreateLogger();

The Loupe configuration is simple because we handle formatting data in-app and automatically collect helpful supplemental data (machine specs, user information, stack traces, you can learn more about supplemental data here). There’s no need to add any enrichers or templates for our config.

Step 3: Add Loupe to the Host Builder

There are two common hosting models for .NET Core. The generic hosting model splits the process into a program.cs file and a startup.cs file. In this case, you can add Loupe to the Host.CreateDefaultBuilder(args) method in the program.cs.

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .AddLoupe()
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });

For this implementation of Loupe, you do not need to make any modifications to the startup.cs.

The other hosting model is the minimal hosting model, exclusive to .NET 6. This model uses just the program.cs file and reduces the required lines of code significantly. You can add Loupe to the host builder in this model using the code below:

var builder = WebApplication.CreateBuilder(args);

//... Serilog Config ...

// Add services to the container.
builder.Services.AddRazorPages();
builder.Logging.AddSerilog();
builder.Host.AddLoupe();

Step 4: Add Loupe Configuration Settings

Loupe can be configured through the appsettings.json file. For Loupe Desktop, you can simply add publisher information:

"Loupe": {
    "Publisher": {
      "ProductName": "Your Product Name Here",
      "ApplicationName": "Your Application Name Here",
      "ApplicationType": "AspNet",
      "ApplicationVersionNumber": "1.0.0"
    }
}

For use with Loupe Server, you will need to add server information as well:

  "Loupe": {
    "Publisher": {
      "ProductName": "Your Product",
      "ApplicationName": "Your Application",
      "ApplicationType": "AspNet",
      "ApplicationVersionNumber": "1.0.1"
    },
    "Server": {
      "UseGibraltarService": true,
      "CustomerName": "Your Loupe Service Name",
      "AutoSendSessions": true,
      "SendAllApplications": true
    }
  }

And from there, you can start logging to Loupe with Serilog!

Using Loupe as an NLog Target

Step 1: Add the following NuGet Packages

Loupe only requires two packages to act as an NLog Target:

  1. Loupe.Agent.NLog: Our NLog Agent targeting .NET Standard 2.0 (compatible with all versions of .NET Core).
  2. Loupe.Agent.Core.Services: Shared configuration library for technology-specific agents built on the Loupe Agent for .NET Core.

Step 2: Add Loupe to the nlog.config File

NLog generally uses an XML config to add targets and rules. In this case, we will register the Loupe package in the <extensions> section, define Loupe in the <targets> section, and add a minlevel logging rule to the <rules> section:

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <extensions>
        <!--Register nuget-package assembly for LoupeTarget class with target type "Loupe" -->
        <add assembly="Loupe.Agent.NLog" />
    </extensions>
    <targets>
        <!--Define a named target using the "Loupe" target type-->
        <target name="Loupe" xsi:type="Loupe" />
    </targets>
    <rules>
        <!--Send all logging to the "Loupe" named target-->
        <logger name="*" minlevel="Trace" writeTo="Loupe" />
    </rules>
</nlog>

Like the Loupe for Serilog config, the Loupe Nlog config is relatively simple compared to other targets. As we automatically format and collect supplemental data, there’s no need to add additional layout text.

Step 3: Add Loupe to the Host Builder

This step is the same for integration with NLog that it is for the previous Serilog instructions. You can add Loupe for projects using the generic host:

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .AddLoupe()
                .UseNLog()
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });

Or the minimal host:

// Add services to the container.
builder.Services.AddRazorPages();
builder.Host.UseNLog();
builder.Host.AddLoupe();

Step 4: Add Loupe Configuration Settings

This step is also consistent with the Serilog instructions. You can add settings for just Loupe Desktop:

"Loupe": {
    "Publisher": {
      "ProductName": "Your Product Name Here",
      "ApplicationName": "Your Application Name Here",
      "ApplicationType": "AspNet",
      "ApplicationVersionNumber": "1.0.0"
    }
}

Or add additional settings for use with Loupe Server:

  "Loupe": {
    "Publisher": {
      "ProductName": "Your Product",
      "ApplicationName": "Your Application",
      "ApplicationType": "AspNet",
      "ApplicationVersionNumber": "1.0.1"
    },
    "Server": {
      "UseGibraltarService": true,
      "CustomerName": "Your Loupe Service Name",
      "AutoSendSessions": true,
      "SendAllApplications": true
    }
  }

Other than the config differences, the process is similar to our Serilog integration. With four steps, we have set up Loupe as an NLog target.

Using Loupe as a Microsoft.Extensions.Logging Provider

We already have up-to-date Microsoft.Extensions.Logging documentation. But, I do want to add these directions in-app with slight modifications.

Compared to using Loupe with 3rd party logging frameworks, adding Loupe as a provider is slightly easier.

Step 1: Add the following NuGet Package

This time we only need to add one package:

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

This package includes the Loupe.Agent.Core.Services agent as well, which you will need to write a using statement for in the program.cs along with the Loupe.Extensions.Logging using statement. It may look like this using .NET 6 and the minimal hosting model:

global using Loupe.Agent.Core.Services;
global using Loupe.Extensions.Logging;

var builder = WebApplication.CreateBuilder(args);

//rest of program.cs file

Step 2: Add Loupe to the Host Builder

Here, you will both add Loupe and LoupeLogging to the host. You will need In the generic host that looks like this:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .AddLoupe() 
        .AddLoupeLogging() 
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

The .AddLoupeLogging() line registers Loupe as a Microsoft.Extensions.Logging provider.

In the minimal host, it looks like this:

// Add services to the container.
builder.Services.AddRazorPages();
builder.Host.AddLoupe().AddLoupeLogging();

Step 3 Add Loupe Configuration Settings

These stay consistent with what we have seen for all the directions. Here’s what you need for Loupe Desktop:

"Loupe": {
    "Publisher": {
      "ProductName": "Your Product Name Here",
      "ApplicationName": "Your Application Name Here",
      "ApplicationType": "AspNet",
      "ApplicationVersionNumber": "1.0.0"
    }
}

And here are the settings for Loupe Server:

  "Loupe": {
    "Publisher": {
      "ProductName": "Your Product",
      "ApplicationName": "Your Application",
      "ApplicationType": "AspNet",
      "ApplicationVersionNumber": "1.0.1"
    },
    "Server": {
      "UseGibraltarService": true,
      "CustomerName": "Your Loupe Service Name",
      "AutoSendSessions": true,
      "SendAllApplications": true
    }
  }

And in three steps, we have a work Microsoft.Extensions.Logging provider with Loupe.

So, Which Integration is the Best?

If I were starting a new project today, I would choose Microsoft.Extensions.Logging over the others, then Serilog over NLog. All these options are great, but I have preferences that led to this conclusion:

  • I have no plans on using other logging outputs. I don’t like formatting text files, I don’t love logging with a console, and I try to avoid things like the Windows Event Viewer as much as possible. Working here has made me a complete log viewer snob. Loupe Desktop is now my acceptable floor, with the internal version of Loupe 5 as my preference.
  • I want the fewest dependencies possible. Microsoft.Extensions.Logging is baked into .NET Core. With Loupe as a provider, I only need to add the Loupe related package.
  • I dislike XML. While NLog can use an appsettings.json config, it’s just not as common. Serilog doesn’t use an XML config, so I give it the edge. But this is a minor personal annoyance, not a real problem with NLog.

If you disagree with these points, you’re not wrong. Some projects need text file logging for supporting processes, some people don’t mind a few additional dependencies, and maybe some people even prefer XML configs.

Ultimately, if you have a project that uses one of the three logging systems discussed, and like it, continue to use it. Loupe will work with it, add supplemental data, and provide an advanced log viewing experience no matter where your application runs.

How Can I Try Loupe?

If you are looking for a new way to read your logs, I recommend giving Loupe a try. There are two ways that don’t even require any payment information:

  1. Loupe Desktop: Great for testing the Loupe integration. Free local log viewer.
  2. Loupe Server Trial: 30 days of our centralized logging service. The trial uses the cloud-hosted SaaS version of Loupe, but the software is representative of our self-hosted versions as well. Currently, the trial is for Loupe 4. As soon as we release Loupe 5, we will update the trial.

If you are looking for a way to analyze log data from production applications, I would check out the Loupe Server Trial. If you are a bit less familiar with logging, I recommend starting with Loupe Desktop. The setup is slightly easier and you can use it for free, forever. That allows you to take your time.

You can learn more about Loupe Desktop in the link below.

Loupe Desktop - A Local .NET and Java Log Viewer

Completely free local log viewer
Works with the technologies you use
Adds additional metrics and supplemental data