Configuring and Viewing Logs in ASP.NET Core Applications

Configuring and Viewing Logs in ASP.NET Core Applications

Logging is a crucial feature in any application, allowing developers to monitor and diagnose issues. In this article, we will explore how to configure and view logs in ASP.NET Core applications.

LoggerFactory Configuration

The logging system in ASP.NET Core consists of three core objects: Logger, LoggerFactory, and LoggerProvider. We can implement a simple configuration of LoggerFactory customization, as well as add LoggerProvider.

By default, the LoggerFactory service is registered in the top level of the application. If the default LoggerFactory service does not meet our needs, we can configure any LoggerFactory settings using the UseLoggerFactory method of WebHostBuilder.

public interface IWebHostBuilder
{
    IWebHostBuilder UseLoggerFactory(ILoggerFactory loggerFactory);
    IWebHostBuilder ConfigureLogging(Action<ILoggerFactory> configureLogging);
    ...
}

To configure logging more explicitly, we can use the ConfigureLogging method and add a certain LoggerProvider. We can do this by calling the ConfigureLogging method of WebHostBuilder.

new WebHostBuilder()
    .ConfigureLogging(factory => factory.AddConsole())
    .UseKestrel()
    .UseStartup<Startup>()
    .Build()
    .Run();

Registering LoggerProvider

We can register a LoggerProvider, such as ConsoleLoggerProvider, by calling the AddConsole method of ConfigureLogging.

new WebHostBuilder()
    .ConfigureLogging(factory => factory.AddConsole(true))
    .UseKestrel()
    .UseStartup<Startup>()
    .Build()
    .Run();

Creating a Logger Object

Once we have registered a LoggerProvider, we can create a Logger object using the CreateLogger method of ILoggerFactory.

public class FoobarMiddleware
{
    private RequestDelegate _next;

    public FoobarMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context, ILoggerFactory loggerFactory)
    {
        ILogger<FoobarMiddleware> logger = loggerFactory.CreateLogger<FoobarMiddleware>();
        logger.LogInformation("...");
        await _next(context);
    }
}

Logging in ASP.NET Core Pipelines

We can also use the same approach to create a Logger object in ASP.NET Core pipelines.

public class Program
{
    public static void Main()
    {
        new WebHostBuilder()
            .ConfigureLogging(factory => factory.AddConsole())
            .UseKestrel()
            .UseStartup<Startup>()
            .Build()
            .Run();
    }
}

public class Startup
{
    public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
    {
        app.Run(async context =>
        {
            LoggerFactory.CreateLogger("App").LogInformation("Log entry for test...");
            await context.Response.WriteAsync("Hello world!");
        });
    }
}

Log Range

The logging system has a concept called “log range,” which aims to create a context in the range of log records multiple correlations and provide a unique identity for this range.

When we conduct log analysis, we can identify a group of associated logs had separate log according to the log range.

To register ConsoleLoggerProvider to support log range, we simply add an extra parameter (true) when calling the AddConsole method.

new WebHostBuilder()
    .ConfigureLogging(factory => factory.AddConsole(true))
    .UseKestrel()
    .UseStartup<Startup>()
    .Build()
    .Run();

Exception Log Records

When an exception occurs in ASP.NET Core, it is not returned directly to the client. Instead, the exception details are logged.

We can use the browser to access the site address, and it will only get a status response 500, and simple tips server error. However, we can get the details of the exception by looking at the logs.

To register a LoggerProvider, such as ConsoleLoggerProvider, we can use the ConfigureLogging method of WebHostBuilder.

new WebHostBuilder()
    .ConfigureLogging(factory => factory.AddConsole(true))
    .UseKestrel()
    .Configure(app => app.Run(async context =>
    {
        int x = 1;
        int y = 0;
        await context.Response.WriteAsync((x / y).ToString());
    }))
    .Build()
    .Run();

Once we have registered a LoggerProvider, we can see the details of the exception directly on the host console.