[EntLib]微软企业库6 日志 RollingFlatFileTraceListener按实际时间命名日志文件名

时间:2021-03-12 05:03:14

关于EntLib的各种构成、原理什么的网上随便找就能找到一大堆相应文章,这里就不细述此部分的相关内容

在使用中,发现RollingFlatFileTraceListener记录下来的日志文件名居然与实际记录的日志Timestamp不一致,比如日志文件内记录的日志是2015-01-20 10:00的,你会发现实际该日志文件的名字为2015-01-20-10:01甚至可能更后(假定设置的RollInterval为Minute,设定的timeStampPattern为yyyyMMddHHmm),因为EntLib的日志库是以日志文件的创建时间来命名的,其实作为日志来说,只要能看懂就可以了,文件名与日志内的Timestamp不一致并不是大问题,只是习惯上可能会有所别扭,但对于某些强迫症患者来说(或者说偏执狂?),总觉得不舒服,既然EntLib开源,那我们完全可以自己做下调整,不是吗?

首先第一步:下载EntLib6的开源代码,你可以在http://www.microsoft.com/en-us/download/details.aspx?id=38789找到源码,源码文件名为EnterpriseLibrary6-source.exe

第二步:执行EnterpriseLibrary6-source.exe解压文件到指定位置,然后打开\Blocks\Logging\Logging.sln

第三步:打开相应的cs文件:Logging—>TraceListeners—>RollingFlatFileTraceListener.Inner.cs

第四步:终于进入正题修改代码了,首先找到第109行的CalculateNextRollDate方法,该方法是根据名字就能知道作用是获取下一次的RollDate,因为原方法只是按rollInterval做了下简单的日期处理,如果要按照真实时间设定日志文件名的话,那这么做肯定是有问题的,因为我们不希望在log201501201000.log中看到2015-01-20-10:01的日志,不是吗?以下是调整代码:按设置的RollInterval最小精度设定NextRollDate

            /// <summary>
            /// Calculates the next roll date for the file.
            /// </summary>
            /// <param name="dateTime">The new date.</param>
            /// <returns>The new date time to use.</returns>
            public DateTime CalculateNextRollDate(DateTime dateTime)
            {
                switch (this.owner.rollInterval)
                {
                    case RollInterval.Minute:
                        return dateTime.Date.AddHours(dateTime.Hour).AddMinutes(dateTime.Minute + 1);
                    case RollInterval.Hour:
                        return dateTime.Date.AddHours(dateTime.Hour + 1);
                    case RollInterval.Day:
                        return dateTime.Date.AddDays(1);
                    case RollInterval.Week:
                        return dateTime.Date.AddDays(7);
                    case RollInterval.Month:
                        return dateTime.Date.AddMonths(1);
                    case RollInterval.Year:
                        return dateTime.Date.AddYears(1);
                    case RollInterval.Midnight:
                        return dateTime.AddDays(1).Date;
                    default:
                        return DateTime.MaxValue;
                }
            }
然后我们还要修正的一个地方就是文件命名了,找到234行的PerformRoll方法,然后该方法内的249行就是获取日志文件名的方法,这里只要把rollDateTime修改为默认Log的CreationTime就可以了,因为在下面的SafeMove方法中,处理完日志文件后,会重新设置默认日志文件的CreationTime
// calculate archive name
string archiveFileName = this.ComputeArchiveFileName(actualFileName, File.GetCreationTime(actualFileName));
好了,至此大功告成,你可以编译成release文件然后供其它程序调用了……

顺带吐槽下patterns & practices小组为啥要设计成RollingFlatFileTraceListener.DateTimeProvider可以继承,该类只包含一个virtual属性CurrentDateTime,该属性确定RollDate,但实际怎么修改都无多大意义!

补充问题:编译后其它程序调用时,这时候用EntLibConfig配置的程序编译无错,运行时却报“程序集清单定义与程序集引用不匹配”错误,需要将声明的Version之类的信息移除,暂时还不知道这个问题应该怎么处理才能使编译成功的dll能够直接引用

再补充:“程序集清单定义与程序集引用不匹配”貌似是强签名导致的,那这个问题就无解了……