在 ASP.NET Core 应用程序中使用 NLog
Posted
技术标签:
【中文标题】在 ASP.NET Core 应用程序中使用 NLog【英文标题】:Use NLog in ASP.NET Core application 【发布时间】:2016-04-13 07:03:36 【问题描述】:我找到了一个CodeProject,其中有一个如何让它工作的例子,但它不起作用。主要问题似乎是 Nuget 中似乎不存在 "Microsoft.Framework.Logging.NLog": "1.0.0-*"
包。我查看了 this *** 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 一起工作吗?
【问题讨论】:
你有Github上的实现代码 【参考方案1】: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 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 & 5
与 ASP.NET Core 2 相比,有一些小的变化,例如有一个IHostBuilder
而不是IWebHostBuilder
。
对于 ASP.NET Core 5,步骤相同。
在 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");
ASP.NET Core 6
对于 ASP.NET Core 6,您可以在没有 Startup
类的情况下对其进行配置。更新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();
配置 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
这不是 ASP.NET Core 5 的必需步骤
确保 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|INFO|创建的 homeController
2018-02-14 16:27:04.0547|aspnetCoreApplication.Controllers|INFO|创建的 homeController
疑难解答
在 ASP.NET Core 2 中缺少调试日志消息?虽然我们在 program.cs 中使用 SetMinimumLevel
,但 appsettings.json 也可以将其融合。
你可以改变如下:
更改 appsettings.json:
"Logging":
"LogLevel":
"Default": "Trace"
你也可以在这里过滤微软的日志,例如
"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 更新
编辑 4:针对 ASP.NET Core 5 更新
编辑 5:针对 ASP.NET Core 6 更新
【讨论】:
app.AddNLogWeb()
对于 NetStandard 2.0 已过时,因为 NLog.Web.AspNetCore v4.7.0 / 2017 年 9 月 29 日:github.com/NLog/NLog.Web/commit/7c6429c7。
@Julian ,到目前为止看起来不错,如果我有 BaseClass
=> ChildClass
es,如果我需要登录 Base
,注入如何工作?有什么想法吗?
@Gopichandar 很难在评论中回答,建议创建一个新问题。 (但请先搜索,我认为它已经在 *** 上得到了回答)【参考方案2】:
更新到Julian's answer:NLog.Framework.Logging 被标记为已过时,请改用NLog.Extensions.Logging(不过只是一个包重命名)。此外,env.ConfigureNLog("nlog.config");
仅适用于 Visual Studio (IIS Express) 中的调试。在测试环境中向常规 IIS 发布服务后,它无法以500 internal server error
启动。花了很长时间才发现服务在启动时找不到nlog.config
。终于找到解决方案in NLog issues:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationEnvironment appEnv)
...
env.ConfigureNLog(Path.Combine(appEnv.ApplicationBasePath, "nlog.config"));
...
问题是在本地调试时工作目录是你的项目目录,里面有nlog.config
,但是发布到IIS后,所有源文件都在%PATH_TO_PUBLISHED_SERVICE%\approot\src\%PROJECT_NAME%\
,而工作目录是%PATH_TO_PUBLISHED_SERVICE%\
。
【讨论】:
【参考方案3】:也可用于 .net 核心控制台应用程序。
private static void ConfigureNlogConfig(string configFile)
LogManager.Configuration = new XmlLoggingConfiguration(Path.Combine(Microsoft.Extensions.PlatformAbstractions.PlatformServices.Default.Application.ApplicationBasePath,configFile), true);
【讨论】:
这正是我在 .Net 核心控制台应用程序中运行 NLog 所缺少的部分。 loggerFactory.AddNLog();似乎(还没有?)将 NLog 配置为使用应用程序目录中的 nlog.config 文件。 从 NLog.Extensions.Logging 的 1.0.0-rtm-beta1 开始,这应该是不必要的【参考方案4】:现在有关于如何将 NLog 与 ASP.NET Core 一起使用的官方 Wiki 页面:
NLog Wiki - Getting started with ASP.NET Core 6 NLog Wiki - Getting started with ASP.NET Core 5 NLog Wiki - Getting started with ASP.NET Core 3 NLog Wiki - Getting started with ASP.NET Core 2 NLog Wiki - Getting started with ASP.NET Core 1【讨论】:
以上是关于在 ASP.NET Core 应用程序中使用 NLog的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用Autofac替换自带DI进行批量依赖注入(MVC当中应用)
如何使用 EF Core 在 ASP.NET Core 中取消应用迁移
ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用Autofac替换自带DI进行构造函数和属性的批量依赖注入(MVC当中应用)