强制 Log4Net 输出特定事件
Force Log4Net to output specific events
我在我的应用程序中使用 log4net 进行诊断日志记录,也就是说,如果 log4net 不起作用,应用程序仍然可以正常运行。
我有一个单独的审计跟踪日志,如果审计跟踪失败,它将阻止应用程序。
我想在我的 log4net 日志中包含 Audit Trail 消息,但我有一个难题:我希望 AuditTrail 消息以最高优先级(Critical 类)输出,但我不想要审计跟踪消息表示为致命错误。
它们应该以 INFO 级别发出,因为它们不是严重错误,而只是强制性消息。
我正在研究 log4net 的内部结构,偶然发现了受保护的 Logger.Forcedlog
方法:
/// <summary>
/// Creates a new logging event and logs the event without further checks.
/// </summary>
/// <param name="logEvent">The event being logged.</param>
/// <remarks>
/// <para>
/// Delivers the logging event to the attached appenders.
/// </para>
/// </remarks>
protected virtual void ForcedLog(LoggingEvent logEvent)
{
logEvent.EnsureRepository((ILoggerRepository) this.Hierarchy);
this.CallAppenders(logEvent);
}
我可以通过反射调用此方法并绕过任何级别检查,但我感到非常内疚。
是否有任何“更清洁”的替代品?
您可以设置命名记录器,例如AuditLog
,在 log4net
设置中有或没有显式配置。
默认情况下,此记录器将从根记录器或配置的记录器继承日志级别。
在您应用 log4net
配置之后,您 configure/overrule 具有您需要的(最低)日志级别的特定记录器。
您应用配置,例如来自文件。
var repository = log4net.LogManager.GetRepository(Assembly.GetExecutingAssembly());
log4net.Config.XmlConfigurator.Configure(repository, new FileInfo("log4net.config"));
在上述配置之后,您可以立即以编程方式更改 AuditLog
记录器的日志级别,例如至 Info
.
var auditLog = repository.GetLogger("AuditLog") as Logger;
auditLog.Level = log4net.Core.Level.Info;
当您通过此 AuditLog
记录器登录时,您应用程序中的任何地方都会考虑其编程设置的级别。以下记录信息性消息的调用将通过,因为它满足已设置的 Info
日志级别。
var auditLog = LogManager.GetLogger("AuditLog");
auditLog.Info("Hello audit trail log!");
一个例子。
鉴于下面的配置,日志级别为 Off
,AuditLog
记录器仍将记录到配置的 FileAppender
.
由于 Off
设置,任何其他记录器都不会。
<log4net>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="log-file.txt" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger %message%newline" />
</layout>
</appender>
<root>
<level value="Off" />
<appender-ref ref="FileAppender" />
</root>
</log4net>
感谢@pfx 的想法,最终对我有用的实际上是声明自定义日志级别。
鉴于这不完全是我的要求,我奖励 pfx 的答案,但我在这里报告我的解决方案以防它可以帮助其他人:
// declares a custom Log4Net Level named Audit with the same priority of Fatal errors
private static readonly Level AuditTrailLevel = new Level(Level.Fatal.Value, "AUDIT");
// to be used as:
_log.Logger.Log(null, AuditTrailLevel, message, exception);
甜蜜而简单!
我在我的应用程序中使用 log4net 进行诊断日志记录,也就是说,如果 log4net 不起作用,应用程序仍然可以正常运行。 我有一个单独的审计跟踪日志,如果审计跟踪失败,它将阻止应用程序。
我想在我的 log4net 日志中包含 Audit Trail 消息,但我有一个难题:我希望 AuditTrail 消息以最高优先级(Critical 类)输出,但我不想要审计跟踪消息表示为致命错误。
它们应该以 INFO 级别发出,因为它们不是严重错误,而只是强制性消息。
我正在研究 log4net 的内部结构,偶然发现了受保护的 Logger.Forcedlog
方法:
/// <summary>
/// Creates a new logging event and logs the event without further checks.
/// </summary>
/// <param name="logEvent">The event being logged.</param>
/// <remarks>
/// <para>
/// Delivers the logging event to the attached appenders.
/// </para>
/// </remarks>
protected virtual void ForcedLog(LoggingEvent logEvent)
{
logEvent.EnsureRepository((ILoggerRepository) this.Hierarchy);
this.CallAppenders(logEvent);
}
我可以通过反射调用此方法并绕过任何级别检查,但我感到非常内疚。
是否有任何“更清洁”的替代品?
您可以设置命名记录器,例如AuditLog
,在 log4net
设置中有或没有显式配置。
默认情况下,此记录器将从根记录器或配置的记录器继承日志级别。
在您应用 log4net
配置之后,您 configure/overrule 具有您需要的(最低)日志级别的特定记录器。
您应用配置,例如来自文件。
var repository = log4net.LogManager.GetRepository(Assembly.GetExecutingAssembly());
log4net.Config.XmlConfigurator.Configure(repository, new FileInfo("log4net.config"));
在上述配置之后,您可以立即以编程方式更改 AuditLog
记录器的日志级别,例如至 Info
.
var auditLog = repository.GetLogger("AuditLog") as Logger;
auditLog.Level = log4net.Core.Level.Info;
当您通过此 AuditLog
记录器登录时,您应用程序中的任何地方都会考虑其编程设置的级别。以下记录信息性消息的调用将通过,因为它满足已设置的 Info
日志级别。
var auditLog = LogManager.GetLogger("AuditLog");
auditLog.Info("Hello audit trail log!");
一个例子。
鉴于下面的配置,日志级别为 Off
,AuditLog
记录器仍将记录到配置的 FileAppender
.
由于 Off
设置,任何其他记录器都不会。
<log4net>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="log-file.txt" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger %message%newline" />
</layout>
</appender>
<root>
<level value="Off" />
<appender-ref ref="FileAppender" />
</root>
</log4net>
感谢@pfx 的想法,最终对我有用的实际上是声明自定义日志级别。
鉴于这不完全是我的要求,我奖励 pfx 的答案,但我在这里报告我的解决方案以防它可以帮助其他人:
// declares a custom Log4Net Level named Audit with the same priority of Fatal errors
private static readonly Level AuditTrailLevel = new Level(Level.Fatal.Value, "AUDIT");
// to be used as:
_log.Logger.Log(null, AuditTrailLevel, message, exception);
甜蜜而简单!