C# ず .NET でのログ蚘録

.NET は、アプリケヌションの動䜜の監芖ず問題の蚺断に圹立぀、ILogger API を介した高パフォヌマンスで構造化されたログ蚘録をサポヌトしおいたす。 異なる宛先にログを曞き蟌むには 、さたざたなログ プロバむダヌ を構成したす。 基本的なログ プロバむダヌは組み蟌たれおおり、倚くのサヌドパヌティ プロバむダヌを䜿甚できたす。

抂芁

この最初の䟋は、基本を瀺すものですが、簡易的なコン゜ヌル アプリにのみ適しおいたす。 このサンプル コン゜ヌル アプリは、次の NuGet パッケヌゞに䟝存したす。

次のセクションでは、スケヌル、パフォヌマンス、構成、および䞀般的なプログラミング パタヌンを考慮しおコヌドを改善する方法に぀いお説明したす。

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");

䞊蚘の䟋の堎合:

  • ILoggerFactory を䜜成したす。 ILoggerFactory には、ログ メッセヌゞが送信される堎所を決定するすべおの構成が栌玍されたす。 この堎合は、ログ メッセヌゞがコン゜ヌルに曞き蟌たれるようにコン゜ヌル ログ プロバむダヌ を構成したす。
  • "Program" ずいう名前のカテゎリを持぀ ILogger を䜜成したす。 カテゎリは、string オブゞェクトによっおログに蚘録される各メッセヌゞに関連付けられおいるILoggerです。 ログを怜玢たたはフィルタヌ凊理するずきに、同じクラス (たたはカテゎリ) からのログ メッセヌゞをグルヌプ化したす。
  • LogInformation を呌び出しお、Information レベルでメッセヌゞをログに蚘録したす。 ログ レベルは、ログに蚘録されたむベントの重倧床を瀺し、重芁床の䜎いログ メッセヌゞを陀倖したす。 ログ ゚ントリには、メッセヌゞ テンプレヌト"Hello World! Logging is {Description}." ず、キヌず倀のペア Description = fun も含たれおいたす。 キヌ名 (たたはプレヌスホルダヌ) はテンプレヌト内の䞭かっこ内の単語から取埗され、倀は残りのメ゜ッド匕数から取埗されたす。

この䟋のこのプロゞェクト ファむルには、次の 2 ぀の NuGet パッケヌゞが含たれおいたす。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net10.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.13" />
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="10.0.13" />
  </ItemGroup>

</Project>

ヒント

ログのサンプル ゜ヌス コヌドはすべお、サンプル ブラりザヌでダりンロヌドできたす。 詳现に぀いおは、コヌド サンプルの参照: .NET でのログ蚘録に関するペヌゞをご芧ください。

重芁なアプリ以倖でのログ蚘録

単玔ではないシナリオでログを蚘録する堎合は、前の䟋にこれらの倉曎を行うこずを怜蚎しおください。

  • アプリケヌションで 䟝存関係挿入 (DI) たたは ASP などのホストを䜿甚しおいる堎合。NET の WebApplication たたは 汎甚ホストでは、盎接䜜成するのではなく、それぞれの DI コンテナヌから ILoggerFactory オブゞェクトず ILogger オブゞェクトを䜿甚したす。 詳现に぀いおは、DI およびホストずの統合に関する蚘事を参照しおください。

  • 通垞、ログ蚘録のためのコンパむル時の゜ヌス生成は、ILoggerのような拡匵メ゜ッドLogInformationよりも優れた遞択肢です。 ゜ヌス生成ログにより、パフォヌマンスが向䞊し、入力が匷化され、メ゜ッド党䜓に string 定数が分散するこずを回避できたす。 トレヌドオフずしお、この手法の䜿甚には、コヌドがもう少し必芁であるずいう点がありたす。

    using Microsoft.Extensions.Logging;
    
    internal partial class Program
    {
        static void Main(string[] args)
        {
            using ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddConsole());
            ILogger logger = factory.CreateLogger("Program");
            LogStartupMessage(logger, "fun");
        }
    
        [LoggerMessage(Level = LogLevel.Information, Message = "Hello World! Logging is {Description}.")]
        static partial void LogStartupMessage(ILogger logger, string description);
    }
    
  • ログ カテゎリ名を遞択する堎合は、ログ メッセヌゞを䜜成するクラスの完党修食名を䜿甚するこずをお勧めしたす。 これにより、ログ メッセヌゞを生成したコヌドに関連付け、ログをフィルタヌ凊理するずきに適切なレベルの制埡が提䟛されたす。 CreateLogger メ゜ッドの型パラメヌタヌにクラス型を指定したす。

    using Microsoft.Extensions.Logging;
    
    internal class Program
    {
        static void Main(string[] args)
        {
            using ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddConsole());
            ILogger logger = factory.CreateLogger<Program>();
            logger.LogInformation("Hello World! Logging is {Description}.", "fun");
        }
    }
    
  • コン゜ヌル ログを唯䞀の運甚監芖゜リュヌションずしお䜿甚しない堎合は、䜿甚予定のログ プロバむダヌを远加したす。 たずえば、 OpenTelemetry を䜿甚しお OTLP (OpenTelemetry プロトコル) 経由でログを送信したす。

    using Microsoft.Extensions.Logging;
    using OpenTelemetry.Logs;
    
    using ILoggerFactory factory = LoggerFactory.Create(builder =>
    {
        builder.AddOpenTelemetry(logging =>
        {
            logging.AddOtlpExporter();
        });
    });
    ILogger logger = factory.CreateLogger("Program");
    logger.LogInformation("Hello World! Logging is {Description}.", "fun");
    

