---
id: logging_netcore
title: Logging with Serilog and Application Insights
linkTitle: Logging
weight: 8
keywords:
  - .net core
  - logging
  - logger
  - serilog
  - application insights
  - standard
  - serilog configuration
---

pass:[.]NET Core provides a simple logging abstraction with most of the required logging features used by an application. Everywhere in the application, when logging is required, the classes generating logs should receive via dependency injection an instance of `ILogger<>` to use as the logger object. The `ILogger<>` instances are created by Logging Factory registered by each application and will abstract the logging library from the application logging.

The standard library has limited capabilities on log forwarding and requires additional packages to add proper filtering, enrichment, and forwarding. For this reason, the use of Serilog is required to extend the default logging features. Serilog integrates with the logger abstraction provided by DotNet Core. It provides additional Sink(outputs), Filter capabilities, and Log Enrichment features to complete the limited set of features in .NET Core default loggers. Every service implemented using .NET Core should make use of the Serilog library to standardize the logging approach.

== Sinks

By default, the *Console* and *ApplicationInsights* sinks should be used.

The *console sink* will output all logging generated by the service to the runtime console, and will make the logs available via command-line tools like kubectl (kubectl get logs) providing a quick and straightforward way of getting the logs for a particular instance.

The *Application Insights* sink will make sure all logs generated (and filtered) are forwarded for the logging platform for correlation and future investigations.

Application Insights is the chosen logging platform and will aggregate all logs generated by all services. The console sink is a useful secondary output in order to facilitate investigation of issues with a particular service that are failing. Having both setup will make it very straightforward to identify issues in real-time or during delayed investigation.

== Serilog Configuration

The following is a sample `appsettings.json` file with annotations about logging configuration:

[source,json]
----
{
  "Serilog": {    // Logging configuration for Serilog
    "Using": [
      "Serilog.Sinks.Console",              // Import console sink package
      "Serilog.Sinks.ApplicationInsights"   // Import ai sink package
    ],
    "MinimumLevel": {
      "Default": "Information", // minimal log level for everything
      "Override": {}            // Override for individual log sources
    },
    "WriteTo": [
      { "Name": "Console" },    // Write Logs to console
      {
        "Name": "ApplicationInsights",  // Write Logs to App Insights
        "Args": {
          "telemetryConverter": "Serilog.Sinks.ApplicationInsights.Sinks.ApplicationInsights.TelemetryConverters.TraceTelemetryConverter, Serilog.Sinks.ApplicationInsights"
        }
      }
    ],
    "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ], // Add custom attributes to the logs, Hostname and the ThreadId
    "Destructure": [],
    "Properties": {             // fixed attributes added to every log for filtering purposes
      "Domain": "identity",     // domain name added to every log
      "Service": "identityapi", // service generating the logs
      "Environment": "dev",     // environment this instance belongs to
    },
    "Filter": [                 // Ignore logs that match the following filters
      {
        "Name": "ByExcluding",
        "Args": {
          "expression": "EndsWith(RequestPath, '/health')" // Filter out health requests to reduce useless log information. Not required for non-api services.
        }
      }
    ]
  }
}
----
