本文所提及的三种方式,不是原创,方法都来自互联网,出处不详。
谈到这个开源日志工具,应该大家都耳熟能详,从http://logging.apache.org/log4net/可以下载到它。
在官方提供的关于数据库插入日志的文档中,我们能看到,我们可以在Message中写入各种各样的文本,对于logger.Info(message, exception),如何才能加入自定义的内容呢?如果我们都只是把他们写入Message,将不便于日后查找。举个例子,比如我们对登录有个日志,对退出也有个日志,如何才能区分二者呢,这时候我们希望对我们的Action有个记录,可能就需要一个Action字段。样子可能是:
logger.Info(actionName, message, exception)。
log4net是开源项目,但是文档并不详细,其实网上对这个的研究已经有很多了,也可以很方便搜到,本文就把它们做一个总结放在一起。
其实对于以上类型的日志,只是Log4net项目的一个日志类型,叫做PatternLayout,就是根据配置文件中提到的Pattern进行输出,让我们瞅一眼配置文件(该配置文件来自官方文档http://logging.apache.org/log4net/release/config-examples.html),被指定为PatternLayout的方法,在PatternParser类中被识别,比如有个字符串为“%message%newline --- hello world %date”,PatternParser类的目的就是识别出其中的%message, %newline, %date,具体怎么做到的,请查看PatternParser类。除了%message之外,还有选项(option)的概念,%property{XXX}就是用到了这个特性,也是在PatternParser.ParseInternal中进行演算的。
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender"> <bufferSize value="100" /> <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <connectionString value="data source=[database server];initial catalog=[database name];integrated security=false;persist security info=True;User ID=[user];Password=[password]" /> <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" /> <parameter> <parameterName value="@log_date" /> <dbType value="DateTime" /> <layout type="log4net.Layout.RawTimeStampLayout" /> </parameter> <parameter> <parameterName value="@thread" /> <dbType value="String" /> <size value="255" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%thread" /> </layout> </parameter> <parameter> <parameterName value="@log_level" /> <dbType value="String" /> <size value="50" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%level" /> </layout> </parameter> <parameter> <parameterName value="@logger" /> <dbType value="String" /> <size value="255" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%logger" /> </layout> </parameter> <parameter> <parameterName value="@message" /> <dbType value="String" /> <size value="4000" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%message" /> </layout> </parameter> <parameter> <parameterName value="@exception" /> <dbType value="String" /> <size value="2000" /> <layout type="log4net.Layout.ExceptionLayout" /> </parameter> </appender>
其中layout部分如果是指定PatternLayout的,则是本文所要涉及的重点,比如%message。
方法1,通过log4net提供的ThreadContext,设置属性的值,详见Info1部分。
方法2,通过PatternLayout的AddConvert,增加用于处理扩展部分(系统预制了一些包括%date、%message),此处做了一个通用的XPatternCustomLayout,用来截取%property{XXX}款式的匹配转换,详见Info2部分。
方法3,通过做一个类似PatternLayout的机制来实现,缺点也是比较明显的,需要针对每一个%XXXX做预制,这样的话,如果需要临时再增加,就比较困难了。但该方法有助于理解log4net PatternLayout的机制。
具体的内容就不在这里详述了,代码这玩意儿需要跑跑才清楚。
要运行代码,本文使用了本地数据库(一个随着压缩包提供的数据库文件,sdf,用到System.Data.SqlServerCe4.0,随Microsoft Visual Studio 2010提供),可以更换成SQLServer等标准数据库来使用,注意各配置文件内的描述。
针对方法1、2、3分别提供了配置文件log4net1.xml、log4net2.xml、log4net3.xml,只需要在Web.config文件中对应的字眼修改即可。
另外本地数据库需要指定路径,共4处需要修改,Web.config、log4net1.xml、log4net2.xml、log4net3.xml。
代码下载:
本地下载 SVN(svn checkout http://v-labs.googlecode.com/svn/trunk/log4net v-labs-read-only )