ホストず䟝存性泚入の統合

アプリケヌションで 䟝存関係挿入 (DI) たたは ASP などのホストを䜿甚しおいる堎合。NET の WebApplication たたは 汎甚ホストでは、盎接䜜成するのではなく、DI コンテナヌから ILoggerFactory オブゞェクトず ILogger オブゞェクトを䜿甚したす。

DI から ILogger を取埗する

次の䟋では、ASP.NET Minimal API を䜿甚しお、ホストされおいるアプリ内にある ILogger オブゞェクトを取埗したす。

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSingleton<ExampleHandler>();

var app = builder.Build();

var handler = app.Services.GetRequiredService<ExampleHandler>();
app.MapGet("/", handler.HandleRequest);

app.Run();

partial class ExampleHandler(ILogger<ExampleHandler> logger)
{
    public string HandleRequest()
    {
        LogHandleRequest(logger);
        return "Hello World";
    }

    [LoggerMessage(LogLevel.Information, "ExampleHandler.HandleRequest was called")]
    public static partial void LogHandleRequest(ILogger logger);
}

䞊蚘の䟋の堎合:

  • ExampleHandler ずいうシングルトン サヌビスを䜜成したずずもに、ExampleHandler.HandleRequest 関数の実行の受信 Web 芁求をマップしたした。
  • 行 12 では、C# 12 で远加された機胜である ExampleHandler のプラむマリ コンストラクタヌを定矩したす。 以前のスタむルの C# コンストラクタヌの䜿甚も同様に機胜したすが、もう少し詳现です。
  • コンストラクタヌを䜿甚するず、ILogger<ExampleHandler> 型のパラメヌタヌが定矩されたす。 ILogger<TCategoryName> は、ILogger から掟生し、ILogger オブゞェクトに含たれるカテゎリを瀺したす。 DI コンテナヌでは、適切なカテゎリを持぀ ILogger を怜玢しお、これをコンストラクタヌ匕数ずしお指定したす。 そのカテゎリを持぀ ILogger がただ存圚しない堎合は、DI コンテナヌによっおサヌビス プロバむダヌの ILoggerFactory から自動的に䜜成されたす。
  • コンストラクタヌで受け取った logger パラメヌタヌは、 HandleRequest 関数のログ蚘録に䜿甚されたす。

ホストが提䟛するILoggerFactory

ホスト ビルダヌを䜿甚するず、既定の構成が初期化され、ホストのビルド時に、構成枈みの ILoggerFactory オブゞェクトがホストの DI コンテナヌに远加されたす。 ホストをビルドする前に、他のホスト䞊の HostApplicationBuilder.Logging、 WebApplicationBuilder.Logging、たたは同様の API を䜿甚しおログ構成を調敎したす。 ホストでは、 appsettings.json や環境倉数などの既定の構成゜ヌスからのログ蚘録構成も適甚されたす。 詳现に぀いおは、「.NET での構成」を参照しおください。

この䟋では、前述のものを展開しお、ILoggerFactory によっお指定された WebApplicationBuilder をカスタマむズしたす。 これにより、OpenTelemetry は、OTLP (OpenTelemetry プロトコル) でログを送信するログ プロバむダヌずしお远加されたす。

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Logging.AddOpenTelemetry(logging => logging.AddOtlpExporter());
builder.Services.AddSingleton<ExampleHandler>();
WebApplication app = builder.Build();

DI で ILoggerFactory を䜜成する

ホストなしで DI コンテナヌを䜿甚しおいる堎合は、AddLogging を䜿甚し、ILoggerFactory を構成しおコンテナヌに远加したす。

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

// Add services to the container including logging
var services = new ServiceCollection();
services.AddLogging(builder => builder.AddConsole());
services.AddSingleton<ExampleService>();
IServiceProvider serviceProvider = services.BuildServiceProvider();

// Get the ExampleService object from the container
ExampleService service = serviceProvider.GetRequiredService<ExampleService>();

// Do some pretend work
service.DoSomeWork(10, 20);

class ExampleService(ILogger<ExampleService> logger)
{
    public void DoSomeWork(int x, int y)
    {
        logger.LogInformation("DoSomeWork was called. x={X}, y={Y}", x, y);
    }
}

䞊蚘の䟋の堎合:

  • コン゜ヌルに曞き蟌むように構成された ILoggerFactory を含む DI サヌビス コンテナヌを䜜成したした
  • コンテナヌにシングルトン ExampleService を远加したした
  • DI コンテナヌから ExampleService のむンスタンスを䜜成し、コンストラクタヌ匕数ずしお䜿甚する ILogger<ExampleService> も自動的に䜜成したした。
  • ExampleService.DoSomeWork呌び出され、ILogger<ExampleService>を䜿甚しおコン゜ヌルにメッセヌゞをログに蚘録したした。

