Hi!

Today we will see how to configure logging in BlazorServer. Immediately after creating a project, the appsettings.json file will be in the root of the project.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

This is where logging settings are set. LogLevel starts with Default which have value Information. This means that the default log level will be Information. Next is Microsoft with the Warning level, respectively for namespace Microsoft the login level will be Warning. And at the very end Microsoft.Hosting.Lifetime with value Information. This means that for all namespace Microsoft except part Microsoft.Hosting.Lifetime which is part of Microsoft namespace log level will be Warning.

If you change the logging settings in this file and run the application, nothing will change. And all because launchSettings.json hase environement variable "ASPNETCORE_ENVIRONMENT": "Development". And for development environment another file is used - appsettings.Development.json. You can find it by clicking on the arrow next to appsettings.json.

DevJson

I will change all levels to Debug in appsettings.Development.json.

{
  "DetailedErrors": true,
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "Microsoft": "Debug",
      "Microsoft.Hosting.Lifetime": "Debug"
    }
  }
}

After that I will launch the application. And there will be a lot of logs in the console.

Debug If I need to include from all logs only any concrete i can do it. For example, I need to see logs from Microsoft.AspNetCore.Components.RenderTree.Renderer in Debug and all others in info. To do this, I will add it to appsettings.Development.json.

{
  "DetailedErrors": true,
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information",
      "Microsoft.AspNetCore.Components.RenderTree.Renderer": "Debug"
    }
  }
}

After that logs will look like this Debug2

Logging from razor pages

Let’s try to send a log message from razor pages. For example, take the page Counter.razor. To use the logger, you must first import the desired namespace @using Microsoft.Extensions.Logging. And with DI, inject the logger in the page @inject ILogger<Counter> Logger. Now you can use logger.

@page "/counter"
@using Microsoft.Extensions.Logging
@inject ILogger<Counter> Logger

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
        Logger.LogInformation("Button clicked, current count #{count}", currentCount);
    }
}

Every time I press the Click me button. The message appears in the console. Clicked

Logging from class

Similarly, log messages can be sent from classes using DI. First, the object private readonly ILogger<WeatherForecastService> _logger; is created and with the help of the constructor i inject logger.

using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace BlazorLearn.Data
{
    public class WeatherForecastService
    {
        private readonly ILogger<WeatherForecastService> _logger;
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        public WeatherForecastService(ILogger<WeatherForecastService> logger)
        {
            _logger = logger;
        }

        public Task<WeatherForecast[]> GetForecastAsync(DateTime startDate)
        {
            _logger.LogInformation("WeatherForecastService called");
            var rng = new Random();
            return Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = startDate.AddDays(index),
                TemperatureC = rng.Next(1, 100),
                Summary = Summaries[rng.Next(Summaries.Length)]
            }).ToArray());
        }
    }
}

Class

Logger configuration from code

If necessary, the logger can be configured from code and not from application.json. This can be done in Program.cs in the CreateHostBuilder method. By default, it looks like this.

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

To configure the logger to CreateDefaultBuilder you need to add ConfigureLogging

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureLogging(logger =>
                {
                    logger.ClearProviders();
                    logger.SetMinimumLevel(LogLevel.Information);
                    logger.AddConsole();
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });

logger.ClearProviders() - clears all previous settings. And then you can immediately add another log provider, such as Seriolog or any other. logger.SetMinimumLevel(LogLevel.Information) - indicates the minimum level log. logger.AddConsole() - adds log output to the console.