Is there a way to format the output format in .NET Core logging?

C#LoggingConsole Application.Net Core

C# Problem Overview


I'm using the built in logging provider for logging into the console (Microsoft.Extensions.Logging.Console) in a .NET Core console application.

Each logging entry produces two lines in the output. I would like to have each entry in one single line. Is there a way to customize the output format?

Here is an example how I use it:

static void Main(string[] args)
{
    var serviceProvider = new ServiceCollection()
      .AddLogging() // This adds the Microsoft logging.
      .AddSingleton<IProjectGeneratorService, CSharpProjectGeneratorService>()
      .BuildServiceProvider();

    // Configure the console logging.
    serviceProvider
      .GetService<ILoggerFactory>()
      .AddConsole(LogLevel.Debug);
    
    // Write a logging entry
    var logger = serviceProvider.GetService<ILoggerFactory>().CreateLogger<Program>();
    logger.LogDebug("Application started...");
}

What I get is:

dbug: Generator.Program[0]
      Application started...

What I would like to have is something like this:

dbug: Generator.Program[0]: Application started...

Any idea? I know, I could write a custom logger, but I would like to know if there is an other way.

Thanks.

C# Solutions


Solution 1 - C#

At the moment, this not configurable. The source code is here on GitHub:

> logBuilder.Append(logName); > logBuilder.Append("["); > logBuilder.Append(eventId); > logBuilder.AppendLine("]");

If you want that, you need to write your own logger. However you can just copy the source code of the console logger, modify as needed and change the namespaces so it doesn't interfere with the version Microsoft ships.

You can also open an issue on the logging repo to ask for this option.

Solution 2 - C#

As @MartinUllrich already mentioned this line break can't be disabled and you have to implement a custom logger to avoid it.

Registration:

loggerFactory.AddProvider(new CustomLoggerProvider());

The implementation (can be extended with using of the original ConsoleLogger source code - for example, you could add the GetLogLevelConsoleColors method):

public class CustomLoggerProvider : ILoggerProvider
{
    public void Dispose() { }

    public ILogger CreateLogger(string categoryName)
    {
        return new CustomConsoleLogger(categoryName);
    }

    public class CustomConsoleLogger : ILogger
    {
        private readonly string _categoryName;

        public CustomConsoleLogger(string categoryName)
        {
            _categoryName = categoryName;
        }

        public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
        {
            if (!IsEnabled(logLevel))
            {
                return;
            }

            Console.WriteLine($"{logLevel}: {_categoryName}[{eventId.Id}]: {formatter(state, exception)}");
        }

        public bool IsEnabled(LogLevel logLevel)
        {
            return true;
        }

        public IDisposable BeginScope<TState>(TState state)
        {
            return null;
        }
    }
}

Solution 3 - C#

This is updated in .NET 5: https://docs.microsoft.com/en-us/dotnet/core/extensions/console-log-formatter. Now provides simple, systemd and json

Solution 4 - C#

Although you can't specify your own custom format, it does support an alternative "systemd" format which you can select like this:

logging.AddConsole(options => {
  options.Format=ConsoleLoggerFormat.Systemd;
});

This outputs each log entry on one line even if you the text has newlines in it (so exceptions aren't very pretty). It also doesn't use colors which is an advantage if you're redirecting to a file.

Solution 5 - C#

This is now easy to do with SimpleConsoleFormatter from the Microsoft.Extensions.Logging.Console 5.0.0 package.

The source code of SimpleConsoleFormatter is here on Github.

Example:

static void Main(string[] args)
{
      var serviceProvider = new ServiceCollection()
            .AddLogging(loggingBuilder => loggingBuilder
                .AddSimpleConsole(formatterOptions =>
                {
                    formatterOptions.SingleLine = true;
                })
                .SetMinimumLevel(LogLevel.Debug))
            .BuildServiceProvider();

      // Write a logging entry
      var logger = serviceProvider.GetRequiredService<ILogger<Program>>();
      logger.LogDebug("Application started...");
}

Output:

dbug: Generator.Program[0]: Application started...

Solution 6 - C#

You can use a logging library like Serilog.

Using the instructions from the ASP.NET Core integration you can later simply provide a logging output template via the Console sink

.WriteTo.Console(
    outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}")

Solution 7 - C#

Starting from .NET 5 you can configure logging formatters to write each log entry in a single line. Use SingleLine property of Formatter to configure it

For example, you can configure console formatter in your appsettings.json without writing any additional code:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.Hosting.Lifetime": "Information"
    },
    "Console": {
      "FormatterName": "simple",
      "FormatterOptions": {
        "SingleLine": true,
        "TimestampFormat": "HH:mm:ss "
      }
    }
  }
}

You can find more information in Microsoft Docs:

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBooFarView Question on Stackoverflow
Solution 1 - C#Martin UllrichView Answer on Stackoverflow
Solution 2 - C#Ilya ChumakovView Answer on Stackoverflow
Solution 3 - C#Wouter Van RanstView Answer on Stackoverflow
Solution 4 - C#AndyView Answer on Stackoverflow
Solution 5 - C#Yevhen CherkesView Answer on Stackoverflow
Solution 6 - C#LincolnView Answer on Stackoverflow
Solution 7 - C#RoganikView Answer on Stackoverflow