.net6の情報が出ていたので、nlogのサンプルを書き直しました。
xUnitと併せてのサンプルです
.NET 6.0 C# Razor
NLog4.7.15
NLog.Web.AspNetCore4.14.0
xunit2.4.1
公式がgithubに記載している以外では
https://github.com/NLog/NLog/wiki/Getting-started-with-ASP.NET-Core-6
[5. Write logs]でControllerから取得しているのですが、
ここでは、Razorを使いたいので、PageModelをつかってます
1 2 3 4 5 |
private readonly ILogger<IndexModel> _logger; public IndexModel(ILogger<IndexModel> logger) { _logger = logger; } |
共通で使用するクラスとかでログ出力するとき
中規模以上のシステムになると、共通でつかうクラスが出てきますが、
ログを出力したいとなると、Modelで取得したLoggerを引っ張りまわすか、その場で生成するという手法が考えられます
Loggerを引っ張りまわすときに呼び出し元のModel名だと都合が悪いので、一回PageModelに型変換すると予備先で楽になります
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public class ThirdModel : PageModel { // PageModelで定義 private readonly ILogger<PageModel> _logger; // ILoggerにはThirdModelを指定 public ThirdModel(ILogger<ThirdModel> logger) { // ThirdModelからPageModelに変換 _logger = (ILogger<PageModel>)logger; } public void OnGet() { var m = new Logic.Sample3Class(_logger); m.SafeCase(); _logger.LogInformation(1, "PageModelでのログ書き出し"); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class Sample3Class { private readonly ILogger<PageModel> _logger; public Sample3Class(ILogger<PageModel> logger) { _logger = logger; } public Boolean SafeCase() { _logger.LogInformation("PageModelをつかってログ出力"); return true; } } |
xUnitで単体テストするときに
xUnitから呼び出す時に、下記の問題がありまして
Razor Pageで、nlogを使うと、コンテキストからloggerをもらうので、
xUnitでログを出力するところがテストできてないです。
ものすごく頑張ればモデルを作れるハズみたいです(下の方のソースにindexModelをつくってる)
https://docs.microsoft.com/en-us/aspnet/core/test/razor-pages-tests?view=aspnetcore-3.1
解決策としては、
ログはエラーハンドリング系にだけに入れておき、xUnitで生成時にILoggerなどにはnullを設定して
どうしてもログ出力を通過する個所については、コンパイル時にシンボル指定して回避する
1 2 3 4 5 6 7 8 |
[Fact] public void UhyoTest1() { ILogger<SecondModel> _logger = null; var a = new SecondModel(_logger); a.OnGet(); Assert.True(a.Uhyo == "hoge"); } |
1 2 3 4 5 6 7 8 9 |
public void OnGet() { Uhyo = "hoge"; #if !UNITTEST _logger.LogDebug(1, "OnGet"); #endif } |
共通処理等でまとめPageModelから遠いクラスでのエラーハンドリングとかでは、
個別にlogerを生成したほうがコーディング量は減るかもしれないです
ログファイルへの出力の場合はファイルへの書き込み待ちが発生するので推奨できないですが、
ログ専用にsyslogサーバーなどを別途立ててxml,jsonもしくはキュー、クエリでログを投げる場合は良いと思います
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class SampleClass { private readonly Logger _logger; public SampleClass() { // loggerの生成 // ログファイルに出力する場合は非推奨: _logger = NLog.LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger(); } public void LogOut() { _logger.Info("インフォメーションレベル"); _logger.Warn("ワーニングレベル"); _logger.Error("エラーレベル"); } } |
今回作成したプロジェクト