.NET Core および ASP.NET Core でのログ記録

作成者: Kirk LarkinJuergen GutschRick Anderson

この記事では、ASP.NET Core アプリに適用される .NET のログについて説明します。 .NET のログの詳細については、「.NET でのログの記録」を参照してください。 Blazor アプリでのログについて詳しくは、「ASP.NET Core Blazor のログ」をご覧ください。

ログ プロバイダー

ログを表示する Console プロバイダーを除き、ログ プロバイダーはログを保存します。 たとえば、Azure Application Insights プロバイダーでは、Azure Application Insights にログが保存されます。 複数のプロバイダーを有効にすることができます。

既定の ASP.NET Core Web アプリ テンプレートからは WebApplication.CreateBuilder が呼び出されます。これにより、次のログ プロバイダーが追加されます。

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

上記のコードは、ASP.NET Core Web アプリ テンプレートを使用して作成された Program.cs ファイルを示しています。 以下の一部のセクションには、ASP.NET Core Web アプリ テンプレートに基づいたサンプルが掲載されています。

次のコードでは、WebApplication.CreateBuilder によって追加された既定のログ プロバイダー一式をオーバーライドしています。

var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddConsole();

builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

前述のログ コードは次のように記述することもできます。

var builder = WebApplication.CreateBuilder();
builder.Host.ConfigureLogging(logging =>
{
    logging.ClearProviders();
    logging.AddConsole();
});

その他のプロバイダーについては、以下を参照してください。

ログを作成する

ログを作成するには、依存関係の挿入 (DI) から ILogger<TCategoryName> オブジェクトを使用します。

次のような例です。

  • AboutModel 型の完全修飾名のログ "カテゴリ" を使用する、ロガー ILogger<AboutModel> を作成します。 ログのカテゴリは、各ログに関連付けられている文字列です。
  • LogInformation を呼び出して、Information レベルでログを記録します。 ログの "レベル" は、ログに記録されるイベントの重大度を示します。
public class AboutModel : PageModel
{
    private readonly ILogger _logger;

    public AboutModel(ILogger<AboutModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
        _logger.LogInformation("About page visited at {DT}", 
            DateTime.UtcNow.ToLongTimeString());
    }
}

レベルカテゴリについては、このドキュメントで後ほど詳しく説明します。

Blazor について詳しくは、「ASP.NET Core Blazor のログ」をご覧ください。

ログの構成

一般に、ログの構成は appsettings.{ENVIRONMENT}.json ファイルの Logging セクションに記述されます。{ENVIRONMENT} は、環境を表すプレースホルダーです。 ASP.NET Core の Web アプリ テンプレートによって、次の appsettings.Development.json ファイルが生成されます。

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

上記の JSON の場合:

  • "Default" および "Microsoft.AspNetCore" の各カテゴリが指定されています。
  • "Microsoft.AspNetCore" カテゴリは、"Microsoft.AspNetCore" で始まるすべてのカテゴリに適用されます。 たとえば、この設定は "Microsoft.AspNetCore.Routing.EndpointMiddleware" カテゴリに適用されます。
  • "Microsoft.AspNetCore" カテゴリでは、ログ レベルが Warning 以上のログが記録されます。
  • 特定のログ プロバイダーが指定されていないため、LogLevel は、Windows EventLog を除くすべての有効なログ プロバイダーに適用されます。

Logging プロパティには LogLevel およびログ プロバイダーのプロパティを含めることができます。 LogLevel により、選択したカテゴリに対するログの最小レベルが指定されます。 上記の JSON では、InformationWarning のログ レベルが指定されています。 LogLevel はログの重大度を 0 - 6 の範囲で示します。

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

LogLevel を指定すると、指定したレベル以上のメッセージに対してログが有効になります。 上記の JSON では、Default カテゴリは Information 以上に対してのみログに記録されます。 たとえば、InformationWarningErrorCritical のメッセージがログに記録されます。 LogLevel が指定されていない場合、ログは既定で Information レベルになります。 詳細については、「ログ レベル」を参照してください。

プロバイダー プロパティで LogLevel プロパティを指定できます。 プロバイダーの下の LogLevel によって、そのプロバイダーのログに記録するレベルが指定され、プロバイダー以外のログ設定がオーバーライドされます。 次の appsettings.json ファイルを考えてみます。

{
  "Logging": {
    "LogLevel": { // All providers, LogLevel applies to all the enabled providers.
      "Default": "Error", // Default logging, Error and higher.
      "Microsoft": "Warning" // All Microsoft* categories, Warning and higher.
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information", // Overrides preceding LogLevel:Default setting.
        "Microsoft.Hosting": "Trace" // Debug:Microsoft.Hosting category.
      }
    },
    "EventSource": { // EventSource provider
      "LogLevel": {
        "Default": "Warning" // All categories of EventSource provider.
      }
    }
  }
}

Logging.LogLevel の設定は、Logging.{PROVIDER NAME}.LogLevel の設定によってオーバーライドされます。{PROVIDER NAME} は、プロバイダーの名前を表すプレースホルダーです。 上記の JSON では、Debug プロバイダーの既定のログ レベルは Information に設定されています。

Logging:Debug:LogLevel:Default:Information

