在ASP.NET Core应用程序中使用NLog [英] Use NLog in ASP.NET Core application

查看:97
本文介绍了在ASP.NET Core应用程序中使用NLog的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了 CodeProject 与一个如何使它工作的示例,但它不起作用.主要问题似乎是"Microsoft.Framework.Logging.NLog": "1.0.0-*"软件包似乎在Nuget中不存在.我看过这StackOverflow问题,并查看了它引用的GitHub示例,但似乎包含相同的问题.

I found a CodeProject with an example of how to get this to work, but it doesn't work. The main problem seems to be that the "Microsoft.Framework.Logging.NLog": "1.0.0-*" package doesn't seem to exist in Nuget. I've looked at this StackOverflow question and looked at the GitHub example it references, but it seems to contain the same issue.

我试图让它自己运行,而我想出的最好的方法是:

I've tried to get it working on my own and the best I've come up with is the following:

public class NLogLogger : ILogger
{
    public NLogLogger()
    {
        new WebLoggerConfigurer().ConfigureDefault();
    }

    public void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter)
    {
        // currently need the global:: for LogLevels because our namespace contains NLog in it. Is there a better naming convention we could use instead?
        var ll = logLevel == LogLevel.Debug ? global::NLog.LogLevel.Debug
                : logLevel == LogLevel.Verbose ? global::NLog.LogLevel.Trace
                : logLevel == LogLevel.Critical ? global::NLog.LogLevel.Fatal
                : logLevel == LogLevel.Error ? global::NLog.LogLevel.Error
                : logLevel == LogLevel.Information ? global::NLog.LogLevel.Info
                : logLevel == LogLevel.Warning ? global::NLog.LogLevel.Warn
                : global::NLog.LogLevel.Off;

        LogManager.GetCurrentClassLogger().Log(ll, formatter(state, exception));
    }

    public bool IsEnabled(LogLevel logLevel)
    {
        return true;
    }

    public IDisposable BeginScopeImpl(object state)
    {
        return new Disposable(() => { });
    }
}

public class NLogLoggerProvider : ILoggerProvider
{
    public void Dispose()
    {
    }

    public ILogger CreateLogger(string categoryName)
    {
        return new NLogLogger();
    }
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddProvider(new NLogLoggerProvider());
    ..
}

BeginScopeImpl的实现似乎是一个hack,但是我不确定如何最好地实现它.

The implementation of BeginScopeImpl seems to be a hack, but I was unsure how best to implement it.

  1. 这似乎是有效的实施选项吗?
  2. 是否有一些更好的方法来实现BeginScopeImpl?
  3. 是否存在使NLog与ASP.NET Core一起使用的另一种方法?

推荐答案

Microsoft.Framework.Logging.NLog已替换为

Microsoft.Framework.Logging.NLog has been replaced by NLog.Extensions.Logging on NuGet, which is maintained by the NLog team.

对于ASP.NET Core,您需要 NLog.Web.AspNetCore (依赖于 NLog.Extensions.Logging)

For ASP.NET Core you need NLog.Web.AspNetCore (which has an dependency on NLog.Extensions.Logging)

使用方法:

需要启用NLog,以便将其集成到ASP.NET Core的DI和日志API中. 这将导致所有由外部人员(例如Microsoft)编写的日志也将发送到NLog-您可以在NLog的配置中将其过滤掉(不影响性能)

NLog needs to be enabled so it will integrate into the DI and log API of ASP.NET Core. This will result that all logs written by externals (e.g. Microsoft) will be also sent to NLog - you could filter that out in the NLog's config (without performance impact)

自从ASP.NET Core 2以来,就有了新的方法.

Since ASP.NET Core 2 there are new approach.

在ASP.NET Core中的Configure和可选的ConfigureServices中,需要更新.

In ASP.NET Core in Configure and optionally ConfigureServices needs to be updated.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    //add NLog to .NET Core
    loggerFactory.AddNLog();

    //Enable ASP.NET Core features (NLog.web) - only needed for ASP.NET Core users
    app.AddNLogWeb();

    //configure nlog.config in your project root. 
    env.ConfigureNLog("nlog.config");
    ...
    //you could use LogManager.Configuration from here


public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    // e.g. services.AddMvc();

    //needed for NLog.Web
    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}

ASP.NET Core 2

对于ASP.NET Core 2,设置与ASP.NET Core 1中的设置不同

ASP.NET Core 2

For ASP.NET Core 2 the setup is different than in ASP.NET Core 1

设置N登录program.cs:

Set-up NLog in program.cs:

using NLog.Web;
using Microsoft.Extensions.Logging;

