log4net封装扩展后不能在.NET Framework 4.0下正常运行
简单对log4net做了一下封装,并使用ILMerge进行程序集合并。
解决方案是.NET Framework 4.0,开发环境Win10 .NET Framework 4.8。
4.0的项目生成后在4.0环境下不能正常运行。
1、自定义了一个Layout使用Properties来实现扩展输出日志分类和标题
因使用了 loggingEvent.LookupProperty(key)方法,在.NET Framework 4.0环境下运行异常
.NET Framework 4使用 loggingEvent.Properties[key] 时正常
namespace SharpCode.Utils.Log4net { public class CustomLayout : PatternLayout { public CustomLayout() { this.AddConverter("Catalog", typeof(CatalogPatternConverter)); this.AddConverter("Title", typeof(TitlePatternConverter)); } } public class TitlePatternConverter : PatternLayoutConverter { protected override void Convert(System.IO.TextWriter writer, log4net.Core.LoggingEvent loggingEvent) { //loggingEvent.LookupProperty("Title") var title = loggingEvent.Properties["Title"] == null ? "无标题" : loggingEvent.Properties["Title"]; WriteObject(writer, loggingEvent.Repository, title); } } public class CatalogPatternConverter : PatternLayoutConverter { //loggingEvent.LookupProperty("Catalog") protected override void Convert(System.IO.TextWriter writer, log4net.Core.LoggingEvent loggingEvent) { var catalog = loggingEvent.Properties["Catalog"] == null ? "未分类" : loggingEvent.Properties["Catalog"]; WriteObject(writer, loggingEvent.Repository, catalog); } } }
在过滤器设置过程中存在同样的问题
按Catalog属性来区分存放WIN_UI和WEB_SERVICE日志时,过滤器设置如下
<filter type="log4net.Filter.LevelRangeFilter"> <LevelMin value="DEBUG"/> <LevelMax value="FATAL"/> <acceptOnMatch value="false" /> </filter> <filter type="log4net.Filter.PropertyFilter"> <key value="Catalog" /> <regexToMatch value="^WIN_UI" /> </filter> <filter type="log4net.Filter.DenyAllFilter"/> ---------------------------------------------------------- <filter type="log4net.Filter.LevelRangeFilter"> <LevelMin value="DEBUG"/> <LevelMax value="FATAL"/> <acceptOnMatch value="false" /> </filter> <filter type="log4net.Filter.PropertyFilter"> <key value="Catalog" /> <regexToMatch value="^WEB_SERVICE" /> </filter> <filter type="log4net.Filter.DenyAllFilter"/>
log4net.Filter.PropertyFilter 在.NET Framework 4.0下不工作
查看log4net.Filter.PropertyFilter的源代码部分
public override FilterDecision Decide(LoggingEvent loggingEvent) { if (loggingEvent == null) { throw new ArgumentNullException("loggingEvent"); } if (m_key == null) { return FilterDecision.Neutral; } object obj = loggingEvent.LookupProperty(m_key); string text = loggingEvent.Repository.RendererMap.FindAndRender(obj); if (text == null || (m_stringToMatch == null && m_regexToMatch == null)) { return FilterDecision.Neutral; } if (m_regexToMatch != null) { if (!m_regexToMatch.Match(text).Success) { return FilterDecision.Neutral; } if (m_acceptOnMatch) { return FilterDecision.Accept; } return FilterDecision.Deny; } if (m_stringToMatch != null) { if (text.IndexOf(m_stringToMatch) == -1) { return FilterDecision.Neutral; } if (m_acceptOnMatch) { return FilterDecision.Accept; } return FilterDecision.Deny; } return FilterDecision.Neutral; }
标红的部分不工作,可以按源代码自己写一个PropertyFilter替换掉其中的loggingEvent.LookupProperty(m_key)为loggingEvent.Properties[m_key]
再给过滤器中的类型改为自己写的PropertyFilter
针对loggingEvent.LookupProperty()方法的问题,可以自行下载源码重新用net4+2005编译生成一个纯4.0的版本。
2、4.0项目中nuget的ILMerge 3.0.29包能装上,是net452的。
应该使用2.14.1208版本的包中的ILMerge.exe做为合并工具
可以用反编译工具查看程序集的TargetFramework,确认使用正确的版本
如 [assembly: TargetFramework(".NETFramework,Version=v4.0", FrameworkDisplayName = ".NET Framework 4")]
应当在最高只有.NET Framework 4的环境下合并程序集,生成的文件才能在.NET Framework 4.0下运行,否则mscorlib会报引用异常。