koudenpaのブログ

趣味のブログです。株式会社はてなでWebアプリケーションエンジニアをやっています。職業柄IT関連の記事が多いと思います。

Blazor WebAssemblyのログ

がどうなってんのか気になったので少し見ていたメモ。

Blazor WebAssemblyのプロジェクトで依存しているDLLで無造作に.AddDebug()してデバッグログを見ていたのだけれど、Blazor WebAssembly上では特にコンソール上に何か出るわけでも、エラーするわけでもなく動作していたので気になった次第。

とりあえずドキュメントを見てもイマイチ分からなかったので試したりソースを眺めたりした。

バージョンは 5.0.3 で、ここでいうログはサードパーティのものではなく Microsoft.Extensions.Logging です。

基本的にはログレベルだけ設定( builder.Logging.SetMinimumLevel(LogLevel.XXX) )すればいいようだった。それだけでWebAssemblyConsoleLoggerというブラウザのコンソールにログ出力するロガーが構成されるようになっている。

Debugレベル以下はブラウザ*1の側でフィルタされているので、それらを見たい場合は『すべてのレベル』を表示するように設定する必要はあった。

f:id:koudenpa:20210228233354g:plain
Debugレベル以下はブラウザの既定ではフィルタされている

未対応のログプロバイダを追加すると動作しないので、変な設定をしてしまったらその設定を消せばよい。スクリーンショット.AddConsole() してみた場合のもの。

f:id:koudenpa:20210228233317p:plain
未対応のProviderを追加すると例外する

この記事の段階のお試し結果を転記しておく。

public class Program
{
  public static async Task Main(string[] args)
  {
    var builder = WebAssemblyHostBuilder.CreateDefault(args);
    builder.RootComponents.Add<App>("#app");
    // Document: https://docs.microsoft.com/ja-jp/aspnet/core/blazor/fundamentals/logging?view=aspnetcore-5.0&pivots=webassembly
    // ドキュメントからだと分かりづらいが、
    // 既定で WebAssemblyConsoleLoggerProvider が構成されており ILogger を注入するだけでコンソールにログ出力を行えるようになっている。
    // https://github.com/dotnet/aspnetcore/blob/d827c653b787c07de908240b7746ce34d3e6271e/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs#L227-L230
    builder.Logging
      // Chromeの開発者ツールの既定では Info レベル以上を表示するようになっている。
      // Debug 以下のレベルを表示するにはブラウザ側の設定も変更が必要。
      .SetMinimumLevel(LogLevel.Trace)
      // 事実上他のプロバイダーは設定しても動かなかったり、設定した瞬間に(ちゃんと)未対応である旨の例外が発生する。
      // 例えばローカルストレージにログを出力する CustomLoggingProvider を実装する、のようなことはできなくもないようだ。
      .AddDebug()
      //.AddConsole()
      //.AddSimpleConsole()
      ;
    builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
    await builder.Build().RunAsync();
  }
}
@page "/counter"

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    [Inject]
    private ILogger<Counter> logger { get; set; }

    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
        logger.LogTrace($"LogTrace Count: {currentCount}");
        logger.LogDebug($"LogDebug Count: {currentCount}");
        logger.LogInformation($"LogInformation Count: {currentCount}");
        logger.LogWarning($"LogWarning Count: {currentCount}");
        logger.LogError($"LogError Count: {currentCount}");
    }
}

例えばローカルストレージにログを出力する CustomLoggingProvider を実装する、のようなことはできなくもないようだ。

これはクラッシュログとか貯めておけて使える場面はあるかもしれない。

後は、Application Insights プロバイダの対応状況は普通に気になるな。これは別途試してみるかもしれないけれど、ログというよりは統合的なApplication Insights対応のほうが気になる。

そんな感じだった。

*1:ChromeやEdgeはそうだったが他のブラウザでどうかは定かではない