public static void Main(string[] args)
{
    // NLog: setup the logger first to catch all errors
    var logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
    try
    {
        logger.Debug("init main");
        CreateWebHostBuilder(args).Build().Run(); 
    }
    catch (Exception ex)
    {
        //NLog: catch setup errors
        logger.Error(ex, "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();
    }
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureLogging(logging =>
        {
            logging.ClearProviders();
            logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
        })
        .UseNLog();  // NLog: setup NLog for Dependency injection

ASP.NET Core 3

与ASP.NET Core 2相比,有一些小的变化,例如有一个IHostBuilder而不是IWebHostBuilder

设置N登录program.cs:

Set-up NLog in program.cs:

using System;
using NLog.Web;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Hosting;

public static void Main(string[] args)
{
    var logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
    try
    {
        logger.Debug("init main");
        CreateHostBuilder(args).Build().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();
    }
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
      .ConfigureWebHostDefaults(webBuilder =>
      {
          webBuilder.UseStartup<Startup>();
      })
      .ConfigureLogging(logging =>
      {
          logging.ClearProviders();
          logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
      })
      .UseNLog();  // NLog: Setup NLog for Dependency injection

写日志

以类类型作为通用参数注入ILogger.

public class HomeController : Controller
{
    public HomeController(ILogger<HomeController> logger)
    {
        logger.LogInformation("created homeController");
    }

配置NLog规则

示例如何配置,记录和过滤.

Configure NLog rules

Example how to configure, log and filter.

创建nlog.config(有关nlog.config的更多信息,请参见 docs )

Create a nlog.config (for more reading about nlog.config, see docs)

此示例将创建2个文件,一个将创建所有日志(包括Microsoft的日志),一个仅包含您的日志的文件.

This example will create 2 files, one will all the logs (including Microsoft's) and a file with only your logs.

<?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="Warn"
        internalLogFile="c:\temp\internal.txt">


    <extensions>
        <!--enable NLog.Web for ASP.NET Core-->
        <add assembly="NLog.Web.AspNetCore"/>
    </extensions>

    <!-- define various log targets -->
    <targets>
        <!-- write logs to file -->
        <target xsi:type="File" name="allfile" fileName="c:\temp\nlog-all-${shortdate}.log"
                        layout="${longdate}|${logger}|${uppercase:${level}}|${message} ${exception}" />

        <target xsi:type="File" name="ownFile" fileName="c:\temp\nlog-own-${shortdate}.log"
                    layout="${longdate}|${logger}|${uppercase:${level}}|${message} ${exception}" />

    </targets>

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

        <!--Skip Microsoft logs - no writeTo attribute-->
        <logger name="Microsoft.*" minlevel="Trace" final="true" />
        <logger name="*" minlevel="Trace" writeTo="ownFile" />
    </rules>
</nlog>

发布nlog.config

确保将nlog.config发布,例如在您的csproj文件中:

Publish nlog.config

Make sure that the nlog.config will be published, e.g in your csproj file:

<ItemGroup>
    <Content Update="nlog.config" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

输出

"nlog-own-2018-02-14.log"包含:

Output

"nlog-own-2018-02-14.log" contains:

2018-02-14 16:27:04.0547 | aspnetCoreApplication.Controllers |信息|创建的homeController

2018-02-14 16:27:04.0547|aspnetCoreApplication.Controllers|INFO|created homeController

2018-02-14 16:27:04.0547 | aspnetCoreApplication.Controllers |信息|创建的homeController

2018-02-14 16:27:04.0547|aspnetCoreApplication.Controllers|INFO|created homeController

问题排查

在ASP.NET Core 2中缺少调试日志消息吗?虽然我们在program.cs中使用SetMinimumLevel,但appsettings.json也可以使之融合.

Troubleshoot

Missing debug log messages in ASP.NET Core 2? While the we use SetMinimumLevel in program.cs, also appsettings.json could confluence this.

您可以进行以下更改:

更改appsettings.json:

Change appsettings.json:

{
    "Logging": {
        "LogLevel": {
            "Default": "Trace"
        }
    }
}

您还可以在此处过滤Microsoft的日志,例如

You could also filter Microsoft's logs here, e.g.

{
    "Logging": {
        "LogLevel": {
            "Default": "Trace",
            "Microsoft": "Information"
        }
    }
}

其他问题,请参阅此步骤计划以查找原因: 在NLog中进行日志记录

Other issues, see this step plan to find the cause: Logging-troubleshooting in NLog

干杯

Julian(NLog)

Julian (NLog)

已更新NLog.Web.AspNetCore 4.3

updated for NLog.Web.AspNetCore 4.3

针对ASP.NET Core 2和最新建议进行了更新

Edit 2: Updated for ASP.NET Core 2 and latest recommendations

已针对ASP.NET Core 3更新

Edit 3: Updated for ASP.NET Core 3

这篇关于在ASP.NET Core应用程序中使用NLog的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