Nlog Getting started with ASP.NET Core 6

[删除(380066935@qq.com或微信通知)]

更好的阅读体验请查看原文:https://github.com/NLog/NLog/wiki/Getting-started-with-ASP.NET-Core-6

In Visual Studio 2022. Version 17.0+ is needed

1. Add dependency in csproj manually or using NuGet

Install the latest:

in csproj:

<ItemGroup>
  <PackageReference Include="NLog.Web.AspNetCore" Version="4.*" />
  <PackageReference Include="NLog" Version="4.*" />
</ItemGroup>

2. Create a nlog.config file.

Create nlog.config (lowercase all) file in the root of your project.

We use this example:

<?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="c:\temp\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="c:\temp\nlog-AspNetCore-all-${shortdate}.log"
            layout="${longdate}|${event-properties:item=EventId_Id: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="c:\temp\nlog-AspNetCore-own-${shortdate}.log"
            layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}|${callsite}" />

    <!--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>

More details of the config file are here.

Notice that one might have to pay special attention to the Hosting Lifetime Startup Messages, if removing all other LoggingProviders (Like Console) and only using NLog. As it can cause hosting environment (Visual Studio / Docker / Azure Container) to not see application as started.

If you like to include other targets or layout renderers, check the Platform support table, as there is a limited set implemented. Check the column NetStandard. To read more about NetStandard, see the docs from Microsoft. Check .NET Standard 2.1 for ASP.NET Core 6.

3. Update program.cs

Update the program.cs

using NLog;
using NLog.Web;

var logger = NLog.LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
logger.Debug("init main");

try
{
    var builder = WebApplication.CreateBuilder(args);

    // Add services to the container.
    builder.Services.AddControllersWithViews();

    // NLog: Setup NLog for Dependency injection
    builder.Logging.ClearProviders();
    builder.Logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
    builder.Host.UseNLog();

    var app = builder.Build();

    // Configure the HTTP request pipeline.
    if (!app.Environment.IsDevelopment())
    {
        app.UseExceptionHandler("/Home/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");

    app.Run();
}
catch (Exception exception)
{
    // NLog: catch setup errors
    logger.Error(exception, "Stopped program because of exception");
    throw;
}
finally
{
    // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
    NLog.LogManager.Shutdown();
}

4. Configure appsettings.json

The Logging configuration specified in appsettings.json overrides any call to SetMinimumLevel. So either remove "Default": or adjust it correctly to your needs.

{
  "Logging": {
    "LogLevel": {
      "Default": "Trace",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Remember to also update any environment specific configuration to avoid any surprises. Ex appsettings.Development.json

5. Write logs

Inject the ILogger in your controller:

using Microsoft.Extensions.Logging;

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

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

    public IActionResult Index()
    {
        _logger.LogInformation("Hello, this is the index!");
        return View();
    }
}

6. Example Output

When starting the ASP.NET Core website, we get two files:

nlog-own-2021-12-01.log

2020-12-29 16:47:02.5291||DEBUG|ASP.NET_Core_6_NLog_Example.Program|init main |url: |action: 
2020-12-29 16:47:03.5943|1|DEBUG|ASP.NET_Core_6_NLog_Example.Controllers.HomeController|NLog injected into HomeController |url: https://localhost/|action: Index
2020-12-29 16:47:03.5943||INFO|ASP.NET_Core_6_NLog_Example.Controllers.HomeController|Hello, this is the index! |url: https://localhost/|action: Index

nlog-all-2021-12-01.log

2020-12-29 16:47:02.5291||DEBUG|ASP.NET_Core_6_NLog_Example.Program|init main 
2020-12-29 16:47:03.5260||INFO|Microsoft.Hosting.Lifetime|Application started. Press Ctrl+C to shut down. 
2020-12-29 16:47:03.5260||INFO|Microsoft.Hosting.Lifetime|Hosting environment: Development 
2020-12-29 16:47:03.5260||INFO|Microsoft.Hosting.Lifetime|Content root path: D:\nlog\NLog.Web\examples\ASP.NET Core 6\ASP.NET Core 6 NLog Example 
2020-12-29 16:47:03.5943|1|DEBUG|ASP.NET_Core_6_NLog_Example.Controllers.HomeController|NLog injected into HomeController 
2020-12-29 16:47:03.5943||INFO|ASP.NET_Core_6_NLog_Example.Controllers.HomeController|Hello, this is the index!  

Configure NLog Targets for output

Next step, see Configure NLog with nlog.config