---
# System prepended metadata

title: NLog
tags: [dotnet]

---

# Nlog

https://nlog-project.org/

# 加入套件
```bash=
dotnet add package NLog --version 5.2.7
dotnet add package NLog.Web.AspNetCore --version 5.3.7
dotnet add package NLog.Targets.ElasticSearch --version 7.7.0
```

# 修改Program.cs
```csharp=
using NLog.Web;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

// NLog: Setup NLog for Dependency injection
builder.Logging.ClearProviders();
builder.Host.UseNLog();

// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.MapControllers();
app.Run();
```

# 加入nlog.config

* 檔案名稱全小寫
* ${basedir}
* ${aspnet-appbasepath}

```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="./logs/internal-nlog-AspNetCore.txt">

  <!-- enable asp.net core layout renderers -->
  <extensions>
    <add assembly="NLog.Web.AspNetCore"/>
  </extensions>

   <!-- the targets to write to -->
  <targets>
    <!-- File Target for all log messages with basic details -->
    <target xsi:type="File" name="allfile" fileName="${aspnet-appbasepath}/logs/nlog-AspNetCore-all-${shortdate}.log"
            layout="${longdate}|${event-properties:item=EventId:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}" />

    <!-- File Target for own log messages with extra web details using some ASP.NET core renderers -->
    <target xsi:type="File" name="ownFile-web" fileName="${aspnet-appbasepath}/logs/nlog-AspNetCore-own-${shortdate}.log"
            layout="${longdate}|${event-properties:item=EventId:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" />

    <!--Console Target for hosting lifetime messages to improve Docker / Visual Studio startup detection -->
    <target xsi:type="Console" name="lifetimeConsole" layout="${MicrosoftConsoleLayout}" />
  </targets>

  <!-- rules to map from logger name to target -->
  <rules>
    <!--All logs, including from Microsoft-->
    <logger name="*" minlevel="Trace" writeTo="allfile" />

    <!--Output hosting lifetime messages to console target for faster startup detection -->
    <logger name="Microsoft.Hosting.Lifetime" minlevel="Info" writeTo="lifetimeConsole, ownFile-web" final="true" />

    <!--Skip non-critical Microsoft logs and so log only own logs (BlackHole) -->
    <logger name="Microsoft.*" maxlevel="Info" final="true" />
    <logger name="System.Net.Http.*" maxlevel="Info" final="true" />
    
    <logger name="*" minlevel="Trace" writeTo="ownFile-web" />
  </rules>

  
</nlog>
```

# 寫入Log
```csharp=
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
public class HomeController : ControllerBase
{
    private readonly ILogger<HomeController> log;

    public HomeController(ILogger<HomeController> log)
    {
        this.log = log;
        this.log.LogDebug(1, "NLog injected into HomeController");
    }

    [HttpGet]
    public string Hello()
    {
        this.log.LogInformation("Hello, this is the index!");
        return "hello";
    }
}
```