ASP.NET Core MVCでSerilogを使ってファイルにログ出力するサンプルを書いてみました。
Serilog — simple .NET logging with fully-structured events
サンプルでは次のことを実現しています。
それではコードを見ていきましょう。
Serilogをインストールする
まずはNuGetで必要なパッケージをインストールします。
Install-Package Serilog Install-Package Serilog.AspNetCore Install-Package Serilog.Formatting.Compact Install-Package Serilog.Settings.Configuration Install-Package Serilog.Sinks.File
パッケージ名から想像できるかもしれませんが、それぞれのパッケージの役割は次のような感じです。
パッケージ | 説明 |
---|---|
Serilog | 本体 |
Serilog.AspNetCore | ASP.NET Core用(WebHostBuilderのUseSerilog) |
Serilog.Formatting.Compact | ログのJSON形式出力 |
Serilog.Settings.Configuration | appsettings.jsonから設定を読み込む |
Serilog.Sinks.File | ログのファイル出力(日付ごとのログファイル作成もこれ) |
今回のサンプルでは使っていませんが以下もよく使いそうですね。
パッケージ | 説明 |
---|---|
Serilog.Sinks.Console | ログのコンソール出力 |
Serilog.Sinks.Debug | ログのデバッグ出力 |
ログ出力の準備をする
一旦appsettings.jsonのことは忘れて、まずはコードでログ出力の準備をしたいと思います。
公式のサンプルなどを見ているとWebHostを構築する前にロガーを準備するといいようで、Programクラスを次のような感じにします。
public class Program { public static void Main(string[] args) { // ロガーを構築する Log.Logger = new LoggerConfiguration() // ファイルに書き込む .WriteTo.File( // JSON形式で出力 formatter: new CompactJsonFormatter(), path: @".\log\webapp.txt", restrictedToMinimumLevel: LogEventLevel.Information, // 日付ごとに新しいファイルを作る rollingInterval: RollingInterval.Day) .CreateLogger(); try { Log.Information("Starting Web Host"); CreateWebHostBuilder(args) .Build() .Run(); } catch (Exception exception) { Log.Fatal(exception, "Host terminated unexpectedly"); } finally { Log.CloseAndFlush(); } } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() // ログプロバイダーとしてSerilogを使う .UseSerilog(); }
コントローラでログを出力する
コントローラのアクションでログを出力するコードを書き足します。
public class HomeController : Controller { private readonly ILogger _logger; public HomeController(ILogger<HomeController> logger) { _logger = logger; } public IActionResult Index() { // ログを出力 _logger.LogInformation( "Log {@param}", new { controller = "Home", action = "Index" }); return Content("Home.Index"); } }
これでアクションを呼び出すとログが出力されるようになりました。
指定した出力先にwebapp20181205.txt
といった日付を含んだ名前のファイルが作成されます。また出力されるログの中身は整形すると次のようなものです。
{ "@t": "2018-12-05T02:18:12.3417756Z", "@mt": "Log {@param}", "param": { "controller": "Home", "action": "Index" }, "SourceContext": "WebApp.Controllers.HomeController", "ActionId": "", "ActionName": "WebApp.Controllers.HomeController.Index (WebApp)", "RequestId": "", "RequestPath": "", "CorrelationId": null, "ConnectionId": "" }
appsettings.jsonを参照する
今度はappsettings.jsonから設定を読み込んで上記と同じロガーを構築したいと思います。
appsettings.jsonを作成して、公式を参考にしながら設定を書いていきます。formatterを指定する方法に悩みましたが多分これでいいはずです。
{ "Serilog": { "Using": [ "Serilog.Sinks.File", "Serilog.Formatting.Compact" ], "WriteTo": [ { "Name": "File", "Args": { "formatter": "Serilog.Formatting.Compact.CompactJsonFormatter, Serilog.Formatting.Compact", "path": ".\\log\\webapp.txt", "restrictedToMinimumLevel": "Information", "rollingInterval": "Day" } } ] } }
Programクラスのロガーを構築する部分は、設定ファイルを読み込むように変更します。
// appsettings.jsonを読み込む準備 var config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .Build(); // ロガーを構築する Log.Logger = new LoggerConfiguration() .ReadFrom.Configuration(config) .CreateLogger();
これでアクションを呼び出すとさっきと同じようなログが出力されます。
おしまい。