ASP.NET Core Blazor のログ
注意
これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
警告
このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、「.NET および .NET Core サポート ポリシー」を参照してください。 現在のリリースについては、この記事の .NET 8 バージョンを参照してください。
重要
この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。
現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
この記事では、構成や Razor コンポーネントからログ メッセージを書き込む方法など、Blazor アプリのログについて説明します。
構成
ログの構成は、アプリの設定ファイルから読み込むことができます。 詳しくは、「ASP.NET Core Blazor の構成」をご覧ください。
既定のログ レベルで、追加のログ プロバイダーを構成しない場合:
- サーバーでは、LogLevel.Information レベル以上の
Development
環境のサーバー側 .NET コンソールに対してのみ、アプリによってログが記録されます。 - クライアントでは、LogLevel.Information レベル以上のクライアント側ブラウザー開発者ツール コンソールに対してのみ、アプリによってログが記録されます。
プロジェクト ファイルで暗黙の名前空間 (<ImplicitUsings>enable</ImplicitUsings>
) を使うようにアプリが構成されている場合、API Visual Studio IntelliSense の補完またはアプリのビルドをサポートするために Microsoft.Extensions.Logging または LoggerExtensions クラス内の任意の API の using
ディレクティブは必要ありません。 暗黙的な名前空間が有効ではない場合、_Imports.razor
ファイル経由でインポートされていないログの名前空間に対して、Razor コンポーネントで @using
ディレクティブを明示的に定義する必要があります。
ログ レベル
ログ レベルは ASP.NET Core アプリのログ レベル (API ドキュメントの LogLevel に掲載) に準拠しています。
Razor コンポーネントのログ
LogWarning や LogError など、API の IntelliSense 入力候補をサポートするには、Microsoft.Extensions.Logging の using
ディレクティブが必要です。
次のような例です。
- ILogger (
ILogger<Counter1>
) オブジェクトを挿入して、ロガーを作成します。 ログの "カテゴリ" は、コンポーネントの種類Counter
の完全修飾名です。 - LogWarning を呼び出して、Warning レベルでログを記録します。
Counter1.razor
:
@page "/counter-1"
@inject ILogger<Counter1> Logger
<PageTitle>Counter 1</PageTitle>
<h1>Counter 1</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
Logger.LogWarning("Someone has clicked me!");
currentCount++;
}
}
@page "/counter-1"
@inject ILogger<Counter1> Logger
<PageTitle>Counter 1</PageTitle>
<h1>Counter 1</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
Logger.LogWarning("Someone has clicked me!");
currentCount++;
}
}
@page "/counter-1"
@inject ILogger<Counter1> Logger
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
Logger.LogWarning("Someone has clicked me!");
currentCount++;
}
}
@page "/counter-1"
@inject ILogger<Counter1> Logger
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
Logger.LogWarning("Someone has clicked me!");
currentCount++;
}
}
@page "/counter-1"
@using Microsoft.Extensions.Logging
@inject ILogger<Counter1> Logger
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
Logger.LogWarning("Someone has clicked me!");
currentCount++;
}
}
@page "/counter-1"
@using Microsoft.Extensions.Logging
@inject ILogger<Counter1> Logger
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
Logger.LogWarning("Someone has clicked me!");
currentCount++;
}
}
次の例は、コンポーネントで ILoggerFactory を使用したログを示しています。
Counter2.razor
:
@page "/counter-2"
@inject ILoggerFactory LoggerFactory
<PageTitle>Counter 2</PageTitle>
<h1>Counter 2</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
var logger = LoggerFactory.CreateLogger<Counter2>();
logger.LogWarning("Someone has clicked me!");
currentCount++;
}
}
@page "/counter-2"
@inject ILoggerFactory LoggerFactory
<PageTitle>Counter 2</PageTitle>
<h1>Counter 2</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
var logger = LoggerFactory.CreateLogger<Counter2>();
logger.LogWarning("Someone has clicked me!");
currentCount++;
}
}
@page "/counter-2"
@inject ILoggerFactory LoggerFactory
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
var logger = LoggerFactory.CreateLogger<Counter2>();
logger.LogWarning("Someone has clicked me!");
currentCount++;
}
}
@page "/counter-2"
@inject ILoggerFactory LoggerFactory
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
var logger = LoggerFactory.CreateLogger<Counter2>();
logger.LogWarning("Someone has clicked me!");
currentCount++;
}
}
@page "/counter-2"
@using Microsoft.Extensions.Logging
@inject ILoggerFactory LoggerFactory
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
var logger = LoggerFactory.CreateLogger<Counter2>();
logger.LogWarning("Someone has clicked me!");
currentCount++;
}
}
@page "/counter-2"
@using Microsoft.Extensions.Logging
@inject ILoggerFactory LoggerFactory
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
var logger = LoggerFactory.CreateLogger<Counter2>();
logger.LogWarning("Someone has clicked me!");
currentCount++;
}
}
サーバー側のログ
ASP.NET Core ログの全般的なガイダンスについては、「.NET Core および ASP.NET Core でのログ記録」を参照してください。
クライアント側のログ
ASP.NET Core ログのすべての機能がクライアント側でサポートされているわけではありません。 たとえば、クライアント側コンポーネントにはクライアントのファイル システムまたはネットワークへのアクセス権がないため、クライアントの物理またはネットワークの記憶域にログを書き込むことはできません。 シングルページ アプリ (SPA) と連携するように設計されたサードパーティ製のログ サービスを使用する場合は、サービスのセキュリティ ガイダンスに従ってください。 クライアント側に保存されているキーやシークレットを含むすべてのデータは安全ではなく、悪意のあるユーザーによって簡単に発見される可能性があることに留意してください。
フレームワークのバージョンとログ機能によっては、ログの実装で Microsoft.Extensions.Logging の名前空間を Program
ファイルに追加する必要があることがあります。
using Microsoft.Extensions.Logging;
WebAssemblyHostBuilder.Logging プロパティを使用して、クライアント側アプリでのログを構成します。 Logging プロパティは ILoggingBuilder 型なので、ILoggingBuilder の拡張メソッドがサポートされます。
最小ログ レベルを設定するには、Program
ファイルのホスト ビルダーで、LogLevel を使用して LoggingBuilderExtensions.SetMinimumLevel を呼び出します。 次の例では、最小ログレベルを Warning に設定しています。
builder.Logging.SetMinimumLevel(LogLevel.Warning);
クライアント側 Program
ファイルのログ
ログは、クライアント側アプリで、フレームワークの内部コンソール ロガー プロバイダー (WebAssemblyConsoleLoggerProvider
(参照ソース)) を使って WebAssemblyHostBuilder がビルドされた後にサポートされます。
Program
ファイルで次の操作を行います。
var host = builder.Build();
var logger = host.Services.GetRequiredService<ILoggerFactory>()
.CreateLogger<Program>();
logger.LogInformation("Logged after the app is built in the Program file.");
await host.RunAsync();
開発者ツール コンソールの出力:
info: Program[0]
Logged after the app is built in the Program file.
Note
通常、.NET 参照ソースへのドキュメント リンクを使用すると、リポジトリの既定のブランチが読み込まれます。このブランチは、.NET の次回リリースに向けて行われている現在の開発を表します。 特定のリリースのタグを選択するには、[Switch branches or tags](ブランチまたはタグの切り替え) ドロップダウン リストを使います。 詳細については、「ASP.NET Core ソース コードのバージョン タグを選択する方法」 (dotnet/AspNetCore.Docs #26205) を参照してください。
クライアント側のログ カテゴリ
ログ カテゴリがサポートされています。
次の例は、Blazor プロジェクト テンプレートから作成されたアプリの Counter
コンポーネントでログ カテゴリを使う方法を示しています。
ILoggerFactory を LoggerFactory
として挿入するアプリの Counter
コンポーネント (Counter.razor
) の IncrementCount
メソッド:
var logger = LoggerFactory.CreateLogger("CustomCategory");
logger.LogWarning("Someone has clicked me!");
開発者ツール コンソールの出力:
warn: CustomCategory[0]
Someone has clicked me!
クライアント側のログ イベント ID
ログ イベント ID がサポートされています。
次の例は、Blazor プロジェクト テンプレートから作成されたアプリの Counter
コンポーネントでログ イベント ID を使う方法を示しています。
LogEvent.cs
:
public class LogEvent
{
public const int Event1 = 1000;
public const int Event2 = 1001;
}
アプリの Counter
コンポーネント (Counter.razor
) の IncrementCount
メソッド:
logger.LogInformation(LogEvent.Event1, "Someone has clicked me!");
logger.LogWarning(LogEvent.Event2, "Someone has clicked me!");
開発者ツール コンソールの出力:
info: BlazorSample.Pages.Counter[1000]
Someone has clicked me!
warn: BlazorSample.Pages.Counter[1001]
Someone has clicked me!
クライアント側のログ メッセージ テンプレート
ログ メッセージ テンプレートがサポートされています。
次の例は、Blazor プロジェクト テンプレートから作成されたアプリの Counter
コンポーネントでログ メッセージ テンプレートを使う方法を示しています。
アプリの Counter
コンポーネント (Counter.razor
) の IncrementCount
メソッド:
logger.LogInformation("Someone clicked me at {CurrentDT}!", DateTime.UtcNow);
開発者ツール コンソールの出力:
info: BlazorSample.Pages.Counter[0]
Someone clicked me at 04/21/2022 12:15:57!
クライアント側のログ例外パラメータ
ログ例外パラメータがサポートされています。
次の例は、Blazor プロジェクト テンプレートから作成されたアプリの Counter
コンポーネントでログ例外パラメーターを使う方法を示しています。
アプリの Counter
コンポーネント (Counter.razor
) の IncrementCount
メソッド:
currentCount++;
try
{
if (currentCount == 3)
{
currentCount = 4;
throw new OperationCanceledException("Skip 3");
}
}
catch (Exception ex)
{
logger.LogWarning(ex, "Exception (currentCount: {Count})!", currentCount);
}
開発者ツール コンソールの出力:
warn: BlazorSample.Pages.Counter[0]
Exception (currentCount: 4)!
System.OperationCanceledException: Skip 3
at BlazorSample.Pages.Counter.IncrementCount() in C:UsersAlabaDesktopBlazorSamplePagesCounter.razor:line 28
クライアント側のフィルター関数
フィルター関数がサポートされています。
次の例は、Blazor プロジェクト テンプレートから作成されたアプリの Counter
コンポーネントでフィルターを使う方法を示しています。
Program
ファイルで次の操作を行います。
builder.Logging.AddFilter((provider, category, logLevel) =>
category.Equals("CustomCategory2") && logLevel == LogLevel.Information);
ILoggerFactory を LoggerFactory
として挿入するアプリの Counter
コンポーネント (Counter.razor
) の IncrementCount
メソッド:
var logger1 = LoggerFactory.CreateLogger("CustomCategory1");
logger1.LogInformation("Someone has clicked me!");
var logger2 = LoggerFactory.CreateLogger("CustomCategory1");
logger2.LogWarning("Someone has clicked me!");
var logger3 = LoggerFactory.CreateLogger("CustomCategory2");
logger3.LogInformation("Someone has clicked me!");
var logger4 = LoggerFactory.CreateLogger("CustomCategory2");
logger4.LogWarning("Someone has clicked me!");
この開発者ツール コンソールの出力では、フィルターは CustomCategory2
カテゴリと Information ログ レベル メッセージのログのみを許可しています。
info: CustomCategory2[0]
Someone has clicked me!
アプリで、特定の名前空間のログ フィルターを構成することもできます。 たとえば、Program
ファイルでログ レベルを Trace に設定します。
builder.Logging.SetMinimumLevel(LogLevel.Trace);
通常、Trace ログ レベルでは、開発者ツール コンソールの出力を詳細レベルにした場合、次のような Microsoft.AspNetCore.Components.RenderTree ログ メッセージが含まれます。
dbug: Microsoft.AspNetCore.Components.RenderTree.Renderer[3]
Rendering component 14 of type Microsoft.AspNetCore.Components.Web.HeadOutlet
Program
ファイルで Microsoft.AspNetCore.Components.RenderTree に固有のログ メッセージを無効にするには、次の方法のいずれかを使います。
-
builder.Logging.AddFilter("Microsoft.AspNetCore.Components.RenderTree.*", LogLevel.None);
-
builder.Services.PostConfigure<LoggerFilterOptions>(options => options.Rules.Add( new LoggerFilterRule(null, "Microsoft.AspNetCore.Components.RenderTree.*", LogLevel.None, null) ));
前述のフィルターのいずれかをアプリに追加した後、詳細レベルのコンソール出力に Microsoft.AspNetCore.Components.RenderTree API からのログ メッセージが表示されなくなります。
クライアント側のカスタム ロガー プロバイダー
このセクションの例では、さらに詳細にカスタマイズするための、カスタム ロガー プロバイダーを紹介します。
Microsoft.Extensions.Logging.Configuration
パッケージのアプリへのパッケージ参照を追加します。
Note
.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。
次のカスタム ロガー構成を追加します。 この構成により、Information、Warning、Error の 3 つのログ レベルのカスタム ログ形式を設定する LogLevels
辞書が確立されます。 LogFormat
enum
は、短い (LogFormat.Short
) 形式と長い (LogFormat.Long
) 形式を表すために使用されます。
CustomLoggerConfiguration.cs
:
using Microsoft.Extensions.Logging;
public class CustomLoggerConfiguration
{
public int EventId { get; set; }
public Dictionary<LogLevel, LogFormat> LogLevels { get; set; } =
new()
{
[LogLevel.Information] = LogFormat.Short,
[LogLevel.Warning] = LogFormat.Short,
[LogLevel.Error] = LogFormat.Long
};
public enum LogFormat
{
Short,
Long
}
}
次のカスタム ロガーをアプリに追加します。 CustomLogger
は、前の CustomLoggerConfiguration
の構成で定義された値 logLevel
に基づいてカスタム ログ形式を出力します。
using Microsoft.Extensions.Logging;
using static CustomLoggerConfiguration;
public sealed class CustomLogger : ILogger
{
private readonly string name;
private readonly Func<CustomLoggerConfiguration> getCurrentConfig;
public CustomLogger(
string name,
Func<CustomLoggerConfiguration> getCurrentConfig) =>
(this.name, this.getCurrentConfig) = (name, getCurrentConfig);
public IDisposable BeginScope<TState>(TState state) => default!;
public bool IsEnabled(LogLevel logLevel) =>
getCurrentConfig().LogLevels.ContainsKey(logLevel);
public void Log<TState>(
LogLevel logLevel,
EventId eventId,
TState state,
Exception? exception,
Func<TState, Exception?, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}
CustomLoggerConfiguration config = getCurrentConfig();
if (config.EventId == 0 || config.EventId == eventId.Id)
{
switch (config.LogLevels[logLevel])
{
case LogFormat.Short:
Console.WriteLine($"{name}: {formatter(state, exception)}");
break;
case LogFormat.Long:
Console.WriteLine($"[{eventId.Id, 2}: {logLevel, -12}] {name} - {formatter(state, exception)}");
break;
default:
// No-op
break;
}
}
}
}
次のカスタム ロガー プロバイダーをアプリに追加します。 CustomLoggerProvider
は、組み込みのログ構成機能を使用してロガーを構成する Options
ベースのアプローチを採用しています。 たとえば、アプリは、このセクションの最後に示すように、カスタム ロガーへのコードを変更することなく、appsettings.json
ファイルを使用してログ形式を設定または変更できます。
CustomLoggerProvider.cs
:
using System.Collections.Concurrent;
using Microsoft.Extensions.Options;
[ProviderAlias("CustomLog")]
public sealed class CustomLoggerProvider : ILoggerProvider
{
private readonly IDisposable onChangeToken;
private CustomLoggerConfiguration config;
private readonly ConcurrentDictionary<string, CustomLogger> loggers =
new(StringComparer.OrdinalIgnoreCase);
public CustomLoggerProvider(
IOptionsMonitor<CustomLoggerConfiguration> config)
{
this.config = config.CurrentValue;
onChangeToken = config.OnChange(updatedConfig => this.config = updatedConfig);
}
public ILogger CreateLogger(string categoryName) =>
loggers.GetOrAdd(categoryName, name => new CustomLogger(name, GetCurrentConfig));
private CustomLoggerConfiguration GetCurrentConfig() => config;
public void Dispose()
{
loggers.Clear();
onChangeToken.Dispose();
}
}
次のカスタム ロガー拡張機能をアプリに追加します。
CustomLoggerExtensions.cs
:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Configuration;
public static class CustomLoggerExtensions
{
public static ILoggingBuilder AddCustomLogger(
this ILoggingBuilder builder)
{
builder.AddConfiguration();
builder.Services.TryAddEnumerable(
ServiceDescriptor.Singleton<ILoggerProvider, CustomLoggerProvider>());
LoggerProviderOptions.RegisterProviderOptions
<CustomLoggerConfiguration, CustomLoggerProvider>(builder.Services);
return builder;
}
}
ホスト ビルダーの Program
ファイルで、ClearProviders を呼び出して既存のプロバイダーをクリアし、カスタム ログ プロバイダーを追加します。
builder.Logging.ClearProviders().AddCustomLogger();
次の CustomLoggerExample
コンポーネントでは、以下のことを行います。
- デバッグ メッセージはログされません。
- 情報メッセージは、短い形式 (
LogFormat.Short
) でログされます。 - 警告メッセージは、短い形式 (
LogFormat.Short
) でログされます。 - エラー メッセージは、長い形式 (
LogFormat.Long
) でログされます。 - トレースメッセージはログされません。
CustomLoggerExample.razor
:
@page "/custom-logger-example"
@inject ILogger<CustomLoggerExample> Logger
<p>
<button @onclick="LogMessages">Log Messages</button>
</p>
@code{
private void LogMessages()
{
Logger.LogDebug(1, "This is a debug message.");
Logger.LogInformation(3, "This is an information message.");
Logger.LogWarning(5, "This is a warning message.");
Logger.LogError(7, "This is an error message.");
Logger.LogTrace(5!, "This is a trace message.");
}
}
@page "/custom-logger-example"
@using Microsoft.Extensions.Logging
@inject ILogger<CustomLoggerExample> Logger
<p>
<button @onclick="LogMessages">Log Messages</button>
</p>
@code{
private void LogMessages()
{
Logger.LogDebug(1, "This is a debug message.");
Logger.LogInformation(3, "This is an information message.");
Logger.LogWarning(5, "This is a warning message.");
Logger.LogError(7, "This is an error message.");
Logger.LogTrace(5!, "This is a trace message.");
}
}
Log Messages
ボタンが選択されると、ブラウザーの開発者ツールコンソールに次の出力が表示されます。 ログ エントリには、カスタム ロガーによって適用される適切な形式が反映されます (クライアント アプリの名前は LoggingTest
)。
LoggingTest.Pages.CustomLoggerExample: This is an information message.
LoggingTest.Pages.CustomLoggerExample: This is a warning message.
[ 7: Error ] LoggingTest.Pages.CustomLoggerExample - This is an error message.
前の例を簡単に確認すると、CustomLoggerConfiguration
の辞書を使用してログ行の形式を設定することは、厳密には必要ないことが明らかです。 カスタム ロガー (CustomLogger
) によって適用された行形式は、logLevel
を Log
メソッドで確認するだけで適用できた可能性があります。 構成を使用してログ形式を割り当てる目的は、次の例に示すように、開発者がアプリ構成を使用してログ形式を簡単に変更できることです。
クライアント側アプリで、、ログ構成を含むように appsettings.json
ファイルを追加または更新します。 次の 3 つのログ レベルのすべてについて、ログの形式を Long
に設定します。
{
"Logging": {
"CustomLog": {
"LogLevels": {
"Information": "Long",
"Warning": "Long",
"Error": "Long"
}
}
}
}
前の例では、カスタム ロガー構成のエントリが CustomLog
であることに注目してください。これは、カスタム ロガー プロバイダー (CustomLoggerProvider
) に [ProviderAlias("CustomLog")]
の別名として適用されました。 ログの構成は、名前 CustomLog
ではなく CustomLoggerProvider
を使用して適用することができましたが、別名 CustomLog
を使用する方がよりユーザー フレンドリです。
Program
ファイルで、ログ構成を使用します。 次のコードを追加します。
builder.Logging.AddConfiguration(
builder.Configuration.GetSection("Logging"));
LoggingBuilderConfigurationExtensions.AddConfiguration の呼び出しは、カスタム ロガー プロバイダーを追加する前または後に配置できます。
再度アプリを実行します。 Log Messages
ボタンを選択します。 ログの構成が appsettings.json
ファイルから適用されていることに注目してください。 3 つすべてのログ エントリは、長い (LogFormat.Long
) 形式です (クライアント アプリの名前は LoggingTest
)。
[ 3: Information ] LoggingTest.Pages.CustomLoggerExample - This is an information message.
[ 5: Warning ] LoggingTest.Pages.CustomLoggerExample - This is a warning message.
[ 7: Error ] LoggingTest.Pages.CustomLoggerExample - This is an error message.
クライアント側のログ スコープ
開発者ツール コンソール ロガーは、ログ スコープをサポートしていません。 しかし、カスタム ロガーはログ スコープをサポートすることができます。 ニーズに合わせてさらに開発できるサポートされていない例については、Blazor サンプル GitHub リポジトリ の BlazorWebAssemblyScopesLogger
サンプル アプリを参照してください (ダウンロード方法)。
サンプル アプリでは、標準の ASP.NET Core BeginScope ログ構文を使用して、ログに記録されたメッセージのスコープを示します。 次の例の Logger
サービスは、アプリの CustomLoggerExample
コンポーネント (CustomLoggerExample.razor
) に挿入される ILogger<CustomLoggerExample>
です。
using (Logger.BeginScope("L1"))
{
Logger.LogInformation(3, "INFO: ONE scope.");
}
using (Logger.BeginScope("L1"))
{
using (Logger.BeginScope("L2"))
{
Logger.LogInformation(3, "INFO: TWO scopes.");
}
}
using (Logger.BeginScope("L1"))
{
using (Logger.BeginScope("L2"))
{
using (Logger.BeginScope("L3"))
{
Logger.LogInformation(3, "INFO: THREE scopes.");
}
}
}
Output:
[ 3: Information ] {CLASS} - INFO: ONE scope. => L1 blazor.webassembly.js:1:35542
[ 3: Information ] {CLASS} - INFO: TWO scopes. => L1 => L2 blazor.webassembly.js:1:35542
[ 3: Information ] {CLASS} - INFO: THREE scopes. => L1 => L2 => L3
前の例の {CLASS}
プレースホルダーは BlazorWebAssemblyScopesLogger.Pages.CustomLoggerExample
です。
プリレンダリングされたコンポーネントのログ
プリレンダリングされたコンポーネントは、コンポーネント初期化コードを 2 回実行します。 ログ記録は、初期化コードの最初の実行時にはサーバー側で、初期化コードの 2 回目の実行時にはクライアント側で行われます。 初期化時のログ記録の目的に応じて、サーバー側、クライアント側、またはその両方でログをチェックします。
SignalR クライアント ビルダーを使用した SignalR クライアントのログ
このセクションは、サーバー側アプリに適用されます。
Blazor スクリプトの開始構成で、ログ レベルを指定して configureLogging
を呼び出す configureSignalR
構成オブジェクトを渡します。
configureLogging
のログ レベル値には、次の表に示す文字列または整数のログ レベルとして引数を渡します。
LogLevel | 文字列の設定 | 整数の設定 |
---|---|---|
Trace | trace |
0 |
Debug | debug |
1 |
Information | information |
2 |
Warning | warning |
3 |
Error | error |
4 |
Critical | critical |
5 |
None | none |
6 |
例 1: 文字列値を使用して Information ログ レベルを設定する。
Blazor Web App:
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
Blazor.start({
circuit: {
configureSignalR: function (builder) {
builder.configureLogging("information");
}
}
});
</script>
Blazor Server:
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
Blazor.start({
configureSignalR: function (builder) {
builder.configureLogging("information");
}
});
</script>
前の例の {BLAZOR SCRIPT}
プレースホルダーは、Blazor スクリプトのパスとファイル名です。 スクリプトの場所については、「ASP.NET Core Blazor プロジェクトの構造」を参照してください。
例 2: 整数値を使用して Information ログ レベルを設定する。
Blazor Web App:
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
Blazor.start({
circuit: {
configureSignalR: function (builder) {
builder.configureLogging(2); // LogLevel.Information
}
}
});
</script>
Blazor Server:
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
Blazor.start({
configureSignalR: function (builder) {
builder.configureLogging(2); // LogLevel.Information
}
});
</script>
前の例の {BLAZOR SCRIPT}
プレースホルダーは、Blazor スクリプトのパスとファイル名です。 スクリプトの場所については、「ASP.NET Core Blazor プロジェクトの構造」を参照してください。
Note
例 2 のように整数を使ってログ レベルを指定することは ("マジック ナンバー" または "マジック定数" と呼ばれることがよくあります)、ソース コードを見たときに整数が示すログ レベルがはっきりわからないため、不適切なコーディング手法と考えられます。 ブラウザーに転送されるバイト数を最小限に抑えることが優先される場合は、整数を使うのが理にかなっている可能性があります (このような場合はコメントの削除を検討してください)。
Blazor の起動 (Blazor.start()
) の詳細については、「ASP.NET Core Blazor の起動」をご覧ください。
アプリ構成を使用しした SignalR クライアントのログ
「ASP.NET Core Blazor の構成」の説明に従って、アプリ設定の構成を設定します。 Logging:LogLevel:HubConnection
アプリ設定を含むアプリ設定ファイルを wwwroot
に配置します。
注意
アプリ設定を使用する代わりに、ハブ接続が Razor コンポーネントで作成されるときに、LogLevel を LoggingBuilderExtensions.SetMinimumLevel の引数として渡すことができます。 ただし、詳細ログを含む運用レベルのホスティング環境にアプリを誤って配置すると、パフォーマンスが低下する可能性があります。 アプリ設定を使用してログ レベルを設定することをお勧めします。
既定の appsettings.json
ファイルと Development
環境アプリ設定ファイルに Logging:LogLevel:HubConnection
アプリ設定を指定します。 既定には、一般的な詳細度の低いログ レベル (LogLevel.Warning など) を使用します。 そのような環境のアプリ設定ファイルが存在しない場合、Staging
と Production
の環境で使用されるものが既定のアプリ設定値です。 LogLevel.Trace などの Development
環境アプリ設定ファイルでは、詳細ログ レベルを使用してください。
wwwroot/appsettings.json
:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"HubConnection": "Warning"
}
}
}
wwwroot/appsettings.Development.json
:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"HubConnection": "Trace"
}
}
}
重要
上記のアプリ設定ファイルの構成は、「ASP.NET Core Blazor の構成」のガイダンスに従う場合のみアプリによって使用されます。
Razor コンポーネント ファイル (.razor
) の上部で:
- ILoggerProvider を挿入して、HubConnectionBuilder に渡されたログ プロバイダーに
WebAssemblyConsoleLogger
を追加します。 ConsoleLoggerProvider とは異なり、WebAssemblyConsoleLogger
はブラウザー固有のログ API (例:console.log
) のラッパーです。WebAssemblyConsoleLogger
を使用すると、ブラウザー コンテキスト内の Mono 内でログ記録できるようになります。 IConfiguration
を挿入してLogging:LogLevel:HubConnection
アプリ設定を読み取ります。
Note
WebAssemblyConsoleLogger
は internal であり、開発者コードで直接サポートされていません。
@inject ILoggerProvider LoggerProvider
@inject IConfiguration Config
メモ
次の例は、Blazor で SignalR を使用するチュートリアルのデモに基づいています。 詳細については、チュートリアルを参照してください。
コンポーネントの OnInitializedAsync
メソッドで、HubConnectionBuilderExtensions.ConfigureLogging を使用してログ プロバイダーを追加し、構成から最小ログ レベルを設定します。
protected override async Task OnInitializedAsync()
{
hubConnection = new HubConnectionBuilder()
.WithUrl(Navigation.ToAbsoluteUri("/chathub"))
.ConfigureLogging(builder =>
{
builder.AddProvider(LoggerProvider);
builder.SetMinimumLevel(
Config.GetValue<LogLevel>("Logging:LogLevel:HubConnection"));
})
.Build();
hubConnection.On<string, string>("ReceiveMessage", (user, message) => ...
await hubConnection.StartAsync();
}
注意
前の例の Navigation
は、挿入された NavigationManager です。
アプリの環境を設定する方法の詳細については、「ASP.NET Core Blazorの環境」を参照してください。
クライアント側認証のログ
アプリの設定でログ構成を使用するか、または Program
ファイルの Microsoft.AspNetCore.Components.WebAssembly.Authentication にログ フィルターを使用して、Blazor 認証メッセージを LogLevel.Debug または LogLevel.Trace ログ レベルでログに記録します。
次の "いずれか" の方法を使用します。
アプリ設定ファイル (例:
wwwroot/appsettings.Development.json
):"Logging": { "LogLevel": { "Microsoft.AspNetCore.Components.WebAssembly.Authentication": "Debug" } }
クライアント側アプリでアプリ設定ファイルの読み取りを構成する方法の詳細については、「ASP.NET Core Blazor の構成」をご覧ください。
ログ フィルターを使用する場合、次の例のようになります。
- C# プリプロセッサ ディレクティブを使用して、
Debug
ビルド構成のログ記録をアクティブにします。 - Blazor 認証メッセージを Debug ログ レベルでログに記録します。
#if DEBUG builder.Logging.AddFilter( "Microsoft.AspNetCore.Components.WebAssembly.Authentication", LogLevel.Debug); #endif
- C# プリプロセッサ ディレクティブを使用して、
メモ
クライアントにレンダリングされた Razor コンポーネントのログは、クライアント側のブラウザー開発者ツール コンソールに対してのみ記録されます。
その他の技術情報
ASP.NET Core