ログの蚭定

コヌドたたは構成ファむルや環境倉数などの倖郚゜ヌスを䜿甚しお、ログ蚘録の構成を蚭定したす。 倖郚構成を䜿甚するず、アプリケヌションをリビルドせずに倉曎できるため、可胜な堎合に圹立ちたす。 ただし、ログ プロバむダヌの蚭定などの䞀郚のタスクは、コヌドからのみ構成できたす。

コヌドなしでログを構成する

ホストを䜿甚するアプリの堎合は、"Logging".jsonファむルの.{Environment}セクションでログ蚘録の構成が提䟛されるのが䞀般的です。 ホストを䜿甚しないアプリの堎合は、 倖郚構成゜ヌスを明瀺的に蚭定 するか、代わりに コヌドで構成したす 。

次の appsettings.Development.json ファむルは、.NET Worker サヌビス テンプレヌトによっお生成されたす。

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

䞊蚘の JSON では、次のように指定されおいたす。

  • "Default"、"Microsoft"、"Microsoft.Hosting.Lifetime" ログ レベルのカテゎリが指定されおいたす。
  • "Default"倀は、特に指定されおいないすべおのカテゎリに適甚され、実質的にすべおのカテゎリのすべおの既定倀が"Information"されたす。 カテゎリの倀を指定しお、この動䜜をオヌバヌラむドしたす。
  • "Microsoft" カテゎリは、"Microsoft" で始たるすべおのカテゎリに適甚されたす。
  • "Microsoft" カテゎリでは、ログ レベルが Warning 以䞊のログが蚘録されたす。
  • "Microsoft.Hosting.Lifetime" カテゎリは "Microsoft" カテゎリよりも詳现なので、"Microsoft.Hosting.Lifetime" カテゎリではログ レベルが "Information" 以䞊のログが蚘録されたす。
  • 特定のログ プロバむダヌが指定されおいないため、LogLevelは、Windows EventLog を陀くすべおの有効なログ プロバむダヌに適甚されたす。

Logging プロパティには LogLevel およびログ プロバむダヌのプロパティを含めるこずができたす。 LogLevel により、遞択したカテゎリに察するログの最小レベルが指定されたす。 䞊蚘の JSON では、Information ず Warning のログ レベルが指定されおいたす。 LogLevel はログの重倧床を 0 - 6 の範囲で瀺したす。

Trace = 0、Debug = 1、Information = 2、Warning = 3、Error = 4、Critical = 5、None = 6。

LogLevel を指定するず、指定したレベル以䞊のメッセヌゞに察しおログが有効になりたす。 䞊蚘の JSON では、Default カテゎリは Information 以䞊に察しおのみログに蚘録されたす。 たずえば、Information、Warning、Error、Critical のメッセヌゞがログに蚘録されたす。 LogLevel が指定されおいない堎合、ログは既定で Information レベルになりたす。 詳现に぀いおは、「ログ レベル」を参照しおください。

プロバむダヌ プロパティで LogLevel プロパティを指定できたす。 プロバむダヌの䞋の LogLevel によっお、そのプロバむダヌのログに蚘録するレベルが指定され、プロバむダヌ以倖のログ蚭定がオヌバヌラむドされたす。 以䞋の appsettings.json ファむルに぀いお考えたす:

{
    "Logging": {
        "LogLevel": {
            "Default": "Error",
            "Microsoft": "Warning"
        },
        "Debug": {
            "LogLevel": {
                "Default": "Information",
                "Microsoft.Hosting": "Trace"
            }
        },
        "EventSource": {
            "LogLevel": {
                "Default": "Warning"
            }
        }
    }
}

Logging.{ProviderName}.LogLevel の蚭定により Logging.LogLevel の蚭定がオヌバヌラむドされたす。 䞊蚘の JSON では、Debug プロバむダヌの既定のログ レベルは Information に蚭定されおいたす。

Logging:Debug:LogLevel:Default:Information

䞊蚘の蚭定により、Information 以倖のすべおの Logging:Debug: カテゎリに Microsoft.Hosting ログ レベルが指定されたす。 特定のカテゎリが䞀芧衚瀺されるず、特定のカテゎリによっお既定のカテゎリがオヌバヌラむドされたす。 䞊蚘の JSON では、Logging:Debug:LogLevel カテゎリ "Microsoft.Hosting" ず "Default" によっお、Logging:LogLevel の蚭定がオヌバヌラむドされたす。

次のいずれかの最小ログ レベルを指定したす。

  • 特定のプロバむダヌ: たずえば、Logging:EventSource:LogLevel:Default:Information
  • 特定のカテゎリ: たずえば、Logging:LogLevel:Microsoft:Warning
  • すべおのプロバむダヌずすべおのカテゎリ: Logging:LogLevel:Default:Warning

最小レベルを䞋回るログ は次の通りではありたせん。

  • プロバむダヌに枡される。
  • ログに蚘録たたは衚瀺される。

すべおのログを抑制するには、LogLevel.None を指定したす。 LogLevel.None の倀は、LogLevel.Critical (5) より倧きい 6 です。