上記の設定により、Microsoft.Hosting 以外のすべての Logging:Debug: カテゴリに Information ログ レベルが指定されます。 特定のカテゴリが一覧表示されると、特定のカテゴリによって既定のカテゴリがオーバーライドされます。 上記の 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": { // No provider, LogLevel applies to all the enabled providers.
      "Default": "Error",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Warning"
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information" // Overrides preceding LogLevel:Default setting.
      }
    },
    "Console": {
      "IncludeScopes": true,
      "LogLevel": {
        "Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning",
        "Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug",
        "Microsoft.AspNetCore.Mvc.Razor": "Error",
        "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.LogLevel の設定は、Logging.{PROVIDER NAME}.LogLevel の設定によってオーバーライドされます。{PROVIDER NAME} は、プロバイダーの名前を表すプレースホルダーです。 たとえば、Debug.LogLevel.Default のレベルにより LogLevel.Default のレベルがオーバーライドされます。
  • 各既定のプロバイダーの "別名" が使用されます。 各プロバイダーでは "エイリアス" が定義されます。これは構成で完全修飾型名の代わりに使用できます。 組み込みプロバイダーの別名には次のものがあります。
    • Console
    • Debug
    • EventSource
    • EventLog
    • AzureAppServicesFile
    • AzureAppServicesBlob
    • ApplicationInsights

Program.cs 内のログ

次の例では、Program.csBuilder.WebApplication.Logger を呼び出し、情報メッセージをログに記録します。

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Logger.LogInformation("Adding Routes");
app.MapGet("/", () => "Hello World!");
app.Logger.LogInformation("Starting the app");
app.Run();

次の例では、Program.csAddConsole を呼び出し、/Test エンドポイントをログに記録します。

var builder = WebApplication.CreateBuilder(args);

builder.Logging.AddConsole();

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.MapGet("/Test", async (ILogger<Program> logger, HttpResponse response) =>
{
    logger.LogInformation("Testing logging in Program.cs");
    await response.WriteAsync("Testing");
});

app.Run();

次の例では、Program.csAddSimpleConsole を呼び出し、カラー出力を無効にして、/Test エンドポイントをログに記録します。

using Microsoft.Extensions.Logging.Console;

var builder = WebApplication.CreateBuilder(args);

builder.Logging.AddSimpleConsole(i => i.ColorBehavior = LoggerColorBehavior.Disabled);

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.MapGet("/Test", async (ILogger<Program> logger, HttpResponse response) =>
{
    logger.LogInformation("Testing logging in Program.cs");
    await response.WriteAsync("Testing");
});

app.Run();

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

ログ レベルは、いずれかの構成プロバイダーで設定できます。

: の区切り記号は、すべてのプラットフォームの環境変数階層キーには対応していません。 __(ダブルアンダースコア)は、

  • すべてのプラットフォームに対応しています。 たとえば、:: の区切り記号には対応していませんが、__ には対応しています。
  • 自動で : に置換されます。

次のコマンドは:

  • 環境キー Logging:LogLevel:Microsoft を Windows の Information の値に設定します。
  • ASP.NET Core Web アプリケーション テンプレートを使用して作成されたアプリを使用する際に、設定をテストします。 dotnet run コマンドは、set を使用した後、プロジェクト ディレクトリで実行する必要があります。
set Logging__LogLevel__Microsoft=Information
dotnet run

上記の環境設定は:

  • コマンド ウィンドウから起動されたプロセスでのみ設定可能です。
  • Visual Studio で起動されたブラウザーでは読み取れません。

次の setx コマンドは、Windows 上で環境キーと値も設定します。 set とは異なり、setx 設定は保持されます。 /M スイッチにより、システム環境で変数が設定されます。 /M が使用されていない場合には、ユーザー環境変数が設定されます。

setx Logging__LogLevel__Microsoft Information /M

次の appsettings.json ファイルを考えてみます。

"Logging": {
  "Console": {
    "LogLevel": {
      "Microsoft.Hosting.Lifetime": "Trace"
    }
  }
}

次のコマンドは、上記の構成を環境に設定するものです。

setx Logging__Console__LogLevel__Microsoft.Hosting.Lifetime Trace /M

Note

macOS と Linux で . (ピリオド) を含む名前で環境変数を構成する場合は、Stack Exchange の「ドット (.) が含まれる変数のエクスポート」という質問と、それに対して受け入れられた回答を考慮してください。

Azure App Service の、[設定] > [構成] ページで [新しいアプリケーション設定] を選択します。 Azure App Service アプリケーションの設定は:

  • 保存時に暗号化され、暗号化されたチャネルで送信されます。
  • 環境変数として公開されます。

詳細については、Azure アプリの、Azure portal を使ったアプリの構成のオーバーライドに関する記事を参照してください。

環境変数を使用して ASP.NET Core 構成値を設定する方法の詳細については、「環境変数」を参照してください。 コマンド ライン、Azure Key Vault、Azure App Configuration、その他のファイル形式など、他の構成ソースの使用の詳細については、「ASP.NET Core の構成」を参照してください。

フィルター規則を適用する方法

ILogger<TCategoryName> オブジェクトを作成すると、ILoggerFactory オブジェクトによって、そのロガーに適用するプロバイダーごとに 1 つの規則が選択されます。 ILogger インスタンスによって書き込まれるすべてのメッセージは、選択した規則に基づいてフィルター処理されます。 使用できる規則から、各プロバイダーとカテゴリのペアごとに最も明確な規則が選択されます。

特定のカテゴリに ILogger が作成されるときに、各プロバイダーに次のアルゴリズムが使用されます。

  • プロバイダーとそのエイリアスと一致するすべての規則が選択されます。 一致が見つからない場合は、空のプロバイダーですべての規則が選択されます。
  • 前の手順の結果、最も長いカテゴリのプレフィックスが一致する規則が選択されます。 一致が見つからない場合は、カテゴリを指定しないすべての規則が選択されます。
  • 複数の規則が選択されている場合は、最後の 1 つが使用されます。
  • 規則が選択されていない場合は、MinimumLevel が使用されます。

dotnet run および Visual Studio からのログ出力

既定のログ プロバイダーで作成されたログが表示されます。

  • Visual Studio 内
    • デバッグ時はデバッグ出力ウィンドウ内。
    • ASP.NET Core Web サーバー ウィンドウ内。
  • アプリが dotnet run で実行されている場合はコンソール ウィンドウ内。

"Microsoft" カテゴリから始まるログは、ASP.NET Core のフレームワークのコードからのログです。 ASP.NET Core とアプリケーション コードでは、同じログ API とログ プロバイダーが使用されます。

ログのカテゴリ

ILogger オブジェクトが作成されるときに、"カテゴリ" が指定されます。 このカテゴリは、ILogger のインスタンスによって作成される各ログ メッセージと共に含められます。 カテゴリ文字列は任意ですが、慣習的には完全修飾クラス名を使用します。 たとえば、コントローラーでは、名前が "TodoApi.Controllers.TodoController" になる場合があります。 ASP.NET Core Web アプリでは、ILogger<T> を使用して、カテゴリとして T の完全修飾型名を使用する ILogger インスタンスが自動的に取得されます。

public class PrivacyModel : PageModel
{
    private readonly ILogger<PrivacyModel> _logger;

    public PrivacyModel(ILogger<PrivacyModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.PrivacyModel called.");
    }
}

さらなる分類が必要な場合、慣習的には、以下のように完全修飾クラス名にサブカテゴリを追加することで階層的な名前を使用し、ILoggerFactory.CreateLogger を使用してカテゴリを明示的に指定します。

public class ContactModel : PageModel
{
    private readonly ILogger _logger;

    public ContactModel(ILoggerFactory logger)
    {
        _logger = logger.CreateLogger("TodoApi.Pages.ContactModel.MyCategory");
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.ContactModel called.");
    }

複数のメソッドで使用する場合、固定名を使用して CreateLogger を呼び出すと、イベントをカテゴリ別に分類できるので便利です。

ILogger<T> は、T の完全修飾型名を使用した CreateLogger の呼び出しと同じです。

ログ レベル

次の表に、LogLevel 値、便利な Log{LogLevel} 拡張メソッド、推奨される使用法を示します。

LogLevel [値] Method 説明
Trace 0 LogTrace 最も詳細なメッセージが含まれます。 これらのメッセージには、機密性の高いアプリ データが含まれる場合があります。 これらのメッセージは既定で無効になっているため、運用環境では有効に "しないでください"。
Debug 1 LogDebug デバッグと開発用。 量が多いため、運用環境では慎重に使用してください。
Information 2 LogInformation アプリの一般的なフローを追跡します。 長期的な値が含まれている可能性があります。
Warning 3 LogWarning 異常なイベントや予期しないイベント用。 通常、アプリが失敗する原因にならないエラーや条件が含まれます。
Error 4 LogError 処理できないエラーと例外の場合。 これらのメッセージは、アプリ全体のエラーではなく、現在の操作や要求における失敗を示します。
Critical 5 LogCritical 即時の注意が必要なエラーの場合。 例: データ損失のシナリオ、ディスク領域不足。
None 6 ログのカテゴリにメッセージを出力しないように指定します。

前の表では、重大度が最も低い方から高い方に LogLevel が一覧表示されています。

Log メソッドの最初のパラメーター LogLevel は、ログの重大度を示します。 ほとんどの開発者は、Log(LogLevel, ...) を呼び出すのではなく、Log{LOG LEVEL} 拡張メソッドを呼び出します。{LOG LEVEL} は、ログ レベルを表すプレースホルダーです。 たとえば、次の 2 つのログ呼び出しは、機能的に同等で、同じログが生成されます。

[HttpGet]
public IActionResult Test1(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);

    _logger.Log(LogLevel.Information, MyLogEvents.TestItem, routeInfo);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    return ControllerContext.MyDisplayRouteInfo();
}

MyLogEvents.TestItem はイベント ID です。 MyLogEvents はサンプル アプリの一部であり、ログ イベント ID セクションに表示されます。

MyDisplayRouteInfo and ToCtxStringRick.Docs.Samples.RouteInfo NuGet パッケージによって提供されます。 このメソッドにより Controller および Razor Page ルート情報が表示されます。

Information および Warning ログを作成するコードを次に示します。

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

上記のコードでは、最初の Log{LOG LEVEL} パラメーター MyLogEvents.GetItem は、ログ イベント ID です。 2 つ目のパラメーターは、他のメソッド パラメーターによって提供される引数値のプレースホルダーを含むメッセージ テンプレートです。 メソッド パラメーターについては、このドキュメントで後述するメッセージ テンプレートのセクションで説明します。

適切な Log{LOG LEVEL} メソッドを呼び出して、特定のストレージ メディアに書き込むログ出力量を制御します。 次に例を示します。

  • 運用環境:
    • TraceDebug、または Information のレベルでログすると、詳細なログ メッセージが大量に生成されます。 コストを制御し、データ ストレージの上限を超えないようにするには、TraceDebug、または Information のレベルのメッセージを、大容量の低コストのデータ ストアにログします。 TraceDebugInformation を特定のカテゴリに制限することを検討してください。
    • Warning から Critical のレベルでログを記録しても、ログ メッセージはほとんど生成されません。
      • 通常、コストとストレージの制限は考慮されません。
      • ログの数が少ないほど、データ ストアをより柔軟に選択できるようになります。
  • 開発中:
    • Warning に設定します。
    • トラブルシューティングの際に TraceDebug、または Information のメッセージを追加します。 出力を制限するには、調査中のカテゴリに対してのみ TraceDebug、または Information を設定します。

ASP.NET Core では、フレームワーク イベントのログが書き込まれます。 たとえば、次のログ出力について考えてみます。

  • ASP.NET Core テンプレートを使用して作成された Razor Pages アプリ
  • Logging:Console:LogLevel:Microsoft:Information に設定されているログ。
  • Privacy ページへの移動。
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/2 GET https://localhost:5001/Privacy
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint '/Privacy'
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[3]
      Route matched with {page = "/Privacy"}. Executing page /Privacy
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[101]
      Executing handler method DefaultRP.Pages.PrivacyModel.OnGet - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[102]
      Executed handler method OnGet, returned result .
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[103]
      Executing an implicit handler method - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[104]
      Executed an implicit handler method, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult.
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[4]
      Executed page /Privacy in 74.5188ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint '/Privacy'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 149.3023ms 200 text/html; charset=utf-8

次の JSON では、Logging:Console:LogLevel:Microsoft:Information が設定されます。

{
  "Logging": {      // Default, all providers.
    "LogLevel": {
      "Microsoft": "Warning"
    },
    "Console": { // Console provider.
      "LogLevel": {
        "Microsoft": "Information"
      }
    }
  }
}

ログ イベント ID

各ログで "イベント ID" を指定できます。 このサンプル アプリでは、MyLogEvents クラスを使用してイベント ID を定義します。

public class MyLogEvents
{
    public const int GenerateItems = 1000;
    public const int ListItems     = 1001;
    public const int GetItem       = 1002;
    public const int InsertItem    = 1003;
    public const int UpdateItem    = 1004;
    public const int DeleteItem    = 1005;

    public const int TestItem      = 3000;

    public const int GetItemNotFound    = 4000;
    public const int UpdateItemNotFound = 4001;
}
[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

イベント ID によって一連のイベントが関連付けられます。 たとえば、ページ上に項目の一覧を表示する機能に関連するすべてのログを 1001 に設定します。

ログ プロバイダーでは、ID フィールドやログ メッセージにイベント ID が格納されたり、またはまったく格納されなかったりする場合があります。 Debug プロバイダーでイベント ID が表示されることはありません。 Console プロバイダーでは、カテゴリの後のブラケット内にイベント ID が表示されます。

info: TodoApi.Controllers.TodoItemsController[1002]
      Getting item 1
warn: TodoApi.Controllers.TodoItemsController[4000]
      Get(1) NOT FOUND

一部のログ プロバイダーでは、イベント ID がフィールドに格納されます。これにより、ID に対するフィルター処理が可能になります。

ログ メッセージ テンプレート

各ログ API では、メッセージ テンプレートが使用されます。 メッセージ テンプレートには、指定される引数のためのプレースホルダーを含めることができます。 プレースホルダーには、数値ではなく名前を使用します。

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

ログ メッセージにプレースホルダーの値を渡すために使用されるパラメーターは、プレースホルダーの名前ではなく "パラメーターの順序" によって決まります。 次のコードのメッセージ テンプレートのプレースホルダーは、パラメーター名の順番が正しくありません。

var apples = 1;
var pears = 2;
var bananas = 3;

_logger.LogInformation("Parameters: {Pears}, {Bananas}, {Apples}", apples, pears, bananas);

しかし、プレースホルダーには、applespearsbananas という順序でパラメーターが割り当てられます。 ログ メッセージに、パラメーターの順序が反映されています。

Parameters: 1, 2, 3

この方法により、ログ プロバイダーが セマンティック ログまたは構造化ログを実装できるようになります。 書式設定されたメッセージ テンプレートだけでなく、引数自体がログ システムに渡されます。 これにより、ログ プロバイダーはフィールドとしてパラメーター値を格納することができます。 たとえば、次のロガー メソッドについて考えてみます。

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

たとえば、Azure Table Storage にログを記録する場合:

  • 各 Azure Table エンティティには、ID プロパティと RequestTime プロパティを含めることができます。
  • プロパティを持つテーブルによって、ログに記録されたデータに対するクエリが簡略化されます。 たとえば、クエリによって、特定の RequestTime の範囲内のすべてのログを検索できます。テキスト メッセージから時間を解析する必要はありません。

例外をログに記録する

ロガー メソッドには、例外パラメーターを受け取るオーバーロードがあります。

[HttpGet("{id}")]
public IActionResult TestExp(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    try
    {
        if (id == 3)
        {
            throw new Exception("Test exception");
        }
    }
    catch (Exception ex)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, ex, "TestExp({Id})", id);
        return NotFound();
    }

    return ControllerContext.MyDisplayRouteInfo();
}

MyDisplayRouteInfo and ToCtxStringRick.Docs.Samples.RouteInfo NuGet パッケージによって提供されます。 このメソッドにより Controller および Razor Page ルート情報が表示されます。

例外ログはプロバイダー固有です。

既定のログ レベル

既定のログ レベルが設定されていない場合、既定のログ レベル値は Information になります。

たとえば、次の Web アプリについて考えてみます。

  • ASP.NET Web アプリ テンプレートを使用して作成された。
  • appsettings.jsonappsettings.Development.json は削除されているか、名前が変更されている。

上記の設定で、プライバシー ページまたはホーム ページに移動すると、カテゴリ名に Microsoft が含まれる多くの TraceDebugInformation のメッセージが生成されます。

次のコードは、既定のログ レベルが構成で設定されていない場合に、既定のログ レベルを設定します。

var builder = WebApplication.CreateBuilder();
builder.Logging.SetMinimumLevel(LogLevel.Warning);

一般に、ログ レベルは、コードではなく構成で指定する必要があります。

フィルター関数

フィルター関数は、構成またはコードによって規則が割り当てられていないすべてのプロバイダーとカテゴリに対して呼び出されます。

var builder = WebApplication.CreateBuilder();
builder.Logging.AddFilter((provider, category, logLevel) =>
{
    if (provider.Contains("ConsoleLoggerProvider")
        && category.Contains("Controller")
        && logLevel >= LogLevel.Information)
    {
        return true;
    }
    else if (provider.Contains("ConsoleLoggerProvider")
        && category.Contains("Microsoft")
        && logLevel >= LogLevel.Information)
    {
        return true;
    }
    else
    {
        return false;
    }
});

上記のコードでは、カテゴリに Controller または Microsoft が含まれ、ログ レベルが Information 以上の場合にコンソール ログが表示されます。

一般に、ログ レベルは、コードではなく構成で指定する必要があります。

ASP.NET Core と EF Core のカテゴリ

次の表に、ASP.NET Core と Entity Framework Core で使用されるいくつかのカテゴリと、ログに関するメモを示します。

カテゴリ メモ
Microsoft.AspNetCore ASP.NET Core の一般的な診断。
Microsoft.AspNetCore.DataProtection どのキーが検討、検索、および使用されたか。
Microsoft.AspNetCore.HostFiltering 許可されるホスト。
Microsoft.AspNetCore.Hosting HTTP 要求が完了するまでにかかった時間と、それらの開始時刻。 どのホスティング スタートアップ アセンブリが読み込まれたか。
Microsoft.AspNetCore.Mvc MVC と Razor の診断。 モデルの構築、フィルター処理の実行、ビューのコンパイル、アクションの選択。
Microsoft.AspNetCore.Routing 一致する情報をルーティングします。
Microsoft.AspNetCore.Server 接続の開始、停止、キープ アライブ応答。 HTTPS 証明書情報。
Microsoft.AspNetCore.StaticFiles 提供されるファイル。
Microsoft.EntityFrameworkCore Entity Framework Core の一般的な診断。 データベースのアクティビティと構成、変更の検出、移行。

コンソール ウィンドウに他のカテゴリを表示するには、appsettings.Development.json を次のように設定します。

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

ログのスコープ

"スコープ" では、論理操作のセットをグループ化できます。 このグループ化を使用して、セットの一部として作成される各ログに同じデータをアタッチすることができます。 たとえば、トランザクション処理の一部として作成されるすべてのログに、トランザクション ID を含めることができます。

スコープは:

  • BeginScope メソッドによって返される IDisposable 型です。
  • 破棄されるまで継続します。

次のプロバイダーではスコープがサポートされています。

ロガーの呼び出しを using ブロックでラップすることによって、スコープを使用します。

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    TodoItem todoItem;
    var transactionId = Guid.NewGuid().ToString();
    using (_logger.BeginScope(new List<KeyValuePair<string, object>>
        {
            new KeyValuePair<string, object>("TransactionId", transactionId),
        }))
    {
        _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

        todoItem = await _context.TodoItems.FindAsync(id);

        if (todoItem == null)
        {
            _logger.LogWarning(MyLogEvents.GetItemNotFound, 
                "Get({Id}) NOT FOUND", id);
            return NotFound();
        }
    }

    return ItemToDTO(todoItem);
}

