有没有办法让log4net通过程序中的某些条件更改目标日志的目标位置,而无需更新和重新部署xml配置?
我不想要任何配置相关的解决方案。它应该纯粹通过代码工作。我有一定的条件,我可以告诉我的程序选择哪个目标。在某些情况下,程序将自动在预定义路径上的文本文件或预定义服务器/数据库上的SQL Server或应用程序套件名称下的事件日志之间切换。文件路径,sql连接字符串和事件日志参数将是我的应用程序配置文件中唯一存储的内容。
这在log4net上是否可行?我找不到与搜索内容有关的任何内容,所以我没有任何代码可以显示。大多数答案都是关于如何更改默认目录位置,但这不是我想要的。
由于
答案 0 :(得分:2)
我知道你曾谈到只在代码中更改你的appender,但我真的认为你可以通过使用根据代码中设置的上下文属性选择的appender获益更多
一个例子是在配置文件中执行类似的操作:
<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 -->
然后在您的代码中,您可以将记录器target
属性设置为您想要的目标:
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在线程的相同逻辑边界中的记录器之间共享(more info on the difference)答案 1 :(得分:0)
可以以编程方式切换每个appender的日志记录。您可以根据您定义的条件控制记录阈值。
例如,这是一些切换名称前缀为“Audit”的appender的代码。
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;
}
}
}