Flexible and efficient optionally-structured console logging out of the box (original) (raw)

Updated by @maryamariyan:

Description

We want to add the capability to control the format of the logs produced by our console logger. Currently, there is an option to choose between Default (logging on multiple lines with colors) and Systemd (logs on a single line without color). We would like to be able to:

Proposal:

The proposal below is aimed at satisfying all the above requirements.

Scope

We are considering limiting the scope of the formatter API to Logging.Console for now, instead of Logging.Abstractions, though this could potentially in the future be adapted to be used for Logging.Debug as well,

Usage and New APIs

Refer to gist: https://gist.github.com/maryamariyan/81f1526fe2156e95352e516f03a61724

we would need to be able to control the formatter used as well as the formatters via Configuration.

As seen in the sample appsettings.json below, the formatter would be selected via Console:Logging:FormatterName, and the formatter options would be set via Console:Logging:FomratterOptions:

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

    "Console": {
      "LogLevel": {
        "Default": "Information"
      },
      "FormatterName": "json",
      "FormatterOptions": {
        "JsonWriterOptions": {
          "Indented": true
        },
        "ExtraCustomProperty": "modified",
        "IncludeScopes": true,
        "TimestampFormat": "HH:mm:ss",
        "UseUtcTimestamp": true
      }
    }
  },
  "AllowedHosts": "*"
}

Screenshots

Screenshots for the different built-in selections (click to view)

default:

image

default:
(when DefaultConsoleLogFormatterOptions.SingleLine is true)
or we could have an additional formatter called compact rather than toggling by property.

image

systemd:

image

json:

image

Original proposal (click to view)

As a web app developer, I'm trying to write web apps (such as nodatime.org) that log efficiently and cleanly, with minimal effort.
As a Google Cloud Platform client library author, I'm trying to make it really easy for our users to integrate with Stackdriver logging and error reporting.
As a .NET community member, I'm trying to make 12-factor apps easier to write.

Currently, there are three reasonably obvious options for logging in my web application:

Option 1: Use the default console logger.

The "no code changed" option.

This has at least three problems:

Option 2: Use Google.Cloud.Diagnostics.AspNetCore

This library makes RPCs directly to the Stackdriver Logging API.

As one of the contributors to the library, I should be able to get this to work easily, right? Well, it does work, but not as conveniently as I'd like. I can improve things, but this is likely to always be a somewhat-heavyweight option. Useful in some cases, such as when there's nothing monitoring console output, but not necessary in modern container-based systems which almost always do monitor the console. It also requires appropriate credentials to be provided when not running on GCP, etc. This ties it to Stackdriver in a way that could be harmful to app portability. (It's fine if you don't need portability of course, but it's a heavyweight dependency otherwise.)

Option 3: Use Serilog

I did get this working, writing out structured JSON to the console, but it was relatively painful to do, and didn't write the JSON in a format that Stackdriver expects. In order to get a custom JSON format, I had to do far more work than I'd normally expect to. It worked, but there's no way that every app should have all of this code in it.

Describe the solution you'd like

Ideally I'd like three simple options:;

The last is for integration with Stackdriver and presumably other cloud providers' monitoring offerings. With the right JSON, the Stackdriver user interface is clear and easy to read, but still provides structured data that can be used to trigger error reporting, create filters etc.

In an ideal world the CNCF would provide a common JSON format for everyone to use for maximum interoperability, but until that happens it would be useful for the ASP.NET Core team to handle the concerns of gathering the log data and writing the resulting to the console efficiently and atomically, leaving cloud providers to just provide the code to convert the raw log data into appropriate JSON. Even though an app using this would still have a dependency on Stackdriver, it's a much lighter-weight one than Google.Cloud.Diagnostics.AspNetCore - and it would be entirely reasonable to depend on multiple formatters and pick the right one at execution time, expecting each to be standalone and small.

Additional context

I have tried to find existing solutions to this, but I've failed so far.

For nodatime.org, I ended up writing my own console logger, which should only be used for the sake of seeing what I'm trying to achieve - it's not aimed at high-performance scenarios, for example. (If anyone wants to point and laugh, they're welcome - it does the job though :)
https://github.com/nodatime/nodatime.org/blob/master/src/NodaTime.Web/Logging/JsonConsoleLogger.cs

API Proposal

Assembly: Microsoft.Extensions.Logging.Abstractions.dll

Assembly: Microsoft.Extensions.Logging.Abstractions.dll

namespace Microsoft.Extensions.Logging {

}

Assembly: Microsoft.Extensions.Logging.Console.dll

namespace Microsoft.Extensions.Logging { public static partial class ConsoleLoggerExtensions { public static ILoggingBuilder AddConsole(this ILoggingBuilder builder); public static ILoggingBuilder AddConsole(this ILoggingBuilder builder, Action configure);

}