組み込みのログ プロバイダー

ASP.NET Core には、共有フレームワークの一部として次のログ プロバイダーが含まれています。

次のログ プロバイダーは、Microsoft によって出荷されますが、共有フレームワークの一部としては提供されません。 これらは別途 NuGet としてインストールする必要があります。

ASP.NET Core には、ログをファイルに書き込むためのログ プロバイダーは含まれていません。 ASP.NET Core アプリからのログをファイルに書き込むには、サードパーティのログ プロバイダーの使用を検討してください。

ASP.NET Core モジュールのデバッグ ログおよび stdout については、「Azure App Service および IIS での ASP.NET Core のトラブルシューティング」および「IIS の ASP.NET Core モジュール (ANCM)」を参照してください。

コンソール

Console プロバイダーでは、コンソールへの出力がログに記録されます。 開発中の Console ログを表示する方法の詳細については、「dotnet run および Visual Studio からのログ出力」を参照してください。

デバッグ

Debug プロバイダーでは、System.Diagnostics.Debug クラスを使ってログ出力が書き込まれます。 Debug プロバイダーに書き込むために System.Diagnostics.Debug.WriteLine が呼び出されます。

Linux では、Debug プロバイダーのログの場所は配布によって異なり、次のいずれかになります。

  • /var/log/message
  • /var/log/syslog

イベント ソース

EventSource プロバイダーでは、Microsoft-Extensions-Logging という名前のクロスプラットフォーム イベント ソースに書き込まれます。 Windows では、プロバイダーによって ETW が使用されます。

dotnet-trace ツール

dotnet-trace ツールは、実行中のプロセスの .NET Core のトレースのコレクションを有効にする、クロスプラットフォームの CLI グローバル ツールです。 このツールでは、LoggingEventSource を使用して Microsoft.Extensions.Logging.EventSource プロバイダー データを収集します。

インストール手順については、「dotnet-trace」をご覧ください。