プロバむダヌでログのスコヌプがサポヌトされおいる堎合、IncludeScopes によっおそれを有効にするかどうかが指定されたす。 詳现に぀いおは、ログ スコヌプのを参照しおください。

次の appsettings.json ファむルには、すべおの組み蟌みプロバむダヌ甚の蚭定が含たれおいたす。

{
    "Logging": {
        "LogLevel": {
            "Default": "Error",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Warning"
        },
        "Debug": {
            "LogLevel": {
                "Default": "Information"
            }
        },
        "Console": {
            "IncludeScopes": true,
            "LogLevel": {
                "Microsoft.Extensions.Hosting": "Warning",
                "Default": "Information"
            }
        },
        "EventSource": {
            "LogLevel": {
                "Microsoft": "Information"
            }
        },
        "EventLog": {
            "LogLevel": {
                "Microsoft": "Information"
            }
        },
        "AzureAppServicesFile": {
            "IncludeScopes": true,
            "LogLevel": {
                "Default": "Warning"
            }
        },
        "AzureAppServicesBlob": {
            "IncludeScopes": true,
            "LogLevel": {
                "Microsoft": "Information"
            }
        },
        "ApplicationInsights": {
            "LogLevel": {
                "Default": "Information"
            }
        }
    }
}

䞊蚘のサンプルに぀いお:

  • カテゎリずレベルは掚奚倀ではありたせん。 このサンプルでは、すべおの既定のプロバむダヌが衚瀺されたす。
  • Logging.{ProviderName}.LogLevel の蚭定により Logging.LogLevel の蚭定がオヌバヌラむドされたす。 たずえば、Debug.LogLevel.Default のレベルにより LogLevel.Default のレベルがオヌバヌラむドされたす。
  • 各プロバむダヌの "゚むリアス" が䜿甚されおいたす。 各プロバむダヌは、完党修食型名の代わりに構成で䜿甚できる ゚むリアス を定矩したす。 組み蟌みプロバむダヌの゚むリアスは次のずおりです。
    • Console
    • Debug
    • EventSource
    • EventLog
    • AzureAppServicesFile
    • AzureAppServicesBlob
    • ApplicationInsights

コマンド ラむン、環境倉数、およびその他の構成でログ レベルを蚭定する

構成プロバむダヌのいずれかを䜿甚しおログ レベルを蚭定 したす。 たずえば、Logging:LogLevel:Microsoftの倀を持぀Informationずいう名前の氞続化された環境倉数を䜜成したす。

ログ レベルの倀が代入された、氞続化された環境倉数を䜜成したす。

:: Assigns the env var to the value
setx "Logging__LogLevel__Microsoft" "Information" /M

コマンド プロンプトの "新しい" むンスタンスで、環境倉数を読み取りたす。

:: Prints the env var value
echo %Logging__LogLevel__Microsoft%

䞊蚘の環境蚭定は、環境に保持されたす。 .NET Worker サヌビス テンプレヌトで䜜成されたアプリを䜿甚しお蚭定をテストするには、環境倉数に代入した埌、プロゞェクト ディレクトリ内で dotnet run コマンドを䜿甚したす。

dotnet run

ヒント

環境倉数を蚭定した埌、統合開発環境 (IDE) を再起動しお、新しく远加した環境倉数を䜿甚できるこずを確認したす。

Azure App Service の、 ペヌゞで > を遞択したす。 Azure App Service アプリケヌションの蚭定は

  • 保存時に暗号化され、暗号化されたチャネル経由で送信されたす。
  • 環境倉数ずしお公開されたす。

環境倉数を䜿甚しお .NET 構成倀を蚭定する方法の詳现に぀いおは、環境倉数に関する蚘事を参照しおください。

コヌドを䜿甚しおログ蚘録を構成する

コヌドにログを構成するには、ILoggingBuilder API を䜿甚したす。 さたざたな堎所からアクセスできたす。

  • ILoggerFactory を盎接䜜成する堎合は、LoggerFactory.Create に構成したす。
  • ホストなしで DI を䜿甚する堎合は、LoggingServiceCollectionExtensions.AddLogging に構成したす。
  • ホストを䜿甚する堎合は、HostApplicationBuilder.Logging、WebApplicationBuilder.Logging、たたはその他のホスト固有の API を䜿甚しお構成したす。

この䟋では、コン゜ヌル ログ プロバむダヌずいく぀かのフィルタヌを蚭定しおいたす。

using Microsoft.Extensions.Logging;

using var loggerFactory = LoggerFactory.Create(static builder =>
{
    builder
        .AddFilter("Microsoft", LogLevel.Warning)
        .AddFilter("System", LogLevel.Warning)
        .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
        .AddConsole();
});

ILogger logger = loggerFactory.CreateLogger<Program>();
logger.LogDebug("Hello {Target}", "Everyone");

前の䟋では、AddFilterさたざたなカテゎリで有効になっおいるログ レベルを調敎したす。 AddConsole はコン゜ヌル ログ プロバむダヌを远加したす。 既定では、Debug の重倧床のログは有効になっおいたせんが、構成によっおフィルタヌが調敎されたため、デバッグ メッセヌゞ "Hello Everyone" がコン゜ヌルに衚瀺されたす。

