晴耕雨読

working in the fields on fine days and reading books on rainy days

[C#] Loggingを使ったログの記録

C# で Microsoft.Extensions.Logging を使ったログの記録方法について説明します。

1. ログ記録

ログのライブラリを使うときは以下の2つのパッケージを dotnet add package コマンドで追加してください。

  • Microsoft.Extensions.Logging
  • Microsoft.Extensions.Logging.Console

以下はログレベル INFO のログをコンソールに出力するだけの例です。

using Microsoft.Extensions.Logging;

using ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddConsole());
ILogger logger = factory.CreateLogger("Program");
logger.LogInformation("Hello World! Logging is {Description}.", "fun");
// => info: Program[0]
//          Hello World! Logging is fun.

流れとしては LoggerFactory で生成したインスタンスから CreateLogger() メソッドで logger を生成します。 その logger のメソッド LogInformation() でログを出力することができます。

ログレベルが異なる他の種類のメソッドもあります。例えば、LogError() や LogDebug() や LogWarning() などです。 詳細は MS の公式ドキュメントを確認ください。

2. コンパイル時にログソースを生成する

LoggerMessageAttribute を使ってログを記録するソースを自動生成すると、パフォーマンスの高いログ出力が可能になります。

Example.cs:

namespace MyExample;

using Microsoft.Extensions.Logging;

partial class Example(ILogger logger)
{
    public void StartUp()
    {
        LogStartupMessage(logger, "fun");
    }

    [LoggerMessage(Level = LogLevel.Information, Message = "Hello World! Logging is {Description}.")]
    static partial void LogStartupMessage(ILogger logger, string description);
}

Program.cs(プログラムのエントリーポイント):

using Microsoft.Extensions.Logging;
using MyExample;

using ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddConsole());
ILogger logger = factory.CreateLogger("Program");

var example = new Example(logger);
example.StartUp();
// => info: Program[474475659]
//          Hello World! Logging is fun.

ただし、ログメソッドで LoggerMessageAttribute を使用するとき、いくつかの制約があります。

  • ログメソッドは partial であり、void を返す必要があります。
  • ログメソッドが static の場合は、ILogger インスタンスがパラメーターとして必要です。

3. ログの書式設定

Consoleログプロバイダーには、いくつかの定義済みのフォーマットが存在します。

  • ConsoleLoggerExtensions.AddJsonConsole
  • ConsoleLoggerExtensions.AddSimpleConsole
  • ConsoleLoggerExtensions.AddSystemdConsole

例えば、AddSimpleConsole でオプション SingleLine = true を設定することで、ログ出力時に各ログが1行で出力されるようになります。

using ILoggerFactory factory =
    LoggerFactory.Create(builder => 
        builder.AddSimpleConsole(options =>
        {
            options.IncludeScopes = true;
            options.SingleLine = true;
            options.TimestampFormat = "HH:mm:ss ";
        }));

ILogger logger = factory.CreateLogger("Program");
logger.LogInformation("Hello World! Logging is {Description}.", "fun");
// => 22:56:45 info: Program[0] Hello World! Logging is fun.

using (logger.BeginScope("[scope]"))
{
    logger.LogInformation("Hello, world!");
    logger.LogWarning("Warning Message");
    logger.LogError("Error Message");
}
// => 23:39:49 info: Program[0] => [scope] Hello, world!
// => 23:39:49 warn: Program[0] => [scope] Warning Message
// => 23:39:49 fail: Program[0] => [scope] Error Message

以上です。

参考資料