dotnet-trace ツールを使用して、アプリからトレースを収集します。

  1. dotnet run コマンドを使用してアプリを実行します。

  2. .NET Core アプリのプロセス識別子 (PID) を決定します。

    dotnet-trace ps
    

    アプリのアセンブリと同じ名前を持つプロセスの PID を検索します。

  3. dotnet-trace コマンドを実行します。

    一般的なコマンド構文

    dotnet-trace collect -p {PID} 
        --providers Microsoft-Extensions-Logging:{Keyword}:{Provider Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Category Level 1};
                {Logger Category 2}:{Category Level 2};
                ...
                {Logger Category N}:{Category Level N}\"
    

    PowerShell コマンド シェルを使用する場合は、--providers 値を単一引用符 (') で囲みます。

    dotnet-trace collect -p {PID} 
        --providers 'Microsoft-Extensions-Logging:{Keyword}:{Provider Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Category Level 1};
                {Logger Category 2}:{Category Level 2};
                ...
                {Logger Category N}:{Category Level N}\"'
    

    Windows 以外のプラットフォームでは、-f speedscope オプションを追加して、出力トレース ファイルの形式を speedscope に変更します。

    次の表にキーワードを定義します。

    Keyword 説明
    1 LoggingEventSource に関するメタ イベントをログに記録します。 ILogger からのイベントは記録されません。
    2 ILogger.Log() が呼び出されたときに、Message イベントをオンにします。 プログラムで (書式設定されずに) 情報が提供されます。
    4 ILogger.Log() が呼び出されたときに、FormatMessage イベントをオンにします。 書式設定された文字列バージョンの情報が提供されます。
    8 ILogger.Log() が呼び出されたときに、MessageJson イベントをオンにします。 引数の JSON 表現が提供されます。

    次の表は、プロバイダー レベルの一覧です。

    プロバイダー レベル 説明
    0 LogAlways
    1 Critical
    2 Error
    3 Warning
    4 Informational
    5 Verbose

    カテゴリ レベルの解析には、文字列または数値を指定できます。

    カテゴリの名前付きの値 数値
    Trace 0
    Debug 1
    Information 2
    Warning 3
    Error 4
    Critical 5

    プロバイダー レベルとカテゴリ レベル:

    • 順序が逆になります。
    • 文字列定数は、必ずしも同一ではありません。

    FilterSpecs が指定されなかった場合、EventSourceLogger の実装は、プロバイダー レベルをカテゴリ レベルに変換し、それをすべてのカテゴリに適用することを試みます。

    プロバイダー レベル カテゴリ レベル
    Verbose(5) Debug(1)
    Informational(4) Information(2)
    Warning(3) Warning(3)
    Error(2) Error(4)
    Critical(1) Critical(5)

    FilterSpecs が指定されている場合、一覧に含まれるカテゴリには、そこでエンコードされているカテゴリ レベルが使用され、その他のカテゴリはすべてフィルターで除外されます。

    以下の例では、次のことを想定しています。

    • アプリが実行中であり、logger.LogDebug("12345") を呼び出している。
    • プロセス ID (PID) が set PID=12345 を介して設定されている。ここで、12345 は実際の PID を表します。

    次のようなコマンドについて考えてみます。

    dotnet-trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:5
    

    上記のコマンドでは次のことが行われます。

    • デバッグ メッセージをキャプチャします。
    • FilterSpecs は適用されません。
    • Debug カテゴリに対応するレベル 5 を指定します。

    次のようなコマンドについて考えてみます。

    dotnet-trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:5\"
    

    上記のコマンドでは次のことが行われます。

    • カテゴリ レベル 5 は Critical であるため、デバッグ メッセージはキャプチャしません。
    • FilterSpecs を指定します。

    次のコマンドでは、カテゴリ レベル 1 によって Debug が指定されているため、デバッグ メッセージがキャプチャされます。

    dotnet-trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:1\"
    

    次のコマンドでは、カテゴリによって Debug が指定されているため、デバッグ メッセージがキャプチャされます。

    dotnet-trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:Debug\"
    

    {Logger Category}{Category Level}FilterSpecs エントリは、追加のログ フィルター条件を表します。 FilterSpecs のエントリの区切りには、セミコロン (;) を使用します。

    Windows コマンド シェルを使用する例:

    dotnet-trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:2:FilterSpecs=\"Microsoft.AspNetCore.Hosting*:4\"
    

    上記のコマンドにより次のことがアクティブになります。

    • エラー (2) に対して書式設定された文字列 (4) を生成するイベント ソース ロガー。
    • Informational ログ レベル (4) での Microsoft.AspNetCore.Hosting のログ記録。
  4. Enter キーまたは Ctr+C キーを押すことで、dotnet-trace ツールを停止します。

    トレースは、dotnet-trace コマンドが実行されたフォルダーに trace.nettrace という名前で保存されます。

  5. Perfview を使用してトレースを開きます。 trace.nettrace ファイルを開き、トレース イベントを調べます。

アプリで WebApplication.CreateBuilder を使ってホストがビルドされない場合は、イベント ソース プロバイダーをアプリのログ構成に追加します。

詳細については次を参照してください:

Perfview

ログの収集と表示には、PerfView ユーティリティを使用します。 ETW ログを表示できる他のツールはありますが、ASP.NET Core から出力される ETW イベントを操作する場合、PerfView は最適なエクスペリエンスを提供します。

このプロバイダーでログに記録されるイベントを収集するように PerfView を構成するには、 [追加プロバイダー] の一覧に文字列 *Microsoft-Extensions-Logging を追加します 文字列の先頭にある * を忘れないでください。

Windows EventLog

EventLog プロバイダーにより、ログ出力が Windows イベント ログに送信されます。 他のプロバイダーとは異なり、EventLog プロバイダーでは既定のプロバイダー以外の設定が継承 "されません"。 EventLog ログ設定が指定されていない場合は、既定の LogLevel.Warning になります。

LogLevel.Warning より下のイベントをログに記録するには、ログ レベルを明示的に設定してください。 次の例では、イベント ログの既定のログ レベルを LogLevel.Information に設定します。

"Logging": {
  "EventLog": {
    "LogLevel": {
      "Default": "Information"
    }
  }
}

AddEventLog のオーバーロードを使用すると、EventLogSettings を渡すことができます。 null または指定しない場合は、次の既定の設定が使用されます。

  • LogName:"Application"
  • SourceName: ".NET Runtime"
  • MachineName:ローカル コンピューター名が使用されます。

次のコードでは、SourceName が既定値の ".NET Runtime" から MyLogs に変更されます。


var builder = WebApplication.CreateBuilder();
builder.Logging.AddEventLog(eventLogSettings =>
{
    eventLogSettings.SourceName = "MyLogs";
});

Azure App Service

Microsoft.Extensions.Logging.AzureAppServices プロバイダー パッケージは、Azure App Service アプリのファイル システムのテキスト ファイルと、Azure ストレージ アカウントの BLOB ストレージにログを書き込みます。

プロバイダー パッケージは、共有フレームワークに含まれていません。 プロバイダーを使用するには、プロバイダー パッケージをプロジェクトに追加します。

プロバイダーの設定を構成するには、次の例のように AzureFileLoggerOptionsAzureBlobLoggerOptions を使用します。

using Microsoft.Extensions.Logging.AzureAppServices;

var builder = WebApplication.CreateBuilder();
builder.Logging.AddAzureWebAppDiagnostics();
builder.Services.Configure<AzureFileLoggerOptions>(options =>
{
    options.FileName = "azure-diagnostics-";
    options.FileSizeLimit = 50 * 1024;
    options.RetainedFileCountLimit = 5;
});
builder.Services.Configure<AzureBlobLoggerOptions>(options =>
{
    options.BlobName = "log.txt";
});

Azure App Service にデプロイされると、Azure portal の [App Service] ページの [App Service ログ] セクションの設定がアプリで使用されます。 次の設定が更新されると、アプリの再起動や再デプロイを必要とせずに、変更がすぐに有効になります。

  • [アプリケーション ログ (ファイル システム)]
  • [アプリケーション ログ (BLOB)]

ログ ファイルの既定の場所は、D:\\home\\LogFiles\\Application です。既定のファイル名は diagnostics-yyyymmdd.txt です。 既定のファイル サイズ制限は 10 MB です。保持されるファイルの既定の最大数は 2 です。 既定の BLOB 名は {app-name}{timestamp}/yyyy/mm/dd/hh/{guid}-applicationLog.txt です。

このプロバイダーは、プロジェクトが Azure 環境で実行される場合にのみログを記録します。

Azure ログのストリーミング

Azure ログのストリーミングでは、以下からのリアル タイムでのログ アクティビティの表示がサポートされています。

  • アプリ サーバー
  • Web サーバー
  • 失敗した要求のトレース

Azure ログのストリーミングを構成するには

  • アプリのポータル ページから [App Service ログ] ページに移動します。
  • [アプリケーション ログ (ファイル システム)][オン] に設定します。
  • ログ [レベル] を選択します。 この設定は、Azure ログ ストリーミングにのみ適用されます。

[ログ ストリーム] ページに移動して、ログを表示します。 ログに記録されたメッセージは、ILogger インターフェイスを使用してログに記録されます。

Azure Application Insights

Microsoft.Extensions.Logging.ApplicationInsights プロバイダー パッケージは、Azure Application Insights にログを書き込みます。 Application Insights は、Web アプリを監視するサービスであり、クエリを実行してテレメトリ データを分析するためのツールを提供します。 このプロバイダーを使用する場合は、Application Insights ツールを使ってクエリを実行し、ログを分析できます。

ログ プロバイダーは、Microsoft.ApplicationInsights.AspNetCore の依存関係として組み込まれており、ASP.NET Core で利用可能なすべてのテレメトリを提供するパッケージです。 このパッケージを使用する場合は、プロバイダー パッケージをインストールする必要はありません。

Microsoft.ApplicationInsights.Web パッケージは、ASP.NET Core ではなく、ASP.NET 4.x 用です。

詳細については、次のリソースを参照してください。

サードパーティ製のログ プロバイダー

ASP.NET Core で使用できるサードパーティ製のログ記録フレームワークをいくつか紹介します。

一部のサードパーティ製フレームワークは、セマンティック ログ記録 (構造化ログ記録とも呼ばれます) を実行できます。

サード パーティ製フレームワークを使用することは、組み込みのプロバイダーのいずれかを使用することと似ています。

  1. プロジェクトに NuGet パッケージを追加します。
  2. ログ記録フレームワークによって提供される ILoggerFactory 拡張メソッドを呼び出します。

詳細については、各プロバイダーのドキュメントをご覧ください。 サード パーティ製のログ プロバイダーは、Microsoft ではサポートされていません。

非同期でないロガー メソッド

ログ記録は高速に実行され、非同期コードのパフォーマンス コストを下回る必要があります。 ログ データ ストアが低速の場合は、そこへ直接書き込まないでください。 まずログ メッセージを高速なストアに書き込んでから、後で低速なストアに移動することを検討してください。 たとえば、SQL Server にログを記録する場合、Log メソッドは同期しているため、Log メソッドで直接それを行わないでください。 代わりに、ログ メッセージをインメモリ キューに同期的に追加し、バックグラウンド ワーカーにキューからメッセージをプルさせて、SQL Server にデータをプッシュする非同期処理を実行させます。 詳細については、低速なデータ ストアのメッセージ キューにログする方法についてのガイダンス (dotnet/AspNetCore.Docs #11801) に関するページを参照してください。

実行中のアプリのログ レベルを変更する

ログ API には、アプリの実行中にログ レベルを変更するシナリオは含まれていません。 ただし、一部の構成プロバイダーは構成を再読み込みすることができ、ログ構成に直ちに影響します。 たとえば、ファイル構成プロバイダーでは、既定でログ構成が再度読み込まれます。 アプリの実行中にコードの構成が変更された場合、アプリは IConfigurationRoot.Reload を呼び出して、アプリのログ構成を更新できます。

ILogger と ILoggerFactory

ILogger<TCategoryName>ILoggerFactory のインターフェイスと実装は .NET Core SDK に含まれています。 これらは、次の NuGet パッケージでも入手できます。

コードでログ フィルター規則を適用する

ログ フィルター規則を設定するには、構成を使用することをお勧めします。

コードにフィルター規則を登録する方法を次の例に示します。

using Microsoft.Extensions.Logging.Console;
using Microsoft.Extensions.Logging.Debug;

var builder = WebApplication.CreateBuilder();
builder.Logging.AddFilter("System", LogLevel.Debug);
builder.Logging.AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information);
builder.Logging.AddFilter<ConsoleLoggerProvider>("Microsoft", LogLevel.Trace);

logging.AddFilter("System", LogLevel.Debug)System カテゴリとログ レベル Debug を指定します。 特定のプロバイダーが構成されていないため、フィルターはすべてのプロバイダーに適用されます。

AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information) は以下を指定します。

  • Debug ログ プロバイダー。
  • ログ レベル Information 以上。
  • "Microsoft" で始まるすべてのカテゴリ。

SpanIdTraceIdParentIdBaggageTags を使用してスコープを自動的にログする

ログ ライブラリでは、SpanIdTraceIdParentIdBaggageTags を使用してスコープ オブジェクトが暗黙的に作成されます。 この動作は、ActivityTrackingOptions を使用して構成されます。

var builder = WebApplication.CreateBuilder(args);

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

builder.Logging.Configure(options =>
{
    options.ActivityTrackingOptions = ActivityTrackingOptions.SpanId
                                       | ActivityTrackingOptions.TraceId
                                       | ActivityTrackingOptions.ParentId
                                       | ActivityTrackingOptions.Baggage
                                       | ActivityTrackingOptions.Tags;
});
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

traceparent HTTP 要求ヘッダーが設定されている場合、ログ スコープの ParentId にインバウンド traceparent ヘッダーからの W3C parent-id が、また、ログ スコープの SpanId に、次のアウトバウンド ステップまたはアウトバウンド スパン用に更新された parent-id が示されます。 詳細については、「traceparent フィールドの変更」を参照してください。

カスタム ロガーを作成する

カスタム ロガーの作成については、「.NET にカスタム ログ プロバイダーを実装する」を参照してください。

その他のリソース

作成者: Kirk LarkinJuergen GutschRick Anderson

このトピックでは、ASP.NET Core アプリに用いられる .NET のログについて説明します。 .NET のログの詳細については、「.NET でのログの記録」を参照してください。 Blazor アプリでのログについて詳しくは、「ASP.NET Core Blazor のログ」をご覧ください。

サンプル コードを表示またはダウンロードします (ダウンロード方法)。

ログ プロバイダー

ログを表示する Console プロバイダーを除き、ログ プロバイダーはログを保存します。 たとえば、Azure Application Insights プロバイダーでは、Azure Application Insights にログが保存されます。 複数のプロバイダーを有効にすることができます。

既定の ASP.NET Core Web アプリ テンプレートでは:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

上記のコードは、ASP.NET Core Web アプリ テンプレートを使用して作成された Program クラスを示しています。 以降のいくつかのセクションでは、汎用ホストを使用する ASP.NET Core Web アプリ テンプレートに基づくサンプルを提供します。 ホスト コンソール以外のアプリについては、このドキュメントで後ほど説明します。