フィルタヌ芏則を適甚する方法

ILogger<TCategoryName> オブゞェクトを䜜成するず、ILoggerFactory オブゞェクトによっお、そのロガヌに適甚するプロバむダヌごずに 1 ぀の芏則が遞択されたす。 ILogger むンスタンスは、遞択したルヌルに基づいお、曞き蟌むすべおのメッセヌゞをフィルタヌ凊理したす。 䜿甚できる芏則から、各プロバむダヌずカテゎリのペアごずに最も明確な芏則が遞択されたす。

特定のカテゎリに ILogger が䜜成されるずきに、各プロバむダヌに次のアルゎリズムが䜿甚されたす。

  • プロバむダヌずその゚むリアスず䞀臎するすべおの芏則が遞択されたす。 䞀臎が芋぀からない堎合は、空のプロバむダヌですべおの芏則が遞択されたす。
  • 前の手順の結果、最も長いカテゎリのプレフィックスが䞀臎する芏則が遞択されたす。 䞀臎が芋぀からない堎合は、カテゎリを指定しないすべおの芏則が遞択されたす。
  • 耇数の芏則が遞択されおいる堎合は、最埌の 1 ぀が䜿甚されたす。
  • 芏則が遞択されおいない堎合は、LoggingBuilderExtensions.SetMinimumLevel(ILoggingBuilder, LogLevel) を䜿甚しお最小ログ蚘録レベルを指定したす。

ログのカテゎリ

ILogger オブゞェクトが䜜成されるずきに、"カテゎリ" が指定されたす。 このカテゎリは、ILogger のむンスタンスによっお䜜成される各ログ メッセヌゞず共に含められたす。 カテゎリ文字列は任意ですが、慣習的には完党修食クラス名を䜿甚したす。 たずえば、サヌビスが次のオブゞェクトように定矩されおいるアプリケヌションでは、カテゎリは "Example.DefaultService" のようになりたす。

namespace Example
{
    public class DefaultService : IService
    {
        private readonly ILogger<DefaultService> _logger;

        public DefaultService(ILogger<DefaultService> logger) =>
            _logger = logger;

        // ...
    }
}

さらなる分類が必芁な堎合、慣習的には、次のように完党修食クラス名にサブカテゎリを远加するこずで階局的な名前を䜿甚し、LoggerFactory.CreateLogger を䜿甚しおカテゎリを明瀺的に指定したす。

namespace Example
{
    public class DefaultService : IService
    {
        private readonly ILogger _logger;

        public DefaultService(ILoggerFactory loggerFactory) =>
            _logger = loggerFactory.CreateLogger("Example.DefaultService.CustomCategory");

        // ...
    }
}

固定名で CreateLogger を呌び出すこずは、むベントをカテゎリ別に敎理できるように、耇数のクラス/型で䜿甚する堎合に䟿利です。

ILogger<T> は、CreateLogger の完党修食型名を䜿甚した T の呌び出しず同じです。

ログ レベル

次の衚に、LogLevel 倀、䟿利な Log{LogLevel} 拡匵メ゜ッド、掚奚される䜿甚法を瀺したす。

LogLevel 䟡倀 メ゜ッド Description
トレヌス 0 LogTrace 最も詳现なメッセヌゞが含たれたす。 これらのメッセヌゞには、機密性の高いアプリ デヌタが含たれおいる堎合がありたす。 これらのメッセヌゞは既定で無効になっおいるため、運甚環境では有効に "しないでください"。
デバッグ 1 LogDebug デバッグず開発甚。 量が倚いため、運甚環境では慎重に䜿甚しおください。
情報 2 LogInformation アプリの䞀般的なフロヌを远跡したす。 長期的な䟡倀があるかもしれたせん。
譊告 3 LogWarning 異垞なむベントや予期しないむベント甚。 通垞、アプリが倱敗する原因にならない゚ラヌや条件が含たれたす。
゚ラヌ 4 LogError 凊理できない゚ラヌず䟋倖の堎合。 これらのメッセヌゞは、アプリ党䜓の゚ラヌではなく、珟圚の操䜜や芁求における倱敗を瀺したす。
重倧 5 LogCritical 即時の泚意が必芁な゚ラヌの堎合。 䟋: デヌタ損倱のシナリオ、ディスク領域䞍足。
なし 6 メッセヌゞを曞き蟌む必芁がないこずを指定したす。

前の衚では、重倧床が最も䜎い方から高い方に LogLevel が䞀芧衚瀺されおいたす。

Log メ゜ッドの最初のパラメヌタヌ LogLevel は、ログの重倧床を瀺したす。 ほずんどの開発者は、Log(LogLevel, ...) を呌び出すのではなく、Log{LogLevel} 拡匵メ゜ッドを呌び出したす。 Log{LogLevel} 拡匵メ゜ッドによっお、Log メ゜ッドが呌び出され、LogLevel が指定されたす。 たずえば、次の 2 ぀のログ呌び出しは、機胜的に同等で、同じログが生成されたす。

public void LogDetails()
{
    var logMessage = "Details for log.";

    _logger.Log(LogLevel.Information, AppLogEvents.Details, logMessage);
    _logger.LogInformation(AppLogEvents.Details, logMessage);
}

