在ASP.NET Core应用程序中使用NLog - c#

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

我试图让它自己工作,而我想出的最好的方法如下:

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,但是我不确定如何最好地实现它。

这看起来像是有效的实现选项吗?
有没有更好的方法来实现BeginScopeImpl?
是否存在使NLog与ASP.NET Core一起工作的另一种方法?

参考方案

Microsoft.Framework.Logging.NLog已替换为NLog.Extensions.Logging on NuGet,由NLog团队维护。

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

如何使用:

建立

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

从ASP.NET Core 2开始,就有了新的方法。

ASP.NET Core 1

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

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中的设置不同

在program.cs中设置NLog:

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

在program.cs中设置NLog:

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规则

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

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

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

<?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文件中:

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

输出量

“ nlog-own-2018-02-14.log”包含:

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

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

疑难排解

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

您可以如下进行更改:

更改appsettings.json:

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

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

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

其他问题,请参阅此步骤计划以查找原因:
Logging-troubleshooting in NLog

干杯,

朱利安(NLog)

编辑:已更新为NLog.Web.AspNetCore 4.3

编辑2:已更新ASP.NET Core 2和最新建议

编辑3:已针对ASP.NET Core 3更新

jQuery发布不会将数据发布到ASP.NET API控制器 - javascript

我有一次噩梦般的时间通过jquery post将数据发送到ASP.NET Controller。这是JSON.stringify之后的数据:[{"scheduleTaskID":"203","task":"Permit","baselineDate":…

在ASP.NET MVC中创建数据库回调的最有效方法 - c#

我有一个ASP.NET MVC网页,该网页基本上通过日期过滤器显示MS SQL数据库中表的行。当新行插入数据库表时,我想用新行列表更新网页视图。实现此目标的最有效方法是什么?基本上,我想从我的JavaScript创建一个到数据库服务器的回调,以用新结果更新UI。假设数据库表中的行数很大。(〜1百万)谢谢,cas 参考方案 如果数据库更新非常频繁,则可以按特定…

在Asp.Net Gridview中分组数据 - c#

我有两个存储过程,它们将返回两组相关数据。数据就是这样。First Procedure这样返回数据ISSUE_ID ISSUETYPE ------------------------------------- 1 ISSUE 1 TYPE 2 ISSUE 2 TYPE 3 ISSUE 3 TYPE 4 ISSUE 4 TYPE 第二个过程基于ISSUE_I…

在Asp.Net MVC Razor中将HTML视图作为电子邮件附件发送 - javascript

我目前在Razor ASP.Net MVC工作。在这里,我有一个HTML view,名为“客户付款”,它是根据某些计算在RAZOR中生成的,并显示在HTML dialog中。我想将此Html View作为电子邮件附件发送。但是在这里,我感到困惑,我不得不将这个HTML View转移到.PDF or .jpg中的某些jQuery中,然后将其发送到Control…

在ASP.NET WebForms中在服务器端初始化bootsrap datatimepicker - javascript

我有这个HTML<div class='datepicker input-group date' id='datetimepickerStart'> <input type='text' class="form-control" /> <span c…