Host.CreateDefaultBuilder によって追加されたログ プロバイダーの既定のセットをオーバーライドするには、ClearProviders を呼び出し、必要なログ プロバイダーを追加します。 コード例を次に示します。

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureLogging(logging =>
        {
            logging.ClearProviders();
            logging.AddConsole();
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

その他のプロバイダーについては、以下を参照してください。

ログを作成する

ログを作成するには、依存関係の挿入 (DI) から ILogger<TCategoryName> オブジェクトを使用します。

次のような例です。

  • AboutModel 型の完全修飾名のログ "カテゴリ" を使用する、ロガー ILogger<AboutModel> を作成します。 ログのカテゴリは、各ログに関連付けられている文字列です。
  • LogInformation を呼び出して、Information レベルでログを記録します。 ログの "レベル" は、ログに記録されるイベントの重大度を示します。
public class AboutModel : PageModel
{
    private readonly ILogger _logger;

    public AboutModel(ILogger<AboutModel> logger)
    {
        _logger = logger;
    }
    public string Message { get; set; }

    public void OnGet()
    {
        Message = $"About page visited at {DateTime.UtcNow.ToLongTimeString()}";
        _logger.LogInformation(Message);
    }
}

レベルカテゴリについては、このドキュメントで後ほど詳しく説明します。

Blazor について詳しくは、「ASP.NET Core Blazor のログ」をご覧ください。

Main および Startup でログを作成に関するセクションには、MainStartup でログを作成する方法が示されています。

ログの構成

一般的に、ログの構成は appsettings.{Environment}.json ファイルの Logging セクションで指定されます。 ASP.NET Core の Web アプリ テンプレートによって、次の appsettings.Development.json ファイルが生成されます。

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

上記の JSON の場合:

  • "Default""Microsoft"、および "Microsoft.Hosting.Lifetime" の各カテゴリが指定されています。
  • "Microsoft" カテゴリは、"Microsoft" で始まるすべてのカテゴリに適用されます。 たとえば、この設定は "Microsoft.AspNetCore.Routing.EndpointMiddleware" カテゴリに適用されます。
  • "Microsoft" カテゴリでは、ログ レベルが Warning 以上のログが記録されます。
  • "Microsoft.Hosting.Lifetime" カテゴリは "Microsoft" カテゴリよりも詳細なので、"Microsoft.Hosting.Lifetime" カテゴリではログ レベルが "情報" 以上のログが記録されます。
  • 特定のログ プロバイダーが指定されていないため、LogLevel は、Windows EventLog を除くすべての有効なログ プロバイダーに適用されます。

Logging プロパティには LogLevel およびログ プロバイダーのプロパティを含めることができます。 LogLevel により、選択したカテゴリに対するログの最小レベルが指定されます。 上記の JSON では、InformationWarning のログ レベルが指定されています。 LogLevel はログの重大度を 0 - 6 の範囲で示します。

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

LogLevel を指定すると、指定したレベル以上のメッセージに対してログが有効になります。 上記の JSON では、Default カテゴリは Information 以上に対してのみログに記録されます。 たとえば、InformationWarningErrorCritical のメッセージがログに記録されます。 LogLevel が指定されていない場合、ログは既定で Information レベルになります。 詳細については、「ログ レベル」を参照してください。

プロバイダー プロパティで LogLevel プロパティを指定できます。 プロバイダーの下の LogLevel によって、そのプロバイダーのログに記録するレベルが指定され、プロバイダー以外のログ設定がオーバーライドされます。 次の appsettings.json ファイルを考えてみます。

{
  "Logging": {
    "LogLevel": { // All providers, LogLevel applies to all the enabled providers.
      "Default": "Error", // Default logging, Error and higher.
      "Microsoft": "Warning" // All Microsoft* categories, Warning and higher.
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information", // Overrides preceding LogLevel:Default setting.
        "Microsoft.Hosting": "Trace" // Debug:Microsoft.Hosting category.
      }
    },
    "EventSource": { // EventSource provider
      "LogLevel": {
        "Default": "Warning" // All categories of EventSource provider.
      }
    }
  }
}

Logging.{providername}.LogLevel の設定により Logging.LogLevel の設定がオーバーライドされます。 上記の JSON では、Debug プロバイダーの既定のログ レベルは Information に設定されています。

Logging:Debug:LogLevel:Default:Information

上記の設定により、Microsoft.Hosting 以外のすべての Logging:Debug: カテゴリに Information ログ レベルが指定されます。 特定のカテゴリが一覧表示されると、特定のカテゴリによって既定のカテゴリがオーバーライドされます。 上記の 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": { // No provider, LogLevel applies to all the enabled providers.
      "Default": "Error",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Warning"
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information" // Overrides preceding LogLevel:Default setting.
      }
    },
    "Console": {
      "IncludeScopes": true,
      "LogLevel": {
        "Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning",
        "Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug",
        "Microsoft.AspNetCore.Mvc.Razor": "Error",
        "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 のレベルがオーバーライドされます。
  • 各既定のプロバイダーの "別名" が使用されます。 各プロバイダーでは "エイリアス" が定義されます。これは構成で完全修飾型名の代わりに使用できます。 組み込みプロバイダーの別名には次のものがあります。
    • コンソール
    • デバッグ
    • EventSource
    • EventLog
    • AzureAppServicesFile
    • AzureAppServicesBlob
    • ApplicationInsights

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

ログ レベルは、いずれかの構成プロバイダーで設定できます。

: の区切り記号は、すべてのプラットフォームの環境変数階層キーには対応していません。 __(ダブルアンダースコア)は、

  • すべてのプラットフォームに対応しています。 たとえば、:: の区切り記号には対応していませんが、__ には対応しています。
  • 自動で : に置換されます。

次のコマンドは:

  • 環境キー Logging:LogLevel:Microsoft を Windows の Information の値に設定します。
  • ASP.NET Core Web アプリケーション テンプレートを使用して作成されたアプリを使用する際に、設定をテストします。 dotnet run コマンドは、set を使用した後、プロジェクト ディレクトリで実行する必要があります。
set Logging__LogLevel__Microsoft=Information
dotnet run

上記の環境設定は:

  • コマンド ウィンドウから起動されたプロセスでのみ設定可能です。
  • Visual Studio で起動されたブラウザーでは読み取れません。

次の setx コマンドは、Windows 上で環境キーと値も設定します。 set とは異なり、setx 設定は保持されます。 /M スイッチにより、システム環境で変数が設定されます。 /M が使用されていない場合には、ユーザー環境変数が設定されます。

setx Logging__LogLevel__Microsoft Information /M

次の appsettings.json ファイルを考えてみます。

"Logging": {
    "Console": {
      "LogLevel": {
        "Microsoft.Hosting.Lifetime": "Trace"
      }
    }
}

次のコマンドは、上記の構成を環境に設定するものです。

setx Logging__Console__LogLevel__Microsoft.Hosting.Lifetime Trace /M

Azure App Service の、[設定] > [構成] ページで [新しいアプリケーション設定] を選択します。 Azure App Service アプリケーションの設定は:

  • 保存時に暗号化され、暗号化されたチャネルで送信されます。
  • 環境変数として公開されます。

詳細については、「Azure アプリ: Azure Portal を使用してアプリの構成をオーバーライドする」を参照してください。

環境変数を使用して ASP.NET Core 構成値を設定する方法の詳細については、「環境変数」を参照してください。 コマンド ライン、Azure Key Vault、Azure App Configuration、その他のファイル形式など、他の構成ソースの使用の詳細については、「ASP.NET Core の構成」を参照してください。

フィルター規則を適用する方法

ILogger<TCategoryName> オブジェクトを作成すると、ILoggerFactory オブジェクトによって、そのロガーに適用するプロバイダーごとに 1 つの規則が選択されます。 ILogger インスタンスによって書き込まれるすべてのメッセージは、選択した規則に基づいてフィルター処理されます。 使用できる規則から、各プロバイダーとカテゴリのペアごとに最も明確な規則が選択されます。

特定のカテゴリに ILogger が作成されるときに、各プロバイダーに次のアルゴリズムが使用されます。

  • プロバイダーとそのエイリアスと一致するすべての規則が選択されます。 一致が見つからない場合は、空のプロバイダーですべての規則が選択されます。
  • 前の手順の結果、最も長いカテゴリのプレフィックスが一致する規則が選択されます。 一致が見つからない場合は、カテゴリを指定しないすべての規則が選択されます。
  • 複数の規則が選択されている場合は、最後の 1 つが使用されます。
  • 規則が選択されていない場合は、MinimumLevel が使用されます。

dotnet run および Visual Studio からのログ出力

既定のログ プロバイダーで作成されたログが表示されます。

  • Visual Studio 内
    • デバッグ時はデバッグ出力ウィンドウ内。
    • ASP.NET Core Web サーバー ウィンドウ内。
  • アプリが dotnet run で実行されている場合はコンソール ウィンドウ内。

"Microsoft" カテゴリから始まるログは、ASP.NET Core のフレームワークのコードからのログです。 ASP.NET Core とアプリケーション コードでは、同じログ API とログ プロバイダーが使用されます。

ログのカテゴリ

ILogger オブジェクトが作成されるときに、"カテゴリ" が指定されます。 このカテゴリは、ILogger のインスタンスによって作成される各ログ メッセージと共に含められます。 カテゴリ文字列は任意ですが、規則ではクラス名を使用します。 たとえば、コントローラーでは、名前が "TodoApi.Controllers.TodoController" になる場合があります。 ASP.NET Core Web アプリでは、ILogger<T> を使用して、カテゴリとして T の完全修飾型名を使用する ILogger インスタンスが自動的に取得されます。

public class PrivacyModel : PageModel
{
    private readonly ILogger<PrivacyModel> _logger;

    public PrivacyModel(ILogger<PrivacyModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.PrivacyModel called.");
    }
}

カテゴリを明示的に指定するには、ILoggerFactory.CreateLogger を呼び出します。

public class ContactModel : PageModel
{
    private readonly ILogger _logger;

    public ContactModel(ILoggerFactory logger)
    {
        _logger = logger.CreateLogger("TodoApi.Pages.ContactModel.MyCategory");
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.ContactModel called.");
    }

複数のメソッドで使用する場合、固定名を使用して CreateLogger を呼び出すと、イベントをカテゴリ別に分類できるので便利です。

ILogger<T> は、T の完全修飾型名を使用した CreateLogger の呼び出しと同じです。

ログ レベル

次の表に、LogLevel 値、便利な Log{LogLevel} 拡張メソッド、推奨される使用法を示します。

LogLevel [値] Method 説明
トレース 0 LogTrace 最も詳細なメッセージが含まれます。 これらのメッセージには、機密性の高いアプリ データが含まれる場合があります。 これらのメッセージは既定で無効になっているため、運用環境では有効に "しないでください"。
デバッグ 1 LogDebug デバッグと開発用。 量が多いため、運用環境では慎重に使用してください。
情報 2 LogInformation アプリの一般的なフローを追跡します。 長期的な値が含まれている可能性があります。
警告 3 LogWarning 異常なイベントや予期しないイベント用。 通常、アプリが失敗する原因にならないエラーや条件が含まれます。
エラー 4 LogError 処理できないエラーと例外の場合。 これらのメッセージは、アプリ全体のエラーではなく、現在の操作や要求における失敗を示します。
重大 5 LogCritical 即時の注意が必要なエラーの場合。 例: データ損失のシナリオ、ディスク領域不足。
None 6 ログのカテゴリにメッセージを記述しないように指定します。

前の表では、重大度が最も低い方から高い方に LogLevel が一覧表示されています。

Log メソッドの最初のパラメーター LogLevel は、ログの重大度を示します。 ほとんどの開発者は、Log(LogLevel, ...) を呼び出すのではなく、Log{LogLevel} 拡張メソッドを呼び出します。 Log{LogLevel} 拡張メソッドによって、Log メソッドが呼び出され、LogLevel が指定されます。 たとえば、次の 2 つのログ呼び出しは、機能的に同等で、同じログが生成されます。

[HttpGet]
public IActionResult Test1(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);

    _logger.Log(LogLevel.Information, MyLogEvents.TestItem, routeInfo);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    return ControllerContext.MyDisplayRouteInfo();
}

MyLogEvents.TestItem はイベント ID です。 MyLogEvents はサンプル アプリの一部であり、ログ イベント ID セクションに表示されます。

MyDisplayRouteInfo and ToCtxStringRick.Docs.Samples.RouteInfo NuGet パッケージによって提供されます。 このメソッドにより Controller および Razor Page ルート情報が表示されます。

Information および Warning ログを作成するコードを次に示します。

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

上記のコードでは、最初の Log{LogLevel} パラメーター MyLogEvents.GetItem は、ログ イベント ID です。 2 つ目のパラメーターは、他のメソッド パラメーターによって提供される引数値のプレースホルダーを含むメッセージ テンプレートです。 メソッド パラメーターについては、このドキュメントで後述するメッセージ テンプレートのセクションで説明します。

適切な Log{LogLevel} メソッドを呼び出して、特定のストレージ メディアに書き込むログ出力量を制御します。 次に例を示します。

  • 運用環境:
    • Trace または Information のレベルでログを記録すると、詳細なログ メッセージが大量に生成されます。 コストを制御し、データ ストレージの上限を超えないようにするには、Trace および Information のレベルのメッセージを、大容量の低コストのデータ ストアに記録します。 TraceInformation を特定のカテゴリに制限することを検討してください。
    • Warning から Critical のレベルでログを記録しても、ログ メッセージはほとんど生成されません。
      • 通常、コストとストレージの制限は考慮されません。
      • ログの数が少ないほど、データ ストアをより柔軟に選択できるようになります。
  • 開発中:
    • Warning に設定します。
    • トラブルシューティングの際に Trace または Information のメッセージを追加します。 出力を制限するには、調査中のカテゴリに対してのみ Trace または Information を設定します。

ASP.NET Core では、フレームワーク イベントのログが書き込まれます。 たとえば、次のログ出力について考えてみます。

  • ASP.NET Core テンプレートを使用して作成された Razor Pages アプリ
  • Logging:Console:LogLevel:Microsoft:Information に設定されているログ
  • Privacy ページへの移動。
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/2 GET https://localhost:5001/Privacy
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint '/Privacy'
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[3]
      Route matched with {page = "/Privacy"}. Executing page /Privacy
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[101]
      Executing handler method DefaultRP.Pages.PrivacyModel.OnGet - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[102]
      Executed handler method OnGet, returned result .
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[103]
      Executing an implicit handler method - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[104]
      Executed an implicit handler method, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult.
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[4]
      Executed page /Privacy in 74.5188ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint '/Privacy'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 149.3023ms 200 text/html; charset=utf-8

次の JSON では、Logging:Console:LogLevel:Microsoft:Information が設定されます。

{
  "Logging": {      // Default, all providers.
    "LogLevel": {
      "Microsoft": "Warning"
    },
    "Console": { // Console provider.
      "LogLevel": {
        "Microsoft": "Information"
      }
    }
  }
}

ログ イベント ID

各ログで "イベント ID" を指定できます。 このサンプル アプリでは、MyLogEvents クラスを使用してイベント ID を定義します。

public class MyLogEvents
{
    public const int GenerateItems = 1000;
    public const int ListItems     = 1001;
    public const int GetItem       = 1002;
    public const int InsertItem    = 1003;
    public const int UpdateItem    = 1004;
    public const int DeleteItem    = 1005;

    public const int TestItem      = 3000;

    public const int GetItemNotFound    = 4000;
    public const int UpdateItemNotFound = 4001;
}
[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

イベント ID によって一連のイベントが関連付けられます。 たとえば、ページ上に項目の一覧を表示する機能に関連するすべてのログを 1001 に設定します。

ログ プロバイダーでは、ID フィールドやログ メッセージにイベント ID が格納されたり、またはまったく格納されなかったりする場合があります。 Debug プロバイダーでイベント ID が表示されることはありません。 Console プロバイダーでは、カテゴリの後のブラケット内にイベント ID が表示されます。

info: TodoApi.Controllers.TodoItemsController[1002]
      Getting item 1
warn: TodoApi.Controllers.TodoItemsController[4000]
      Get(1) NOT FOUND

一部のログ プロバイダーでは、イベント ID がフィールドに格納されます。これにより、ID に対するフィルター処理が可能になります。

ログ メッセージ テンプレート

各ログ API では、メッセージ テンプレートが使用されます。 メッセージ テンプレートには、指定される引数のためのプレースホルダーを含めることができます。 プレースホルダーには、数値ではなく名前を使用します。

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

ログ メッセージにプレースホルダーの値を渡すために使用されるパラメーターは、プレースホルダーの名前ではなく "パラメーターの順序" によって決まります。 次のコードのメッセージ テンプレートのプレースホルダーは、パラメーター名の順番が正しくありません。

var apples = 1;
var pears = 2;
var bananas = 3;

_logger.LogInformation("Parameters: {pears}, {bananas}, {apples}", apples, pears, bananas);

しかし、プレースホルダーには、applespearsbananas という順序でパラメーターが割り当てられます。 ログ メッセージに、パラメーターの順序が反映されています。

Parameters: 1, 2, 3

この方法により、ログ プロバイダーが セマンティック ログまたは構造化ログを実装できるようになります。 書式設定されたメッセージ テンプレートだけでなく、引数自体がログ システムに渡されます。 これにより、ログ プロバイダーはフィールドとしてパラメーター値を格納することができます。 たとえば、次のロガー メソッドについて考えてみます。

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

たとえば、Azure Table Storage にログを記録する場合:

  • 各 Azure Table エンティティには、ID プロパティと RequestTime プロパティを含めることができます。
  • プロパティを持つテーブルによって、ログに記録されたデータに対するクエリが簡略化されます。 たとえば、クエリによって、特定の RequestTime の範囲内のすべてのログを検索できます。テキスト メッセージから時間を解析する必要はありません。

例外をログに記録する

ロガー メソッドには、例外パラメーターを受け取るオーバーロードがあります。

[HttpGet("{id}")]
public IActionResult TestExp(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    try
    {
        if (id == 3)
        {
            throw new Exception("Test exception");
        }
    }
    catch (Exception ex)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, ex, "TestExp({Id})", id);
        return NotFound();
    }

    return ControllerContext.MyDisplayRouteInfo();
}

MyDisplayRouteInfo and ToCtxStringRick.Docs.Samples.RouteInfo NuGet パッケージによって提供されます。 このメソッドにより Controller および Razor Page ルート情報が表示されます。

例外ログはプロバイダー固有です。

既定のログ レベル

既定のログ レベルが設定されていない場合、既定のログ レベル値は Information になります。

たとえば、次の Web アプリについて考えてみます。

  • ASP.NET Web アプリ テンプレートを使用して作成された。
  • appsettings.jsonappsettings.Development.json は削除されているか、名前が変更されている。

上記の設定で、プライバシー ページまたはホーム ページに移動すると、カテゴリ名に Microsoft が含まれる多くの TraceDebugInformation のメッセージが生成されます。

次のコードは、既定のログ レベルが構成で設定されていない場合に、既定のログ レベルを設定します。

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging => logging.SetMinimumLevel(LogLevel.Warning))
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

