关于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能够直接引用
再补充:“程序集清单定义与程序集引用不匹配”貌似是强签名导致的,那这个问题就无解了……