代码之家  ›  专栏  ›  技术社区  ›  Alberto Chiesa

强制Log4Net输出特定事件

  •  0
  • Alberto Chiesa  · 技术社区  · 2 年前

    我在应用程序中使用log4net进行诊断日志记录,也就是说,如果log4net不工作,应用程序仍然可以正常运行。 我有一个单独的审计跟踪日志,如果审计跟踪失败,它将阻止应用程序。

    我想在我的log4net日志中包含审计跟踪消息,但我有一个难题:我希望审计跟踪消息以最高优先级(类似于临界)输出,但我不希望审计跟踪消息被表示为致命错误。
    它们应该以信息级别发出,因为它们不是关键错误,只是强制性消息。

    我在查看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);
    }
    

    我可以通过反射调用这个方法,绕过任何级别检查,但我感到非常内疚。

    有没有“更清洁”的替代品?

    0 回复  |  直到 2 年前
        1
  •  2
  •   pfx    2 年前

    您可以设置一个命名的记录器,例如。 AuditLog 中有或没有显式配置 log4net 设置。
    默认情况下,此记录器将从根记录器或配置的记录器继承日志级别。

    就在你申请 log4net 配置时,您可以使用所需的(最低)日志级别配置/否决特定记录器。

    应用配置,例如从文件中应用。

    var repository = log4net.LogManager.GetRepository(Assembly.GetExecutingAssembly());
    log4net.Config.XmlConfigurator.Configure(repository, new FileInfo("log4net.config"));
    

    完成上述配置后,立即更改 审计日志 以编程方式记录日志,例如 Info .

    var auditLog = repository.GetLogger("AuditLog") as Logger;
    auditLog.Level = log4net.Core.Level.Info;
    

    当您通过此登录时,应用程序中的任何位置 审计日志 记录器,其编程设置级别将被考虑。以下记录信息性消息的调用将在完成 信息 已设置的日志级别。

    var auditLog = LogManager.GetLogger("AuditLog");
    auditLog.Info("Hello audit trail log!");
    

    举个例子。
    给定以下配置,其中日志级别为 Off 这个 审计日志 记录器仍将登录到已配置的 FileAppender .
    任何其他伐木工人都不会,因为 背景

    <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>
    
        2
  •  0
  •   Alberto Chiesa    2 年前

    多亏了@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);
    

    甜蜜而简单!