一般に、ログ レベルは、コードではなく構成で指定する必要があります。

フィルター関数

フィルター関数は、構成またはコードによって規則が割り当てられていないすべてのプロバイダーとカテゴリに対して呼び出されます。

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
            {
                logging.AddFilter((provider, category, logLevel) =>
                {
                    if (provider.Contains("ConsoleLoggerProvider")
                        && category.Contains("Controller")
                        && logLevel >= LogLevel.Information)
                    {
                        return true;
                    }
                    else if (provider.Contains("ConsoleLoggerProvider")
                        && category.Contains("Microsoft")
                        && logLevel >= LogLevel.Information)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                });
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

上記のコードでは、カテゴリに Controller または Microsoft が含まれ、ログ レベルが Information 以上の場合にコンソール ログが表示されます。

一般に、ログ レベルは、コードではなく構成で指定する必要があります。

ASP.NET Core と EF Core のカテゴリ

次の表に、ASP.NET Core と Entity Framework Core で使用されるいくつかのカテゴリと、ログに関するメモを示します。

カテゴリ メモ
Microsoft.AspNetCore ASP.NET Core の一般的な診断。
Microsoft.AspNetCore.DataProtection どのキーが検討、検索、および使用されたか。
Microsoft.AspNetCore.HostFiltering 許可されるホスト。
Microsoft.AspNetCore.Hosting HTTP 要求が完了するまでにかかった時間と、それらの開始時刻。 どのホスティング スタートアップ アセンブリが読み込まれたか。
Microsoft.AspNetCore.Mvc MVC と Razor の診断。 モデルの構築、フィルター処理の実行、ビューのコンパイル、アクションの選択。
Microsoft.AspNetCore.Routing 一致する情報をルーティングします。
Microsoft.AspNetCore.Server 接続の開始、停止、キープ アライブ応答。 HTTPS 証明書情報。
Microsoft.AspNetCore.StaticFiles 提供されるファイル。
Microsoft.EntityFrameworkCore Entity Framework Core の一般的な診断。 データベースのアクティビティと構成、変更の検出、移行。

コンソール ウィンドウに他のカテゴリを表示するには、appsettings.Development.json を次のように設定します。

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

ログのスコープ

"スコープ" では、論理操作のセットをグループ化できます。 このグループ化を使用して、セットの一部として作成される各ログに同じデータをアタッチすることができます。 たとえば、トランザクション処理の一部として作成されるすべてのログに、トランザクション ID を含めることができます。

スコープは:

  • BeginScope メソッドによって返される IDisposable 型です。
  • 破棄されるまで継続します。

次のプロバイダーではスコープがサポートされています。

ロガーの呼び出しを using ブロックでラップすることによって、スコープを使用します。

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    TodoItem todoItem;
    var transactionId = Guid.NewGuid().ToString();
    using (_logger.BeginScope(new List<KeyValuePair<string, object>>
        {
            new KeyValuePair<string, object>("TransactionId", transactionId),
        }))
    {
        _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

        todoItem = await _context.TodoItems.FindAsync(id);

        if (todoItem == null)
        {
            _logger.LogWarning(MyLogEvents.GetItemNotFound, 
                "Get({Id}) NOT FOUND", id);
            return NotFound();
        }
    }

    return ItemToDTO(todoItem);
}

