Skip to content

Logging

This documentation explain logging basics and configuration for VC Platform.

Overview

VirtoCommerce Platform uses Serilog library to capture and store log messages from the application. Serilog also supports a wide range of sinks (logging providers), which are the destinations for log messages. These can include local files, network destinations, cloud-based services, and more. Serilog's configuration system makes it easy to set up and manage these sinks, so you can quickly and easily start logging to the destinations.

By default Platform provides Console and Debug sinks. Azure Application Insights sink is delivered in the separate Commerce Bundle module.

Configuring Serilog

The default Development configuration in the appsettings.json file will look like this:

{
  "Serilog": {
    "Using": [
      "Serilog.Sinks.Console",
      "Serilog.Sinks.Debug"
    ],
    "MinimumLevel": {
      "Default": "Verbose",
      "Override": {
        "System": "Information",
        "Microsoft": "Information",
        "Microsoft.AspNetCore.SignalR": "Verbose",
        "Microsoft.AspNetCore.Http.Connections": "Verbose"
      }
    },
    "WriteTo": [
      "Console",
      "Debug"
    ]
  }
}

The configuration is read from the Serilog section. The Using section contains list of assemblies in which configuration methods (WriteTo.File(), Enrich.WithThreadId()) reside. The MinimumLevel configuration property can be set to a single value as in the sample above, or, levels can be overridden per logging source. Sinks are configured using the WriteTo configuration property.

Log levels

Serilog offers several log levels that can be used for both production and development environments. The appropriate log levels will depend on the specific needs of your application and the level of detail you want to capture in your logs. However, here are some general recommendations:

For production environments, it is recommended to use the following log levels:

  • Information: This log level is suitable for general logging of important events in your application that are not errors or warnings. For example, successful requests or completed transactions.
  • Warning: This log level is suitable for logging events that are potentially problematic, but not critical. For example, failed login attempts or failed database connections.
  • Error: This log level is suitable for logging events that indicate an error or problem with your application that needs attention. For example, exceptions, crashes or unhandled errors.

For development environments, it is recommended to use the following log levels:

  • Debug: This log level is suitable for detailed logging of events during development and debugging. For example, variable values, method calls or control flow.
  • Trace: This log level is suitable for extremely detailed logging of events that are not normally logged. For example, low-level system events or diagnostic information.

Extending logging

The Platform reads Serilog configuration from the appsettings.json and can also configured from the code. To achieve this Platform provides ILoggerConfigurationService interface that allows users writing adding their own sinks or making customizations.

UseSerilog((context, services, loggerConfiguration) =>
{
    // read from configuration
    _ = loggerConfiguration.ReadFrom.Configuration(context.Configuration);

    // enrich configuration from external sources
    var configurationServices = services.GetService<IEnumerable<ILoggerConfigurationService>>();
    foreach (var service in configurationServices)
    {
        service.Configure(loggerConfiguration);
    }
})

This code shows how Serilog is being initialized in the Platform. First the loggerConfiguration objects is initialized from the configuration sections and the passed to a list of external services. To implement your own config services first create a class that inherits ILoggerConfig and implement it. For example, this is the implementation for the Azure Application Insights sink:

public class ApplicationInsightsLoggerConfiguration : ILoggerConfigurationService
{
    private readonly TelemetryConfiguration _configuration;

    public ApplicationInsightsLoggerConfiguration(TelemetryConfiguration configuration)
    {
        _configuration = configuration;
    }

    public void Configure(LoggerConfiguration loggerConfiguration)
    {
        loggerConfiguration.WriteTo.ApplicationInsights(telemetryConfiguration: _configuration,
        telemetryConverter: TelemetryConverter.Traces,
        restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Error);
    }
}

Them register the implementation in module.cs Initialize method of your external module:

public void Initialize(IServiceCollection serviceCollection)
{
    serviceCollection.AddTransient<ILoggerConfigurationService, ApplicationInsightsLoggerConfiguration>();
}

References


Last update: April 27, 2023