AppLogEvents.Details はむベント ID であり、暗黙的に Int32 定数倀によっお衚されたす。 AppLogEvents はさたざたな名前付き識別子定数を公開するクラスであり、ログ むベント ID セクションに衚瀺されたす。

Information および Warning ログを䜜成するコヌドを次に瀺したす。

public async Task<T> GetAsync<T>(string id)
{
    _logger.LogInformation(AppLogEvents.Read, "Reading value for {Id}", id);

    var result = await _repository.GetAsync(id);
    if (result is null)
    {
        _logger.LogWarning(AppLogEvents.ReadNotFound, "GetAsync({Id}) not found", id);
    }

    return result;
}

䞊蚘のコヌドでは、最初の Log{LogLevel} パラメヌタヌ ( AppLogEvents.Read) は Log むベント ID です。 2 ぀目のパラメヌタヌは、他のメ゜ッド パラメヌタヌによっお提䟛される匕数倀のプレヌスホルダヌを含むメッセヌゞ テンプレヌトです。 メ゜ッド パラメヌタヌに぀いおは、この蚘事の埌半のメッセヌゞ テンプレヌトに関するセクションで説明したす。

適切なログ レベルを構成し、適切な Log{LogLevel} メ゜ッドを呌び出しお、特定のストレヌゞ メディアに曞き蟌むログ出力の量を制埡したす。 䟋えば次が挙げられたす。

  • 運甚環境:
    • Trace たたは Debug のレベルでログを蚘録するず、詳现なログ メッセヌゞが倧量に生成されたす。 コストを制埡し、デヌタ ストレヌゞの䞊限を超えないようにするには、Trace および Debug のレベルのメッセヌゞを、倧容量の䜎コストのデヌタ ストアに蚘録したす。 Trace ず Debug を特定のカテゎリに制限するこずを怜蚎しおください。
    • Warning から Critical のレベルでログを蚘録しおも、ログ メッセヌゞはほずんど生成されたせん。
      • 通垞、コストずストレヌゞの制限は考慮されたせん。
      • ログの数が少ないほど、デヌタ ストアをより柔軟に遞択できるようになりたす。
  • 開発䞭:
    • Warning に蚭定したす。
    • トラブルシュヌティングの際に Trace たたは Debug のメッセヌゞを远加したす。 出力を制限するには、調査䞭のカテゎリに察しおのみ Trace たたは Debug を蚭定したす。

次の JSON は Logging:Console:LogLevel:Microsoft:Information を蚭定したす。

{
    "Logging": {
        "LogLevel": {
            "Microsoft": "Warning"
        },
        "Console": {
            "LogLevel": {
                "Microsoft": "Information"
            }
        }
    }
}

ログ むベント ID

各ログでは、"むベント識別子" を指定できたす。EventId は、Id および省略可胜な Name 読み取り専甚プロパティを持぀構造䜓です。 サンプル ゜ヌス コヌドでは、AppLogEvents クラスを䜿甚しおむベント ID を定矩しおいたす。

using Microsoft.Extensions.Logging;

internal static class AppLogEvents
{
    internal static EventId Create = new(1000, "Created");
    internal static EventId Read = new(1001, "Read");
    internal static EventId Update = new(1002, "Updated");
    internal static EventId Delete = new(1003, "Deleted");

    // These are also valid EventId instances, as there's
    // an implicit conversion from int to an EventId
    internal const int Details = 3000;
    internal const int Error = 3001;

    internal static EventId ReadNotFound = 4000;
    internal static EventId UpdateNotFound = 4001;

    // ...
}

ヒント

int を EventId に倉曎する方法に぀いおは、「EventId.Implicit(Int32 to EventId) 挔算子」を参照しおください。

むベント ID によっお䞀連のむベントが関連付けられたす。 たずえば、リポゞトリからの倀の読み取りに関連するすべおのログを 1001 にするこずができたす。

ログ プロバむダヌは、むベント ID を ID フィヌルド、ログ メッセヌゞ、たたはたったくログに蚘録しない可胜性がありたす。 Debug プロバむダヌでむベント ID が衚瀺されるこずはありたせん。 Console プロバむダヌでは、カテゎリの埌のブラケット内にむベント ID が衚瀺されたす。

info: Example.DefaultService.GetAsync[1001]
      Reading value for a1b2c3
warn: Example.DefaultService.GetAsync[4000]
      GetAsync(a1b2c3) not found

䞀郚のログ プロバむダヌでは、むベント ID がフィヌルドに栌玍されたす。これにより、ID に察するフィルタヌ凊理が可胜になりたす。

ログ メッセヌゞ テンプレヌト

各ログ API では、メッセヌゞ テンプレヌトが䜿甚されたす。 メッセヌゞ テンプレヌトには、指定される匕数のためのプレヌスホルダヌを含めるこずができたす。 プレヌスホルダヌには、数倀ではなく名前を䜿甚したす。 プレヌスホルダヌの名前ではなく、プレヌスホルダヌの順序によっお、倀の指定に䜿甚されるパラメヌタヌが決たりたす。 次のコヌドでは、パラメヌタヌ名がメッセヌゞ テンプレヌト内のシヌケンスの倖にありたす。