組み込みのログ プロバイダー

ASP.NET Core には、共有フレームワークの一部として次のログ プロバイダーが含まれています。

次のログ プロバイダーは、Microsoft によって出荷されますが、共有フレームワークの一部としては提供されません。 これらは別途 NuGet としてインストールする必要があります。

ASP.NET Core には、ログをファイルに書き込むためのログ プロバイダーは含まれていません。 ASP.NET Core アプリからのログをファイルに書き込むには、サードパーティのログ プロバイダーの使用を検討してください。

ASP.NET Core モジュールのデバッグ ログおよび stdout については、「Azure App Service および IIS での ASP.NET Core のトラブルシューティング」および「IIS の ASP.NET Core モジュール (ANCM)」を参照してください。

コンソール

Console プロバイダーでは、コンソールへの出力がログに記録されます。 開発中の Console ログを表示する方法の詳細については、「dotnet run および Visual Studio からのログ出力」を参照してください。

デバッグ

Debug プロバイダーでは、System.Diagnostics.Debug クラスを使ってログ出力が書き込まれます。 Debug プロバイダーに書き込むために System.Diagnostics.Debug.WriteLine が呼び出されます。

Linux では、Debug プロバイダーのログの場所は配布によって異なり、次のいずれかになります。

  • /var/log/message
  • /var/log/syslog

イベント ソース

EventSource プロバイダーでは、Microsoft-Extensions-Logging という名前のクロスプラットフォーム イベント ソースに書き込まれます。 Windows では、プロバイダーによって ETW が使用されます。

dotnet trace ツール

dotnet-trace ツールは、実行中のプロセスの .NET Core のトレースのコレクションを有効にする、クロスプラットフォームの CLI グローバル ツールです。 このツールでは、LoggingEventSource を使用して Microsoft.Extensions.Logging.EventSource プロバイダー データを収集します。

インストール手順については、dotnet-trace に関するページを参照してください。

dotnet trace ツールを使用して、アプリからトレースを収集します。

  1. dotnet run コマンドを使用してアプリを実行します。

  2. .NET Core アプリのプロセス識別子 (PID) を決定します。

    dotnet trace ps
    

    アプリのアセンブリと同じ名前を持つプロセスの PID を検索します。

  3. dotnet trace コマンドを実行します。

    一般的なコマンド構文

    dotnet trace collect -p {PID} 
        --providers Microsoft-Extensions-Logging:{Keyword}:{Provider Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Category Level 1};
                {Logger Category 2}:{Category Level 2};
                ...
                {Logger Category N}:{Category Level N}\"
    

    PowerShell コマンド シェルを使用する場合は、--providers 値を単一引用符 (') で囲みます。

    dotnet trace collect -p {PID} 
        --providers 'Microsoft-Extensions-Logging:{Keyword}:{Provider Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Category Level 1};
                {Logger Category 2}:{Category Level 2};
                ...
                {Logger Category N}:{Category Level N}\"'
    

    Windows 以外のプラットフォームでは、-f speedscope オプションを追加して、出力トレース ファイルの形式を speedscope に変更します。

    次の表にキーワードを定義します。

    Keyword 説明
    1 LoggingEventSource に関するメタ イベントをログに記録します。 ILogger からのイベントは記録されません。
    2 ILogger.Log() が呼び出されたときに、Message イベントをオンにします。 プログラムで (書式設定されずに) 情報が提供されます。
    4 ILogger.Log() が呼び出されたときに、FormatMessage イベントをオンにします。 書式設定された文字列バージョンの情報が提供されます。
    8 ILogger.Log() が呼び出されたときに、MessageJson イベントをオンにします。 引数の JSON 表現が提供されます。

    次の表は、プロバイダー レベルの一覧です。

    プロバイダー レベル 説明
    0 LogAlways
    1 Critical
    2 Error
    3 Warning
    4 Informational
    5 Verbose

    カテゴリ レベルの解析には、文字列または数値を指定できます。

    カテゴリの名前付きの値 数値
    Trace 0
    Debug 1
    Information 2
    Warning 3
    Error 4
    Critical 5

    プロバイダー レベルとカテゴリ レベル:

    • 順序が逆になります。
    • 文字列定数は、必ずしも同一ではありません。

    FilterSpecs が指定されなかった場合、EventSourceLogger の実装は、プロバイダー レベルをカテゴリ レベルに変換し、それをすべてのカテゴリに適用することを試みます。

    プロバイダー レベル カテゴリ レベル
    Verbose(5) Debug(1)
    Informational(4) Information(2)
    Warning(3) Warning(3)
    Error(2) Error(4)
    Critical(1) Critical(5)

    FilterSpecs が指定されている場合、一覧に含まれるカテゴリには、そこでエンコードされているカテゴリ レベルが使用され、その他のカテゴリはすべてフィルターで除外されます。

    以下の例では、次のことを想定しています。

    • アプリが実行中であり、logger.LogDebug("12345") を呼び出している。
    • プロセス ID (PID) が set PID=12345 を介して設定されている。ここで、12345 は実際の PID を表します。

    次のようなコマンドについて考えてみます。

    dotnet trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:5
    

    上記のコマンドでは次のことが行われます。

    • デバッグ メッセージをキャプチャします。
    • FilterSpecs は適用されません。
    • Debug カテゴリに対応するレベル 5 を指定します。

    次のようなコマンドについて考えてみます。

    dotnet trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:5\"
    

    上記のコマンドでは次のことが行われます。

    • カテゴリ レベル 5 は Critical であるため、デバッグ メッセージはキャプチャしません。
    • FilterSpecs を指定します。

    次のコマンドでは、カテゴリ レベル 1 によって Debug が指定されているため、デバッグ メッセージがキャプチャされます。

    dotnet trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:1\"
    

    次のコマンドでは、カテゴリによって Debug が指定されているため、デバッグ メッセージがキャプチャされます。

    dotnet trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:Debug\"
    

    {Logger Category}{Category Level}FilterSpecs エントリは、追加のログ フィルター条件を表します。 FilterSpecs のエントリの区切りには、セミコロン (;) を使用します。

    Windows コマンド シェルを使用する例:

    dotnet trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:2:FilterSpecs=\"Microsoft.AspNetCore.Hosting*:4\"
    

    上記のコマンドにより次のことがアクティブになります。

    • エラー (2) に対して書式設定された文字列 (4) を生成するイベント ソース ロガー。
    • Informational ログ レベル (4) での Microsoft.AspNetCore.Hosting のログ記録。
  4. Enter キーまたは Ctrl + C キーを押すことで、dotnet trace ツールを停止します。

    トレースは、dotnet trace コマンドが実行されたフォルダーに trace.nettrace という名前で保存されます。

  5. Perfview を使用してトレースを開きます。 trace.nettrace ファイルを開き、トレース イベントを調べます。

アプリで CreateDefaultBuilder を使ってホストがビルドされない場合は、イベント ソース プロバイダーをアプリのログ構成に追加します。

詳細については次を参照してください:

Perfview

ログの収集と表示には、PerfView ユーティリティを使用します。 ETW ログを表示できる他のツールはありますが、ASP.NET Core から出力される ETW イベントを操作する場合、PerfView は最適なエクスペリエンスを提供します。

このプロバイダーでログに記録されるイベントを収集するように PerfView を構成するには、 [追加プロバイダー] の一覧に文字列 *Microsoft-Extensions-Logging を追加します 文字列の先頭にある * を忘れないでください。

Windows EventLog

EventLog プロバイダーにより、ログ出力が Windows イベント ログに送信されます。 他のプロバイダーとは異なり、EventLog プロバイダーでは既定のプロバイダー以外の設定が継承 "されません"。 EventLog ログ設定が指定されていない場合は、既定の LogLevel.Warning になります。

LogLevel.Warning より下のイベントをログに記録するには、ログ レベルを明示的に設定してください。 次の例では、イベント ログの既定のログ レベルを LogLevel.Information に設定します。

"Logging": {
  "EventLog": {
    "LogLevel": {
      "Default": "Information"
    }
  }
}

AddEventLog のオーバーロードを使用すると、EventLogSettings を渡すことができます。 null または指定しない場合は、次の既定の設定が使用されます。

  • LogName:"Application"
  • SourceName: ".NET Runtime"
  • MachineName:ローカル コンピューター名が使用されます。

次のコードでは、SourceName が既定値の ".NET Runtime" から MyLogs に変更されます。

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
            {
                logging.AddEventLog(eventLogSettings =>
                {
                    eventLogSettings.SourceName = "MyLogs"; 
                });
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

Azure App Service

Microsoft.Extensions.Logging.AzureAppServices プロバイダー パッケージは、Azure App Service アプリのファイル システムのテキスト ファイルと、Azure Storage アカウントの BLOB ストレージにログを書き込みます。

プロバイダー パッケージは、共有フレームワークに含まれていません。 プロバイダーを使用するには、プロバイダー パッケージをプロジェクトに追加します。

プロバイダーの設定を構成するには、次の例のように AzureFileLoggerOptionsAzureBlobLoggerOptions を使用します。

public class Scopes
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureLogging(logging => logging.AddAzureWebAppDiagnostics())
                .ConfigureServices(serviceCollection => serviceCollection
                    .Configure<AzureFileLoggerOptions>(options =>
                    {
                        options.FileName = "azure-diagnostics-";
                        options.FileSizeLimit = 50 * 1024;
                        options.RetainedFileCountLimit = 5;
                    })
                    .Configure<AzureBlobLoggerOptions>(options =>
                    {
                        options.BlobName = "log.txt";
                    }))
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

Azure App Service にデプロイされると、Azure portal の [App Service] ページの [App Service ログ] セクションの設定がアプリで使用されます。 次の設定が更新されると、アプリの再起動や再デプロイを必要とせずに、変更がすぐに有効になります。

  • [アプリケーション ログ (ファイル システム)]
  • [アプリケーション ログ (BLOB)]

ログ ファイルの既定の場所は、D:\home\LogFiles\Application フォルダーです。既定のファイル名は diagnostics-yyyymmdd.txt です。 既定のファイル サイズ制限は 10 MB です。保持されるファイルの既定の最大数は 2 です。 既定の BLOB 名は {app-name}{timestamp}/yyyy/mm/dd/hh/{guid}-applicationLog.txt です。

このプロバイダーは、プロジェクトが Azure 環境で実行される場合にのみログを記録します。

Azure ログのストリーミング

Azure ログのストリーミングでは、以下からのリアル タイムでのログ アクティビティの表示がサポートされています。

  • アプリ サーバー
  • Web サーバー
  • 失敗した要求のトレース

Azure ログのストリーミングを構成するには

  • アプリのポータル ページから [App Service ログ] ページに移動します。
  • [アプリケーション ログ (ファイル システム)][オン] に設定します。
  • ログ [レベル] を選択します。 この設定は、Azure ログ ストリーミングにのみ適用されます。

[ログ ストリーム] ページに移動して、ログを表示します。 ログに記録されたメッセージは、ILogger インターフェイスを使用してログに記録されます。

Azure Application Insights

Microsoft.Extensions.Logging.ApplicationInsights プロバイダー パッケージでは、Azure Application Insights にログが書き込まれます。 Application Insights は、Web アプリを監視するサービスであり、クエリを実行してテレメトリ データを分析するためのツールを提供します。 このプロバイダーを使用する場合は、Application Insights ツールを使ってクエリを実行し、ログを分析できます。

ログ プロバイダーは、Microsoft.ApplicationInsights.AspNetCore の依存関係として組み込まれており、ASP.NET Core で利用可能なすべてのテレメトリを提供するパッケージです。 このパッケージを使用する場合は、プロバイダー パッケージをインストールする必要はありません。

Microsoft.ApplicationInsights.Web パッケージは、ASP.NET Core ではなく、ASP.NET 4.x 用です。

詳細については、次のリソースを参照してください。

サードパーティ製のログ プロバイダー

ASP.NET Core で使用できるサードパーティ製のログ記録フレームワークをいくつか紹介します。

一部のサードパーティ製フレームワークは、セマンティック ログ記録 (構造化ログ記録とも呼ばれます) を実行できます。

サード パーティ製フレームワークを使用することは、組み込みのプロバイダーのいずれかを使用することと似ています。

  1. プロジェクトに NuGet パッケージを追加します。
  2. ログ記録フレームワークによって提供される ILoggerFactory 拡張メソッドを呼び出します。

詳細については、各プロバイダーのドキュメントをご覧ください。 サード パーティ製のログ プロバイダーは、Microsoft ではサポートされていません。

ホスト コンソール以外のアプリ

非 Web コンソール アプリで汎用ホストを使用する方法の例については、バックグラウンド タスクのサンプル アプリ (ASP.NET Core でホステッド サービスを使用するバックグラウンド タスク) の Program.cs ファイルを参照してください。

汎用ホストを使用しないアプリのログ記録コードは、プロバイダーの追加方法とロガーの作成方法によって異なります。

ログ プロバイダー

ホスト コンソール以外のアプリでは、LoggerFactory を作成するときにプロバイダーの Add{provider name} 拡張メソッドを呼び出します。

class Program
{
    static void Main(string[] args)
    {
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder
                .AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
                .AddConsole()
                .AddEventLog();
        });
        ILogger logger = loggerFactory.CreateLogger<Program>();
        logger.LogInformation("Example log message");
    }
}

