Serilog とは?
構造化ログ出力ライブラリです。
C# 側でこう書くと、
_logger.LogWarning("送信できないドメインです {@Params}", new { model.Id, model.Category });
こんな感じで出力できます。
{ "@t": "2017-08-24T02:24:16.0165287Z", "@mt": "送信できないドメインです {@Params}", "@l": "Warning", "Params": { "Id": "1234abc", "Category": "Test" }, "SourceContext": "MailWorker.Controllers.MainController", "ActionId": "b9510bc5-ac72-4651-b3ba-1116371b019a", "ActionName": "MailWorker.Controllers.MainController.Post (MailWorker)", "RequestId": "0HL7AISC1171N:00000004", "RequestPath": "/", "MachineName": "TEST-002" }
構造化された状態で持っておくことでログを効率的に処理する(集計やアラート設定など)ことができます。
Install / Setup (ASP.NET Core / .NET Core 2.0)
Install-Package Serilog Install-Package Serilog.Extensions.Logging Install-Package Serilog.Enrichers.Environment Install-Package Serilog.Formatting.Compact Install-Package Serilog.Sinks.Logentries
public class Startup { public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) .AddEnvironmentVariables(); Configuration = builder.Build(); // Serilog settings var token = Configuration.GetValue<string>("Logentries:Token"); if (!string.IsNullOrWhiteSpace(token)) { Log.Logger = new LoggerConfiguration() .MinimumLevel.Information() // デフォルトログレベル .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) // SourceContext毎のレベルの上書き .MinimumLevel.Override("System", LogEventLevel.Warning) .Enrich.FromLogContext() // Context (RequestIdやRequestPathなど)を付加する .Enrich.WithMachineName() // マシン名を付加する .WriteTo.Logentries(token, new CompactJsonFormatter()) // Logentries に CompactJson で書き出す .CreateLogger(); Log.Information("Startup End"); // アプリの起動ログが書ける } } public IConfigurationRoot Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(dispose: true)); } }
通常は標準のLoggerをDIで使いますが、Startupでは使えないのでSerilogのAPIで起動ログを書いています。
用語
https://github.com/serilog/serilog/wiki/Writing-Log-Events https://github.com/serilog/serilog/wiki/Configuration-Basics
- Source Contexts
- NLog や Log4net でいうところの logger name
- Enrichers
- ログに特定の情報を固定付与する
- NLogでもできないことはないが、こちらの方が拡張しやすい
- Serilog.Enrichers.[付与情報] という命名規則でライブラリが作成されている
- ログに特定の情報を固定付与する
- Sinks
- 設定で
WriteTo
から拡張メソッドで指定して、ログの出力先を決める - Serilog.Sinks.[接続先] という命名規則でログの出力先別にライブラリが作成されている
- 設定で
最初に知っておいたほうがよさそうなライブラリ
- Serilog.Extensions.Logging
- 標準の Microsoft.Extensions.Logging に紐付ける
- ログ出力が標準実装になっていれば後からSerilogを追加したとても全く既存コードに影響はない
- Serilog.Formatting.Compact
- デフォルトのJsonFormatterでもJSONにはできるがこれを使うとよりコンパクトにできる
- Serilog.Enrichers.Environment
- MachineNameを付与できる
- ライブラリ側でWindowsとその他のOSの差異を吸収している
- MachineNameを付与できる
- Serilog.Sinks.Async
- 非同期化
- Serilog.Settings.Configuration
- 標準っぽく appsettings.json に設定を書ける
- タイプセーフに設定を書けたほうがいいので個人的にはこれは使わなくていいと思う
- NLog で設定ファイル間違えてサイレントにログが出なくなってハマった思い出
- CI/CDをちゃんとやっているとデプロイのコストは変わらない
リファレンス
- https://nblumhardt.com/
- 作者のブログ
- 公式Wikiに反映されてないのもあるので参考になる