将所有 ASP.NET 核心日志记录重定向到单个 NLog 记录器
Redirect all ASP.NET Core logging into a single NLog logger
我有一个 ASP.NET 项目将其日志发送到 NLog。
但是在这个项目中,我有自己的 NLog 记录器,我想知道如何通过它路由所有日志。
我想我不应该将 NLog 添加为记录器,但我应该找到一种方法来注册一个方法,每次 ASP 尝试记录任何内容时都会调用该方法。
如何实现?
这是创建记录器的代码:
// create the module name
var ProcessName = Process.GetCurrentProcess().ProcessName;
_ModuleName = ProcessName + " (\"" + Oracle.GuessMyName() + "\")";
// create the logger configuration
var Configuration = new LoggingConfiguration();
// create the file target
var FileTarget = new FileTarget ("file")
{
FileName = @"x:\Logs${processname}.log",
ArchiveFileName = @"x:\Logs${processname}.{#}.log",
Layout = @"${longdate}|${logger}|${level}|${message}${onexception:|Exception occurred:${exception:format=tostring}${newline}",
ArchiveEvery = FileArchivePeriod.Day,
ArchiveNumbering = ArchiveNumberingMode.Rolling,
MaxArchiveFiles = 7,
ConcurrentWrites = true
};
Configuration.AddTarget(FileTarget);
// create the viewer target
var ViewerTarget = new NLogViewerTarget ("viewer")
{
Layout = @"${message}${onexception:${newline} --> Exception occurred\:${exception:format=tostring}",
IncludeSourceInfo = true,
IncludeCallSite = true,
Address = @"udp://127.0.0.1:9999"
};
Configuration.AddTarget(ViewerTarget);
// set the rules
Configuration.LoggingRules.Add(new LoggingRule("*", LogLevel.Info, FileTarget));
Configuration.LoggingRules.Add(new LoggingRule("*", LogLevel.Info, ViewerTarget));
// set the configuration
LogManager.Configuration = Configuration;
// create a new logger
_Logger = LogManager.GetLogger(_ModuleName);
这也是 ASP.net 附加到 nlog 的方式:
LoggerFactory.AddNLog();
Application.AddNLogWeb();
现在两个进程的当前日志布局如下所示(每次重新启动进程时,动物名称都会自动更改)
所以两个进程:这里的 shinobi 和 mouserun 都有自己的日志输出,但是任何 ASP 相关的东西都会转到 ASP 的名为 Microsoft 的 nlog 实例,而不管进程如何。
目标是让 shinobi 的 ASP 输出进入 shinobi 记录器,mouserun ASP 输出进入 mouserun 记录器。
您还可以创建自定义目标,并使用 NLog 规则将所有非全局记录器消息重定向到该目标:
https://github.com/nlog/NLog/wiki/Configuration-file#rules
然后自定义目标可以将日志事件转发到全局记录器:
https://github.com/NLog/NLog/wiki/How-to-write-a-custom-target
你应该小心循环日志记录。也许在自定义目标中有一个过滤器来忽略来自全局记录器的消息。
但我认为这是一个丑陋的解决方案,我无法理解只有一个记录器对象的限制。特别是当原因是因为它应该以应用程序命名时。为什么不是名称的全局变量而不是滥用记录器名称?
或者您可以创建一个自定义目标包装器,将记录器固定在 LogEventInfo 上,因此当转发到包装目标(UDP-/文件-目标)时,它们看起来都来自同一个记录器。
类似于此人正在尝试做的事情:
https://github.com/NLog/NLog/issues/2352
又是一个非常难看的解决方案,只应在无法弄清楚时使用,如何避免在所需 Nlog 目标的配置中使用记录器名称(例如,使用某些东西配置文件目标文件名否则)。
查看 NLog.Extensions.Logging 的代码,它在其中注入了自己的自定义日志提供程序。
您也可以这样做,只需包装您的全局记录器对象:
public static ILoggerFactory AddNLog(this ILoggerFactory factory, NLogProviderOptions options)
{
ConfigureHiddenAssemblies();
using (var provider = new NLogLoggerProvider(options))
{
factory.AddProvider(provider);
}
return factory;
}
我有一个 ASP.NET 项目将其日志发送到 NLog。
但是在这个项目中,我有自己的 NLog 记录器,我想知道如何通过它路由所有日志。
我想我不应该将 NLog 添加为记录器,但我应该找到一种方法来注册一个方法,每次 ASP 尝试记录任何内容时都会调用该方法。
如何实现?
这是创建记录器的代码:
// create the module name
var ProcessName = Process.GetCurrentProcess().ProcessName;
_ModuleName = ProcessName + " (\"" + Oracle.GuessMyName() + "\")";
// create the logger configuration
var Configuration = new LoggingConfiguration();
// create the file target
var FileTarget = new FileTarget ("file")
{
FileName = @"x:\Logs${processname}.log",
ArchiveFileName = @"x:\Logs${processname}.{#}.log",
Layout = @"${longdate}|${logger}|${level}|${message}${onexception:|Exception occurred:${exception:format=tostring}${newline}",
ArchiveEvery = FileArchivePeriod.Day,
ArchiveNumbering = ArchiveNumberingMode.Rolling,
MaxArchiveFiles = 7,
ConcurrentWrites = true
};
Configuration.AddTarget(FileTarget);
// create the viewer target
var ViewerTarget = new NLogViewerTarget ("viewer")
{
Layout = @"${message}${onexception:${newline} --> Exception occurred\:${exception:format=tostring}",
IncludeSourceInfo = true,
IncludeCallSite = true,
Address = @"udp://127.0.0.1:9999"
};
Configuration.AddTarget(ViewerTarget);
// set the rules
Configuration.LoggingRules.Add(new LoggingRule("*", LogLevel.Info, FileTarget));
Configuration.LoggingRules.Add(new LoggingRule("*", LogLevel.Info, ViewerTarget));
// set the configuration
LogManager.Configuration = Configuration;
// create a new logger
_Logger = LogManager.GetLogger(_ModuleName);
这也是 ASP.net 附加到 nlog 的方式:
LoggerFactory.AddNLog();
Application.AddNLogWeb();
现在两个进程的当前日志布局如下所示(每次重新启动进程时,动物名称都会自动更改)
所以两个进程:这里的 shinobi 和 mouserun 都有自己的日志输出,但是任何 ASP 相关的东西都会转到 ASP 的名为 Microsoft 的 nlog 实例,而不管进程如何。
目标是让 shinobi 的 ASP 输出进入 shinobi 记录器,mouserun ASP 输出进入 mouserun 记录器。
您还可以创建自定义目标,并使用 NLog 规则将所有非全局记录器消息重定向到该目标:
https://github.com/nlog/NLog/wiki/Configuration-file#rules
然后自定义目标可以将日志事件转发到全局记录器:
https://github.com/NLog/NLog/wiki/How-to-write-a-custom-target
你应该小心循环日志记录。也许在自定义目标中有一个过滤器来忽略来自全局记录器的消息。
但我认为这是一个丑陋的解决方案,我无法理解只有一个记录器对象的限制。特别是当原因是因为它应该以应用程序命名时。为什么不是名称的全局变量而不是滥用记录器名称?
或者您可以创建一个自定义目标包装器,将记录器固定在 LogEventInfo 上,因此当转发到包装目标(UDP-/文件-目标)时,它们看起来都来自同一个记录器。
类似于此人正在尝试做的事情:
https://github.com/NLog/NLog/issues/2352
又是一个非常难看的解决方案,只应在无法弄清楚时使用,如何避免在所需 Nlog 目标的配置中使用记录器名称(例如,使用某些东西配置文件目标文件名否则)。
查看 NLog.Extensions.Logging 的代码,它在其中注入了自己的自定义日志提供程序。
您也可以这样做,只需包装您的全局记录器对象:
public static ILoggerFactory AddNLog(this ILoggerFactory factory, NLogProviderOptions options)
{
ConfigureHiddenAssemblies();
using (var provider = new NLogLoggerProvider(options))
{
factory.AddProvider(provider);
}
return factory;
}