ログを作成する

ログを作成するには、ILogger<TCategoryName> オブジェクトを使用します。 ILogger を作成するには、LoggerFactory を使用します。

次の例では、カテゴリが LoggingConsoleApp.Program のロガーを作成します。

class Program
{
    static void Main(string[] args)
    {
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder
                .AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
                .AddConsole()
                .AddEventLog();
        });
        ILogger logger = loggerFactory.CreateLogger<Program>();
        logger.LogInformation("Example log message");
    }
}

次の例では、ロガーを使用して、レベルが Information のログを作成します。 ログの "レベル" は、ログに記録されるイベントの重大度を示します。

class Program
{
    static void Main(string[] args)
    {
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder
                .AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
                .AddConsole()
                .AddEventLog();
        });
        ILogger logger = loggerFactory.CreateLogger<Program>();
        logger.LogInformation("Example log message");
    }
}

レベルカテゴリについては、このドキュメントで詳しく説明しています。

ホストの構築時のログ記録

ホストの構築時のログ記録は、直接サポートされていません。 ただし、別のロガーを使用することができます。 次の例では、CreateHostBuilder でログを記録するために、Serilog ロガーが使用されています。 AddSerilog では、Log.Logger で指定された静的な構成が使用されます。

using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var builtConfig = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .AddCommandLine(args)
            .Build();

        Log.Logger = new LoggerConfiguration()
            .WriteTo.Console()
            .WriteTo.File(builtConfig["Logging:FilePath"])
            .CreateLogger();

        try
        {
            return Host.CreateDefaultBuilder(args)
                .ConfigureServices((context, services) =>
                {
                    services.AddRazorPages();
                })
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.AddConfiguration(builtConfig);
                })
                .ConfigureLogging(logging =>
                {   
                    logging.AddSerilog();
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Host builder error");

            throw;
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }
}

ILogger に依存するサービスを構成する

ASP.NET Core の以前のバージョンでは Web ホスト用に別の DI コンテナーが作成されるため、ロガーの Startup へのコンストラクター挿入が機能します。 汎用ホストに対して 1 つのコンテナーのみが作成される理由については、破壊的変更に関するお知らせに関する記事を参照してください。

ILogger<T> に依存するサービスを構成するには、コンストラクターの挿入を使用するか、ファクトリ メソッドを指定します。 ファクトリ メソッドの方法は、他の選択肢がない場合にのみお勧めします。 たとえば、DI によって提供される ILogger<T> インスタンスを必要とするサービスについて考えてみます。

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddRazorPages();

    services.AddSingleton<IMyService>((container) =>
    {
        var logger = container.GetRequiredService<ILogger<MyService>>();
        return new MyService() { Logger = logger };
    });
}

前の強調表示されているコードは、DI コンテナーで MyService のインスタンスが初めて作成されるときに実行される Func<T,TResult> です。 この方法では、任意の登録済みサービスにアクセスできます。

Main でログを作成する

次のコードでは、ホストを構築した後に DI から ILogger インスタンスを取得することによって Main でログを記録します。

public static void Main(string[] args)
{
    var host = CreateHostBuilder(args).Build();

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

    host.Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Startup でログを作成する

次のコードは、Startup.Configure にログを書き込みます。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env,
                      ILogger<Startup> logger)
{
    if (env.IsDevelopment())
    {
        logger.LogInformation("In Development.");
        app.UseDeveloperExceptionPage();
    }
    else
    {
        logger.LogInformation("Not Development.");
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapRazorPages();
    });
}

Startup.ConfigureServices メソッドでの DI コンテナーの設定が完了する前にログを書き込むことはサポートされていません。

  • Startup コンストラクターへのロガーの挿入はサポートされていません。
  • Startup.ConfigureServices メソッド シグネチャへのロガーの挿入はサポートされていません

この制限の理由は、ログ記録は DI と構成に依存しており、さらに構成は DI に依存しているためです。 DI コンテナーは、ConfigureServices が完了するまで設定されません。

ILogger<T> に依存するサービスの構成、または Startup へのロガーのコンストラクター挿入が以前のバージョンで機能した理由については、ILogger に依存するサービスの構成に関するページを参照してください。

非同期でないロガー メソッド

ログ記録は高速に実行され、非同期コードのパフォーマンス コストを下回る必要があります。 ログ データ ストアが低速の場合は、そこへ直接書き込まないでください。 まずログ メッセージを高速なストアに書き込んでから、後で低速なストアに移動することを検討してください。 たとえば、SQL Server にログを記録する場合、Log メソッドは同期しているため、Log メソッドで直接それを行わないでください。 代わりに、ログ メッセージをインメモリ キューに同期的に追加し、バックグラウンド ワーカーにキューからメッセージをプルさせて、SQL Server にデータをプッシュする非同期処理を実行させます。 詳細については、この GitHub の問題を参照してください。

実行中のアプリのログ レベルを変更する

ログ API には、アプリの実行中にログ レベルを変更するシナリオは含まれていません。 ただし、一部の構成プロバイダーは構成を再読み込みすることができ、ログ構成に直ちに影響します。 たとえば、ファイル構成プロバイダーでは、既定でログ構成が再度読み込まれます。 アプリの実行中にコードの構成が変更された場合、アプリは IConfigurationRoot.Reload を呼び出して、アプリのログ構成を更新できます。

ILogger と ILoggerFactory

ILogger<TCategoryName>ILoggerFactory のインターフェイスと実装は .NET Core SDK に含まれています。 これらは、次の NuGet パッケージでも入手できます。

コードでログ フィルター規則を適用する

ログ フィルター規則を設定するには、構成を使用することをお勧めします。

コードにフィルター規則を登録する方法を次の例に示します。

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
               logging.AddFilter("System", LogLevel.Debug)
                  .AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information)
                  .AddFilter<ConsoleLoggerProvider>("Microsoft", LogLevel.Trace))
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

logging.AddFilter("System", LogLevel.Debug)System カテゴリとログ レベル Debug を指定します。 特定のプロバイダーが構成されていないため、フィルターはすべてのプロバイダーに適用されます。

AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information) は以下を指定します。

  • Debug ログ プロバイダー。
  • ログ レベル Information 以上。
  • "Microsoft" で始まるすべてのカテゴリ。

SpanId、TraceId、ParentId を使用してスコープを自動的にログする

ログ ライブラリでは、SpanIdTraceIdParentId を使用してスコープ オブジェクトが暗黙的に作成されます。 この動作は、ActivityTrackingOptions を使用して構成されます。

  var loggerFactory = LoggerFactory.Create(logging =>
  {
      logging.Configure(options =>
      {
          options.ActivityTrackingOptions = ActivityTrackingOptions.SpanId
                                              | ActivityTrackingOptions.TraceId
                                              | ActivityTrackingOptions.ParentId;
      }).AddSimpleConsole(options =>
      {
          options.IncludeScopes = true;
      });
  });

traceparent HTTP 要求ヘッダーが設定されている場合、ログ スコープの ParentId にインバウンド traceparent ヘッダーからの W3C parent-id が、また、ログ スコープの SpanId に、次のアウトバウンド ステップまたはアウトバウンド スパン用に更新された parent-id が示されます。 詳細については、「traceparent フィールドの変更」を参照してください。

カスタム ロガーを作成する

カスタム ロガーの作成については、「.NET にカスタム ログ プロバイダーを実装する」を参照してください。

その他のリソース