ASP.NET Advent Calendar 6日目です。
ASP.NET 5 でLoggingの機能が一新されます。今日は簡単に紹介したいと思います。なお下記のドキュメントを参考にしつつ、コードは ASP.NET RC1 時点のものを参照しているため、Nugetのパッケージ名など一部が変更されています*1。
Logging — ASP.NET 0.0.1 documentation
Loggingするには
Loggingのインターフェース自体はおそらく .NET Coreでも使われると思われますが*2、ASP.NET においてはDIによるLoggerの注入が前提となっています。ILoggerFactory を注入してCreateLogger
するか ILogger もしくは ILogger
public class HomeController : Controller { private ILogger<HomeController> logger; public HomeController(ILogger<HomeController> logger) { this.logger = logger; } public IActionResult Index() { logger.LogInformation("Home"); return View(); } }
public class HomeController : Controller { private readonly ILogger logger; public HomeController(ILoggerFactory loggerFactory) { logger = loggerFactory.CreateLogger<HomeController>(); } public IActionResult Index() { logger.LogInformation("Home"); return View(); } }
DIにより取得するので一番わかりやすいControllerでサンプルを書きました。じゃあ、それ以外のDIではなくインスタンス生成されるクラスでロギングしたい場合はどうするか?という点についてはあまり情報がなく、ILoggerFactoryを引き回して渡すか、コンストラクタ経由の注入ではなく別の方法でILoggerFactoryのインスタンスを取得するか、になるのではないでしょうか。ただ後者については、現時点でのドキュメントには方法が書いておらず、自分が調べた範囲でもどうやるかはわからないままです。
Dependency Injection — ASP.NET 0.0.1 documentation
Loggingの構成と出力のカスタマイズ
Startup.Configure
メソッドで引数に渡されるILoggerFactory
に対してメソッドを呼び出すことで設定を行います。ConsoleやDebug、TraceListenerやEventLogへ出力するためのライブラリが標準で提供されているので、project.json に追加して設定を行います。
"dependencies": { "Microsoft.Extensions.Logging": "1.0.0-rc1-final", "Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final", "Microsoft.Extensions.Logging.Debug": "1.0.0-rc1-final", "Microsoft.Extensions.Logging.TraceSource": "1.0.0-rc1-final", }
ただ、TraceListenerやEventLogはDNX Coreではサポートしていないので、ifディレクティブなどと併用する必要があります。
loggerFactory.AddDebug(); loggerFactory.AddConsole(); #if DNX451 var sourceSwitch = new SourceSwitch("LoggingSample"); loggerFactory.AddTraceSource(sourceSwitch, new ConsoleTraceListener(false)); loggerFactory.AddTraceSource(sourceSwitch, new EventLogTraceListener("Application")); #endif
自前で出力先を追加したい場合は、ILogger
を継承して出力を行うクラスに加えて、仲介するためのILoggerProvider
を継承したクラスを作成したうえで、AddDebug
, AddConsole
のように ILoggerFactory
を第一引数として受け取り必要な設定を行うための拡張メソッドを用意するのが推奨されています。既存の拡張を参考にするとわかりやすいでしょう。
Logging/src/Microsoft.Extensions.Logging.Debug at 1.0.0-rc1 · aspnet/Logging · GitHub
Logging/src/Microsoft.Extensions.Logging.Console at 1.0.0-rc1 · aspnet/Logging · GitHub
ファイル出力をしたい場合は...?
GitHubのIssueでNLogもしくはSeriLogを使えばといった既存の仕組みがあるので、そちらを当面使ってほしいとのことのようです。
確かにサンプルアプリを見るとNLogを使っていて、NLog.config経由でログの設定を行えるので、既存のアプリのconfigをそのまま動かすこともできそうです。将来的には、ビルドインの機能として提供したいようですが、Issueに書いてある通りそこに至るのは時間がかかりそうです。
Logging/samples/SampleApp at 1.0.0-rc1 · aspnet/Logging · GitHub
構造化ログを使いたい場合は...?
GitHubのIssueには上がっています。
が、これどう見ても検討すらしておらず後回しにしてる様が見て取れます...
実際、ILoggrのメソッド定義を見るに文字列前提にしているため、ここから構造化ログに対応するのは割と骨が折れそうな気配があります。
構造化ログを採用したいなら、Semantic Logging Application Block(SLAB).aspx)を全面的に採用して、EventSource 経由でのロギングにするのがいいのではと思います。SLABはSLABで全く動きがみられないんですが、EventSource自体は.NET標準の機能ですし、そこから取り出す方法は別途考えることができます。この辺のお話はまた別途。