2013-10-22 15:07
3147人阅读
收藏
举报
分类:
版权声明:本文为博主原创文章,未经博主允许不得转载。
log4net可以轻易的将信息日志写入文本,但是无论记录在哪里终究还是为了后期发现问题,维护所用。所以为了查询方便,可以将其配置输出至数据库(Oracle)。
一、插入系统默认字段
首先建库,sql如下:
[sql]
view plain
copy
print
?
-
- createtableSYSTEMLOG
- (
- log_idNUMBERnotnull,
- log_dateDATE,
- log_levelVARCHAR2(255),
- log_identityVARCHAR2(255),
- log_messageVARCHAR2(4000),255); color:inherit; line-height:20px; font-size:18px; list-style-position:outside!important"> log_exceptionVARCHAR2(4000),92); line-height:20px; font-size:18px; list-style-position:outside!important"> log_loggerVARCHAR2(255),255); color:inherit; line-height:20px; font-size:18px; list-style-position:outside!important"> log_sourceVARCHAR2(1000),)
- sequenceSYSTEMLOG_SEQ
- minvalue1
- maxvalue999999999
- startwith8061
- incrementby1
- cache20;
以上所有字段(除了log_id)均为系统字段,字段的定义可以看配置文件,如下:
[html]
copy
?
<?xmlversion="1.0"encoding="utf-8"?>
- <configuration>
- log4net
>
configSectionssectionname="log4net"type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
</appendername="ADONetAppender"type="log4net.Appender.ADONetAppender"bufferSizevalue="1"/>
connectionTypevalue="Oracle.DataAccess.Client.OracleConnection,Oracle.DataAccess,Version=2.111.7.20,Culture=neutral,PublicKeyToken=89b483f429c47342"connectionStringvalue="DataSource=//59.74.137.215:1521/GSGLAQYJ;UserID=GSGLAQYJ;Password=GSGLAQYJ;"commandTextvalue="INSERTINTOLOG4NET(LOG_ID,LOG_DATE,LOG_LEVEL,LOG_IDENTITY,LOG_MESSAGE,LOG_EXCEPTION,LOG_LOGGER,LOG_SOURCE)VALUES(LOG4NET_SEQ.nextval,:log_date,:log_level,:log_identity,:log_message,:log_exception,:logger,:source)"parameterparameterNamevalue=":log_date"dbTypevalue="DateTime"layouttype="log4net.Layout.RawTimeStampLayout"layoutparameterNamevalue=":log_level"dbTypevalue="String"sizevalue="10"layouttype="log4net.Layout.PatternLayout"conversionPatternvalue="%level"parameterNamevalue=":log_identity"sizevalue="100"conversionPatternvalue="%identity"parameterNamevalue=":log_message"sizevalue="4000"conversionPatternvalue="%m"parameterNamevalue=":log_exception"conversionPatternvalue="%exception"parameterNamevalue=":logger"sizevalue="255"conversionPatternvalue="%logger"parameterNamevalue=":source"sizevalue="1000"conversionPatternvalue="%file:%line"appenderappendername="InfoAppender"type="log4net.Appender.RollingFileAppender"paramname="File"value="LogLogInfo"paramname="AppendToFile"value="true"paramname="MaxFileSize"value="10240"paramname="MaxSizeRollBackups"value="100"paramname="StaticLogFileName"value="false"paramname="DatePattern"value="yyyyMMdd".log""paramname="RollingStyle"value="Date"paramname="ConversionPattern"value="%n日志时间:%d[%t]%n日志级别:%-5p%n日志类:%c[%x]%n%m%n"
<!--loggername="loginfo"levelvalue="INFO"appender-refref="InfoAppender"logger>--rootlevelvalue="All"appender-refref="ADONetAppender">
以上配置文件最主要的就是一下几行:
copy
connectionStringvalue="DataSource=//xx.xx.xx.xx:1521/xxx;UserID=xxx;Password=xxx;"commandTextvalue="INSERTINTO
YSTEMLOG(LOG_ID,:source)"/>
1.Oracle.DataAccess.dll
就好比你自己写sql语句一样,无论那种数据库都得引一个XXXclient的库,后面的公钥要写对,查询一个dll的公开密钥可以先打开vs的命令工具,将dll放入命令工具的当前目录下,然后输入SN -T 回车即可获得公钥.
2.Oracle.DataAccess.Client.OracleConnection
这个就不用说了,肯定是连接数据库的字符串,网上好多格式都不对,这里我贴出了详细的格式
copy
/>
3.插入语句
copy
prename="code"class="html"> SYSTEMLOG(LOG_ID,LOG_SOURCE)VALUES
(LOG4NET_SEQ.nextval,0); margin:0px; padding:0px; border:none; background-color:inherit; font-weight:bold">/>pre>
一定要注意变量的个数要一致,oracle变量默认以冒号开头。 4.其他配置
其他配置与写入文件的配置一样,可以参考上一篇,没有特别提出的都是在上篇的配置基础上继续进行的。
最后,调用代码如下:
[csharp]
copy
?
classProgram
- {
- private
staticILoglog=LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
staticvoidMain(string[]args)
log.Info("我");
log.Warn("你");
log.Debug("他");
log.Error("她");
log.Fatal("它");
Console.ReadLine();
}
}
结果如下图:
注意事项:
项目需要log4net.dll,和其对应的.config和xml文件,并且需要引入上面的Oracle.DataAccess.dll,若没有oracle客户端,则就需要将pl/sql中的几个必备库拷贝至debug目录才能执行成功。所需库文件已上传http://download.csdn.net/detail/kkkkkxiaofei/6436383
二、插入自定义字段
sql如下:
copy
loginidVARCHAR2(100),255); color:inherit; line-height:20px; font-size:18px; list-style-position:outside!important"> loginnameVARCHAR2(100),92); line-height:20px; font-size:18px; list-style-position:outside!important"> menunameVARCHAR2(100),255); color:inherit; line-height:20px; font-size:18px; list-style-position:outside!important"> actionnameVARCHAR2(100),92); line-height:20px; font-size:18px; list-style-position:outside!important"> remarkVARCHAR2(1000),255); color:inherit; line-height:20px; font-size:18px; list-style-position:outside!important"> terminalnoVARCHAR2(30),92); line-height:20px; font-size:18px; list-style-position:outside!important"> ordernoVARCHAR2(10)
)
sequenceSYSTEMLOG_SEQ
minvalue1
maxvalue999999999
startwith8061
incrementby1
cache20;
插入自定义字段需要继承log4net里的基类,先看配置文件
copy
sectionname="log4net"type="System.Configuration.IgnoreSectionHandler,0); background-color:inherit; font-weight:bold">loggername="RollingLogFileAppender"levelvalue="ALL"appender-refref="RollingLogFileAppender"loggername="AdoNetAppender_Oracle"appender-refref="AdoNetAppender_Oracle"loggername="WarningDatail_Oracle"appender-refref="WarningDatail_Oracle"appendername="RollingLogFileAppender"type="log4net.Appender.RollingFileAppender"
filevalue="./GSGLAQYJLOG/ExecuteInfo.log"<!--是否覆盖,默认是追加true-->
appendToFilevalue="true"<!--按照文件的大小进行变换日志文件-->
rollingStylevalue="Size" <!--按照日期变换文件名称
rollingStylevalue="Date"datePatternvalue="yyyyMMdd-HHmm'.log'" --<!--设置无限备份=-1,最大备份数为1000-->
maxSizeRollBackupsvalue="-1"<!--每个文件的最大2M-->
maximumFileSizevalue="2MB"<!--日志文件名是否为静态-->
staticLogFileNamevalue="false"<!--输出文件格式-->
conversionPatternvalue="%d[%t]%-5p%c[%x]-%m[%r]%n" <!--輸出文件格式説明:
%d输出当前语句运行的时刻
%t当前语句所在的线程
%-数字:表示该项的最小长度,如果不够,则用空格填充
%p日志的当前优先级别,即DEBUG、INFO<、WARN…等
%m输出的日志消息,如ILog.Debug(…)>输出的一条消息
%n换行
%r咝械臅r間
%c当前日志对象的名称
<!--Log4net多线程写入-->
lockingModeltype="log4net.Appender.FileAppender+MinimalLock"<!--日志记录数据库-->
appendername="AdoNetAppender_Oracle"type="log4net.Appender.AdoNetAppender"bufferSizevalue="1"
connectionStringvalue="DATASOURCE=//59.74.137.215:1521/GSGLAQYJ;USERID=GSGLAQYJ;PASSWORD=GSGLAQYJ"<!--<commandTextvalue="INSERTINTOLOG4NET(LOG_ID,:source)"/>-->
commandTextvalue="INSERTINTOSYSTEMLOG(LOG_ID,LOG_SOURCE,LOGINID,LOGINNAME,MENUNAME,ACTIONNAME,REMARK)VALUES
(SYSTEMLOG_SEQ.nextval,:source,:LoginID,:LoginName,:MenuName,:ActionName,:Remark)"layouttype="log4net.Layout.RawTimeStampLayout"<!--自定义属性-->
parameterNamevalue=":LoginID"layouttype="Log4netHandler.CustomLayout"conversionPatternvalue="%LoginID"parameterNamevalue=":LoginName"conversionPatternvalue="%LoginName"parameterNamevalue=":MenuName"conversionPatternvalue="%MenuName"parameterNamevalue=":ActionName"conversionPatternvalue="%ActionName"parameterNamevalue=":Remark"conversionPatternvalue="%Remark"appendername="WarningDatail_Oracle"type="log4net.Appender.AdoNetAppender"commandTextvalue="INSERTINTOSYSTEMLOG(LOG_ID,TERMINALNO,ORDERNO)VALUES(SYSTEMLOG_SEQ.nextval,:terminalno,:orderno)"<!--自定义属性:-->
parameterNamevalue=":terminalno"sizevalue="30"conversionPatternvalue="%TerminalNo"parameterNamevalue=":orderno"conversionPatternvalue="%OrderNo">
配置文件定义了三个节点
copy
>
每一个logger就相当一个root(上面插入系统字段时用的是root,两者都行),一个logger对应一个appender,分别是:
写入文本的节点:
copy
>
写入数据库的字段(一部分自定义字段):
copy
>
写入数据库的字段(另一部分自定义字段)
copy
>
其中自定义字段分两个节点是因为最后一个节点是在warn级别时才记录入库,而前者在info级别就入库了,这么做有利于分开处理。到时候插入库的时候也会发现插入前者时后者为空,而插入后者时前者也为空。
自定义节点如下:
copy
<!--自定义属性:-->
>
以第一个节点为例,插入时的变量为:terminalno,在重写的类里,该变量是做为属性TerminalNo出现的,其实就是将类里的TerminalNo利用反射转换为oracle所能识别的变量:terminalno
代码如下:
1.实现该属性的类
copy
internalsealedclassTerminalNo:PatternLayoutConverter
//Methods
protectedoverridevoidConvert(TextWriterwriter,LoggingEventloggingEvent)
{
LogContentcontent=loggingEvent.MessageObjectasLogContent;
if(content!=null)
writer.Write(content.TerminalNo);
}
}
其他几个变量一样,都需要继承PatterLayoutConverter
2.反射
copy
copy
namespaceLog4netHandler
publicclassCustomLayout:PatternLayout
publicCustomLayout()
base.AddConverter("TerminalNo",typeof(TerminalNo));
}
再看上面自定义属性时的配置文件,里面有一行
copy
>
这时看到这个类想必就应该有所领悟了吧.
3.封装节点
copy
classOperaterLog
//Fields
staticILoglogfile;
staticILoglogoracle;
staticILoglogwaring;
//Methods
staticILogLogin2File()
return(logfile=LogManager.GetLogger("文件节点"));
staticILogLogin2Oracle()
return(logoracle=LogManager.GetLogger("数据库节点1"));
staticILogLoginWarning()
return(logwaring=LogManager.GetLogger("数据库节点2"));
}
4.调用
copy
Log4netHandler.LogContentmsg=newLog4netHandler.LogContent();
msg.LoginID="OutSocket_LoginID";
msg.LoginName="OutSocket_LoginName";
msg.MenuName="OutSocket_MenuName";
msg.ActionName="OutSocket_ActionName";
msg.Remark="12312";
msg.TerminalNo="空123";
msg.OrderNo="空2323";
Log4netHandler.OperaterLog.Login2Oracle().Info(msg);
Log4netHandler.OperaterLog.Login2File().Info("12312");
Log4netHandler.OperaterLog.LoginWarning().Info(msg);
Console.Read();
}
5.结果如下
如上面所说,插入第一部分自定义字段时后面两个为空,插入后面两个时前面也为空,这些都取决于封装的时候读取的节点。最后要说明一下,整个调试过程十分恶心,无论是出现任何错误,用Log4Net调用oracle时都不报错,所以必须十分小心,记得把项目类型换成.net 4,不然会吐血的。再次吐槽CSDN的排版,蛋疼。。 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|