1

有没有办法让 log4net 通过程序中的某些条件更改预期日志的目标位置,而无需更新和重新部署 xml 配置?

我不想要任何依赖于配置的解决方案。它应该纯粹通过代码工作。我有一定的条件,我可以根据这些条件告诉我的程序选择哪个目标。在某些情况下,程序将自动在预定义路径上的文本文件或预定义服务器/数据库上的 SQL Server 或我的应用程序套件名称下的事件日志之间切换。文件路径、sql 连接字符串和事件日志参数将是唯一存储在我的应用程序配置文件中的内容。

这在 log4net 上是否可行?我找不到与我搜索的内容相关的任何内容,因此我还没有可以显示的任何代码。大多数答案都是关于如何更改默认目录位置,但这不是我想要的。

谢谢

4

2 回答 2

2

我知道您谈到仅在代码中更改您的附加程序,但我真的认为您会通过使用根据代码中设置的上下文属性选择的附加程序来获得更多好处

一个例子是在你的配置文件中做这样的事情:

<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender,log4net">

  <filter type="log4net.Filter.PropertyFilter">
    <key value="target" />
    <stringToMatch value="DB" />
    <acceptOnMatch value="true" />
  </filter>
  <filter type="log4net.Filter.DenyAllFilter" />

<!-- your ado configuration -->


<appender name="AnotherAppender" type="log4net.Appender.EventLogAppender,log4net">

  <filter type="log4net.Filter.PropertyFilter">
    <key value="target" />
    <stringToMatch value="EventLog" />
    <acceptOnMatch value="true" />
  </filter>
  <filter type="log4net.Filter.DenyAllFilter" />

<!-- your Eventlog configuration -->

然后在您的代码中,您可以将 loggertarget属性设置为您想要的目标:

var isDB = true;
var loggingEvent = new LoggingEvent(typeof(Program), Log.Logger.Repository, Log.Logger.Name, Level.Info, "message", null);
loggingEvent.Properties["target"] = isDB ? "DB" : "EventLog";
Log.Logger.Log(loggingEvent);

这样,您的代码中就不会隐藏神奇的日志输出,输出是通过配置驱动的,因此您可以轻松更改它,并且路由是您在应用程序中唯一需要处理的事情。

如果您不需要每条消息的上下文(例如,您知道一旦记录路由更改,它不会再次切换很长时间),您可以使用可以全局设置的其他三个上下文之一:

  • log4net.GlobalContext用于应用程序中的所有记录器
  • log4net.ThreadContext在同一线程中的记录器之间共享
  • log4net.ThreadLogicalContext 在线程的相同逻辑边界中的记录器之间共享(有关差异的更多信息
于 2014-07-15T08:44:20.903 回答
0

可以以编程方式切换每个附加程序的日志记录。您可以根据定义的条件控制日志记录阈值。

例如,这是一些代码,它切换名称以“Audit”为前缀的附加程序。

        private static void ToggleAuditing(bool enabled)
    {
        log4net.Appender.IAppender[] appenders = log4net.LogManager.GetRepository().GetAppenders();

        foreach (log4net.Appender.IAppender app in appenders)
        {
            log4net.Appender.AppenderSkeleton skel = app as log4net.Appender.AppenderSkeleton;

            if (skel != null && app.Name.StartsWith("Audit"))
            {
                skel.Threshold = enabled ? Level.All : Level.Off;
            }
        }
    }
于 2014-07-14T17:22:05.750 回答