ASP.NET Coreに NLogを組み込む


## パッケージのインストール

NuGet使って以下の最新パッケージをインストールします。

```
NLog.Web.AspNetCore 
NLog 
```

csprojファイルには、以下のような記述が追加されているはずです。

``` xml
<PackageReference Include="NLog.Web.AspNetCore" Version="4.9.0" />
<PackageReference Include="NLog" Version="4.6.8" />
```


## nlog.config ファイルの作成

プロジェクトの直下に、nlog.config ファイルを新規追加します。

nlog.config ファイルの例を示します。

```xml
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      internalLogLevel="Info"
      internalLogFile="internal-nlog.txt">
  <extensions>
    <add assembly="NLog.Web.AspNetCore" />
  </extensions>
  <targets async="true">
    <target xsi:type="File" name="debuglog" 
            fileName="${aspnet-appbasepath}/logs/debug-${shortdate}.log" 
            layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message}|url: ${aspnet-request-url:IncludeQueryString=true}" />
    <target xsi:type="File" name="infolog"
            fileName="${aspnet-appbasepath}/logs/info-${shortdate}.log"
            layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url:IncludeQueryString=true}" />
    <target xsi:type="File" name="errorlog"
            fileName="${aspnet-appbasepath}/logs/error-${shortdate}.log"
            layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|user: ${aspnet-user-identity} |url: ${aspnet-request-url:IncludeQueryString=true}|action: ${aspnet-request-form}" />
  </targets>
  <rules>
    <logger name="*" maxlevel="Debug" writeTo="debuglog" />
    <logger name="Microsoft.*" maxLevel="Info" final="true" />
    <logger name="*" levels="Error,Fatal,Warn" writeTo="errorlog" />
    <logger name="*" minlevel="Info" writeTo="infolog" />
  </rules>
</nlog>
```

## nlob.config のプロパティ設定

Visual Studioで、nlog.config のプロパティを開き、

- 「ビルドアクション」を "コンテンツ"、
- 「出力ディレクトリにコピー」を "新しい場合はコピーする"

に設定します。

## Program.cs の編集

Program.cs を以下のように変更します。

```c#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using NLog.Web;

namespace MyApp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
            try {
                logger.Debug("init main");
                var host = CreateHostBuilder(args).Build();
                using (var scope = host.Services.CreateScope()) {
					... // 必要ならここになにかを記述
                }
                host.Run();
            }
            catch (Exception ex) {
                logger.Error(ex, "Stopped program because of exception");
                throw;
            } finally {
                NLog.LogManager.Shutdown();
            }
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>  {
                    webBuilder.UseStartup<Startup>();
                })
                .ConfigureLogging(logging => {
                    logging.ClearProviders();
                    logging.SetMinimumLevel(LogLevel.Trace);
                })
                .UseNLog();
    }
}

```

## appsettings.json を編集

"Logging" に対する設定を以下のように変更します。

```json
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Trace",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  ...
```

LogLevelは、必要に応じて変更します。まあ、これは、nlog.config側で全部制御するという方針ならば、すべてを"Trace"にしてしまっても良いかもしれません。

LogLevelは、

Trace、Debug、Information、Warning、Error、Critical

の6種類があります。

## ログを出力する

例えば、HomeController の Index Action メソッドの中で、ログ出力する場合は、以下のようなコードを記述します。

```c#
using Microsoft.Extensions.Logging;

public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;

    public HomeController(ILogger<HomeController> logger)
    {
        _logger = logger;
    }

    public IActionResult Index()
    {
        _logger.LogInformation("Enter HomeController.Index Method");
        return View();
    }
```

## 実行例

プロジェクトのあるフォルダに logs フォルダが作成され、２つのファイルが作成されます。


### info-2020-02-16.log

```
2020-02-16 15:29:30.3013||INFO|RazorPagesMovie.Pages.IndexModel|HomeController.Index method called!!! |url: https://localhost/
```


### debug-2020-02-16.log

```
2020-02-16 15:29:26.2826||DEBUG|RazorPagesMovie.Program|init main|url: 
```