log4net动态创建不同名称的日志时遇到的问题

问题:原本是通过配置文件设置Appender的<file>节点的值value="Logs\%property{xxx}\"对日志按照xxx变量分类,然后发现运行时在第一次生成后,后续无论怎么更改xxx,后面的日志都生成在第一次生成的日志内。

原因:在经历大量网上冲浪和面向AI编程后,发现原因是Appender初始化时已绑定最终路径,即log4net的Appender在首次初始化(ActivateOptions执行时)会对<file>节点的占位符(包括%property{xxx})进行一次性解析和替换,生成固定的物理日志路径并缓存。后续即使修改了xxx属性的值,由于 Appender 不会主动重新解析<file>节点,也不会刷新已缓存的日志路径,因此新的属性值无法生效,日志仍会输出到最初解析的路径中。

解决:个人解决方法是选择通过代码动态生成Appender

//logger缓存字典
private static Dictionary<string, ILog> _LoggerList = new Dictionary<string, ILog>();
//根据变量名称获取logger
private static ILog GetLoggerByName(string varName)
{
    if (!_LoggerList.ContainsKey(varName))
    {
        //目标logger不存在则生成
        _LoggerList[varName] = CreateDynamicLog(varName);
    }
    return _LoggerList[varName];
}

//动态创建logger
private static ILog CreateDynamicLog(string varName)
{
    ILog logger = LogManager.GetLogger(varName);
    var hierarchyLogger = (logger.Logger as Logger);

    var fileAppender = new RollingFileAppender
    {
        //动态生成Appender名称
        Name = $"{varName}Appender",
        //动态生成file路径
        File = $"Logs/{varName}/",
        DatePattern = "yyyyMMdd'.log'",
        AppendToFile = true,
        //混合滚动(日期+大小)
        RollingStyle = RollingFileAppender.RollingMode.Composite,
        //使用动态文件名
        StaticLogFileName = false,
        MaxSizeRollBackups = 30,
        MaximumFileSize = "10MB",
        Encoding = System.Text.Encoding.UTF8,
        LockingModel = new FileAppender.MinimalLock(),
        Layout = new PatternLayout("%date %n%message %n%exception %n")
    };
    //激活Appender配置
    fileAppender.ActivateOptions();
    //绑定Appender并刷新配置
    hierarchyLogger.AddAppender(fileAppender);
    LogManager.GetRepository().ConfigurationChanged += (s, e) => { };
    hierarchyLogger.Repository.Configured = true;

    return logger;
}

运行时发现生成的日志内容均为空,原因是未设置Logger级别。在创建logger方法中补上语句

    //显式设置Logger级别为All
    hierarchyLogger.Level = log4net.Core.Level.All;

运行后发现能正常生成日志了,但是又遇到新的问题:每次生成新的logger并写入日志时,缓存字典中存在的logger也会一起写入同样的内容。查阅资(dou)料(bao)后发现是没有禁用累加性(Additivity,又称 “日志传递性”),简单来说:如果启用累加性,一条日志会同时输出到当前 Logger 的 Appender 和所有父 Logger 的 Appender。解决方法很简单,在创建logger方法中再补上语句

    //禁用累加性
    hierarchyLogger.Additivity = false;

再次运行,日志不会重复写入其他文件了,成功达到预期效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值