string p1 = "param1";
string p2 = "param2";
_logger.LogInformation("Parameter values: {p2}, {p1}", p1, p2);

䞊蚘のコヌドでは、シヌケンス内のパラメヌタヌ倀を含むログ メッセヌゞが䜜成されたす。

Parameter values: param1, param2

泚

1 ぀のメッセヌゞ テンプレヌト内で耇数のプレヌスホルダヌを䜿甚するずきは泚意しおください。序数基準になりたす。 名前は、匕数をプレヌスホルダヌに合わせるために䜿甚されたせん。

この方法により、ログ プロバむダヌは セマンティック ログたたは構造化ログを実装できたす。 曞匏蚭定されたメッセヌゞ テンプレヌトだけでなく、匕数自䜓がログ システムに枡されたす。 これにより、ログ プロバむダヌはフィヌルドずしおパラメヌタヌ倀を栌玍するこずができたす。 次のロガヌ メ゜ッドに぀いお考えおみたす。

_logger.LogInformation("Getting item {Id} at {RunTime}", id, DateTime.Now);

たずえば、Azure Table Storage にログを蚘録する堎合:

  • 各 Azure Table ゚ンティティには、ID プロパティず RunTime プロパティを含めるこずができたす。
  • プロパティを持぀テヌブルによっお、ログに蚘録されたデヌタに察するク゚リが簡略化されたす。 たずえば、ク゚リによっお、特定の RunTime の範囲内のすべおのログを怜玢できたす。テキスト メッセヌゞから時間を解析する必芁はありたせん。

ログ メッセヌゞ テンプレヌトの曞匏蚭定

ログ メッセヌゞ テンプレヌトでは、プレヌスホルダヌの曞匏蚭定がサポヌトされおいたす。 テンプレヌトでは、指定された型匕数に 任意の有効な圢匏 を指定できたす。 たずえば、次の Information ロガヌ メッセヌゞ テンプレヌトに぀いお考えおみたす。

_logger.LogInformation("Logged on {PlaceHolderName:MMMM dd, yyyy}", DateTimeOffset.UtcNow);
// Logged on January 06, 2022

前の䟋では、DateTimeOffset むンスタンスは、ロガヌ メッセヌゞ テンプレヌトの PlaceHolderName に察応する型になりたす。 倀は序数基準であり、この名前には䜕でも指定できたす。 MMMM dd, yyyy 圢匏は DateTimeOffset 型で有効です。

DateTime および DateTimeOffset の詳现に぀いおは、「カスタム日時圢匏文字列」をご芧ください。

䟋瀺

次の䟋では、{} プレヌスホルダヌ構文を䜿甚しおメッセヌゞ テンプレヌトを曞匏蚭定する方法が瀺されたす。 さらに、{} プレヌスホルダヌ構文を゚スケヌプする䟋がその出力ず共に瀺されたす。 最埌に、テンプレヌト プレヌスホルダヌを䜿甚した文字列補間も瀺されたす。

logger.LogInformation("Number: {Number}", 1);               // Number: 1
logger.LogInformation("{{Number}}: {Number}", 3);           // {Number}: 3
logger.LogInformation($"{{{{Number}}}}: {{Number}}", 5);    // {Number}: 5

ヒント

  • ほずんどの堎合、ログ蚘録時には、垞にログ メッセヌゞ テンプレヌトの曞匏蚭定を䜿甚する必芁がありたす。 文字列補間を䜿甚するず、パフォヌマンスに問題が発生するこずがありたす。
  • コヌド分析のルヌル「CA2254: テンプレヌトは静的な匏にする必芁がありたす」は、ログ メッセヌゞに適切な曞匏蚭定が䜿甚されおいない堎所に぀いお譊告するのに圹立ちたす。

䟋倖をログに蚘録する

ロガヌ メ゜ッドには、䟋倖パラメヌタヌを受け取るオヌバヌロヌドがありたす。

public void Test(string id)
{
    try
    {
        if (id is "none")
        {
            throw new Exception("Default Id detected.");
        }
    }
    catch (Exception ex)
    {
        _logger.LogWarning(
            AppLogEvents.Error, ex,
            "Failed to process iteration: {Id}", id);
    }
}

䟋倖ログはプロバむダヌ固有です。

既定のログ レベル

既定のログ レベルが蚭定されおいない堎合、既定のログ レベルの倀は Information。

たずえば、次のようなワヌカヌ サヌビス アプリに぀いお考えおみたす。

  • .NET Worker テンプレヌトを䜿甚しお䜜成された。
  • appsettings.json ず appsettings.Development.json が削陀たたは名前が倉曎された。

䞊蚘の蚭定で、プラむバシヌ ペヌゞたたはホヌム ペヌゞに移動するず、カテゎリ名に Trace が含たれる倚くの Debug、Information、Microsoft のメッセヌゞが生成されたす。

次のコヌドは、既定のログ レベルが構成で蚭定されおいない堎合に既定のログ レベルを蚭定したす。

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Logging.SetMinimumLevel(LogLevel.Warning);

using IHost host = builder.Build();

await host.RunAsync();

フィルタヌ関数

フィルタヌ関数は、構成たたはコヌドによっお芏則が割り圓おられおいないすべおのプロバむダヌずカテゎリに察しお呌び出されたす。

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Logging.AddFilter((provider, category, logLevel) =>
{
    return provider.Contains("ConsoleLoggerProvider")
        && (category.Contains("Example") || category.Contains("Microsoft"))
        && logLevel >= LogLevel.Information;
});

using IHost host = builder.Build();

await host.RunAsync();

䞊蚘のコヌドでは、カテゎリに Example たたは Microsoft が含たれ、ログ レベルが Information 以䞊の堎合にコン゜ヌル ログが衚瀺されたす。

ログのスコヌプ

"スコヌプ" では、論理操䜜のセットをグルヌプ化したす。 このグルヌプ化では、セットの䞀郚ずしお䜜成された各ログに同じデヌタをアタッチできたす。 たずえば、トランザクション凊理の䞀郚ずしお䜜成されるすべおのログに、トランザクション ID を含めるこずができたす。

スコヌプは:

  • IDisposable メ゜ッドによっお返される BeginScope 型です。
  • 砎棄されるたでそのたた有効です。

次のプロバむダヌではスコヌプがサポヌトされおいたす。

ロガヌの呌び出しを using ブロックでラップするこずによっお、スコヌプを䜿甚したす。

public async Task<T> GetAsync<T>(string id)
{
    T result;
    var transactionId = Guid.NewGuid().ToString();

    using (_logger.BeginScope(new List<KeyValuePair<string, object>>
        {
            new KeyValuePair<string, object>("TransactionId", transactionId),
        }))
    {
        _logger.LogInformation(
            AppLogEvents.Read, "Reading value for {Id}", id);

        var result = await _repository.GetAsync(id);
        if (result is null)
        {
            _logger.LogWarning(
                AppLogEvents.ReadNotFound, "GetAsync({Id}) not found", id);
        }
    }

    return result;
}

次の JSON では、Console プロバむダヌのスコヌプを有効にしおいたす。

{
    "Logging": {
        "Debug": {
            "LogLevel": {
                "Default": "Information"
            }
        },
        "Console": {
            "IncludeScopes": true,
            "LogLevel": {
                "Microsoft": "Warning",
                "Default": "Information"
            }
        },
        "LogLevel": {
            "Default": "Debug"
        }
    }
}

次のコヌドでは、Console プロバむダヌのスコヌプを有効にしおいたす。

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Logging.ClearProviders();
builder.Logging.AddSimpleConsole(options => options.IncludeScopes = true);

using IHost host = builder.Build();

await host.RunAsync();

Main でログを䜜成する

次のコヌドでは、ホストを構築した埌に DI から Main むンスタンスを取埗するこずによっお ILogger でログを蚘録したす。

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

using IHost host = Host.CreateApplicationBuilder(args).Build();

var logger = host.Services.GetRequiredService<ILogger<Program>>();
logger.LogInformation("Host created.");

await host.RunAsync();

䞊蚘のコヌドは、次の 2 ぀の NuGet パッケヌゞに䟝存しおいたす。

プロゞェクト ファむルは次のようになりたす。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
    <PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
  </ItemGroup>

</Project>

非同期でないロガヌ メ゜ッド

ログ蚘録は高速に実行され、非同期コヌドのパフォヌマンス コストを䞋回る必芁がありたす。 ログ デヌタ ストアが䜎速の堎合は、そこぞ盎接曞き蟌たないでください。 たずログ メッセヌゞを高速なストアに曞き蟌んでから、埌で䜎速なストアに移動するこずを怜蚎しおください。 たずえば、SQL Server にログを蚘録する堎合、Log メ゜ッドは同期しおいるため、Log メ゜ッドで盎接それを行わないでください。 代わりに、ログ メッセヌゞをむンメモリ キュヌに同期的に远加し、バックグラりンド ワヌカヌにキュヌからメッセヌゞをプルさせお、SQL Server にデヌタをプッシュする非同期凊理を実行させたす。

実行䞭のアプリのログ レベルを倉曎する

ログ API には、アプリの実行䞭にログ レベルを倉曎するシナリオは含たれおいたせん。 ただし、䞀郚の構成プロバむダヌは構成を再読み蟌みでき、ログ蚘録の構成にすぐに圱響したす。 たずえば、ファむル構成プロバむダヌでは、既定でログ構成が再床読み蟌たれたす。 アプリの実行䞭にコヌド内の構成を倉曎した堎合、アプリは IConfigurationRoot.Reload を呌び出しおアプリのログ構成を曎新できたす。

NuGet パッケヌゞ

ILogger<TCategoryName> ず ILoggerFactory のむンタヌフェむスず実装は、ほずんどの .NET SDK に暗黙的なパッケヌゞ参照ずしお含たれおいたす。 暗黙的に参照されない堎合でも、次の NuGet パッケヌゞで明瀺的に䜿甚するこずができたす。

どの .NET SDK に暗黙的なパッケヌゞ参照が含たれるかの詳现に぀いおは、.NET SDK: 暗黙的な名前空間ぞのテヌブルに関する蚘事を参照しおください。

こちらも参照ください