版权声明:本文为博主原创文章,未经博主允许不得转载。
log4net可以轻易的将信息日志写入文本,但是无论记录在哪里终究还是为了后期发现问题,维护所用。所以为了查询方便,可以将其配置输出至数据库(Oracle)。
一、插入系统默认字段
首先建库,sql如下:
- -- Create table
- create table SYSTEMLOG
- (
- log_id NUMBER not null,
- log_date DATE,
- log_level VARCHAR2(255),
- log_identity VARCHAR2(255),
- log_message VARCHAR2(4000),
- log_exception VARCHAR2(4000),
- log_logger VARCHAR2(255),
- log_source VARCHAR2(1000), ) -- Create sequence
- create sequence SYSTEMLOG_SEQ
- minvalue 1
- maxvalue 999999999
- start with 8061
- increment by 1
- cache 20;
- <?xml version="1.0" encoding="utf-8" ?>
- <configuration>
- <log4net>
- <configSections>
- <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
- </configSections>
- <appender name="ADONetAppender" type="log4net.Appender.ADONetAppender">
- <bufferSize value="1" />
- <connectionType value="Oracle.DataAccess.Client.OracleConnection, Oracle.DataAccess, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342" />
- <connectionString value="Data Source=//59.74.137.215:1521/GSGLAQYJ;User ID=GSGLAQYJ;Password=GSGLAQYJ;" />
- <commandText value="INSERT INTO LOG4NET (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)" />
- <parameter>
- <parameterName value=":log_date" />
- <dbType value="DateTime" />
- <layout type="log4net.Layout.RawTimeStampLayout">
- </layout>
- </parameter>
- <parameter>
- <parameterName value=":log_level" />
- <dbType value="String" />
- <size value="10" />
- <layout type="log4net.Layout.PatternLayout">
- <conversionPattern value="%level" />
- </layout>
- </parameter>
- <parameter>
- <parameterName value=":log_identity" />
- <dbType value="String" />
- <size value="100" />
- <layout type="log4net.Layout.PatternLayout">
- <conversionPattern value="%identity" />
- </layout>
- </parameter>
- <parameter>
- <parameterName value=":log_message" />
- <dbType value="String" />
- <size value="4000" />
- <layout type="log4net.Layout.PatternLayout">
- <conversionPattern value="%m" />
- </layout>
- </parameter>
- <parameter>
- <parameterName value=":log_exception" />
- <dbType value="String" />
- <size value="4000" />
- <layout type="log4net.Layout.PatternLayout">
- <conversionPattern value="%exception" />
- </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=":source" />
- <dbType value="String" />
- <size value="1000" />
- <layout type="log4net.Layout.PatternLayout">
- <conversionPattern value="%file:%line" />
- </layout>
- </parameter>
- </appender>
- <appender name="InfoAppender" type="log4net.Appender.RollingFileAppender">
- <param name="File" value="Log\\LogInfo\\" />
- <param name="AppendToFile" value="true" />
- <param name="MaxFileSize" value="10240" />
- <param name="MaxSizeRollBackups" value="100" />
- <param name="StaticLogFileName" value="false" />
- <param name="DatePattern" value="yyyyMMdd".log"" />
- <param name="RollingStyle" value="Date" />
- <layout type="log4net.Layout.PatternLayout">
- <param name="ConversionPattern" value="%n日志时间:%d [%t] %n日志级别:%-5p %n日 志 类:%c [%x] %n%m %n" />
- </layout>
- </appender>
- <!--<logger name="loginfo">
- <level value="INFO" />
- <appender-ref ref="InfoAppender" />
- </logger>-->
- <root>
- <level value="All"/>
- <appender-ref ref="ADONetAppender" />
- <appender-ref ref="InfoAppender" />
- </root>
- </log4net>
- </configuration>
- <connectionType value="Oracle.DataAccess.Client.OracleConnection, Oracle.DataAccess, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342" />
- <connectionString value="Data Source=//xx.xx.xx.xx:1521/xxx;User ID=xxx;Password=xxx;" />
- <commandText value="INSERT INTO
- YSTEMLOG (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)" />
1.Oracle.DataAccess.dll
就好比你自己写sql语句一样,无论那种数据库都得引一个XXXclient的库,后面的公钥要写对,查询一个dll的公开密钥可以先打开vs的命令工具,将dll放入命令工具的当前目录下,然后输入SN -T 回车即可获得公钥.
2.Oracle.DataAccess.Client.OracleConnection
这个就不用说了,肯定是连接数据库的字符串,网上好多格式都不对,这里我贴出了详细的格式
- <connectionString value="Data Source=//xx.xx.xx.xx:1521/xxx;User ID=xxx;Password=xxx;" />
- <pre name="code" class="html"><commandText value="INSERT INTO
- SYSTEMLOG (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)" /></pre>
一定要注意变量的个数要一致,oracle变量默认以冒号开头。
4.其他配置
其他配置与写入文件的配置一样,可以参考上一篇,没有特别提出的都是在上篇的配置基础上继续进行的。
最后,调用代码如下:
- class Program
- {
- private static ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
- static void Main(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如下:
- -- Create table
- create table SYSTEMLOG
- (
- log_id NUMBER not null,
- log_date DATE,
- log_level VARCHAR2(255),
- log_identity VARCHAR2(255),
- log_message VARCHAR2(4000),
- log_exception VARCHAR2(4000),
- log_logger VARCHAR2(255),
- log_source VARCHAR2(1000),
- loginid VARCHAR2(100),
- loginname VARCHAR2(100),
- menuname VARCHAR2(100),
- actionname VARCHAR2(100),
- remark VARCHAR2(1000),
- terminalno VARCHAR2(30),
- orderno VARCHAR2(10)
- )
- -- Create sequence
- create sequence SYSTEMLOG_SEQ
- minvalue 1
- maxvalue 999999999
- start with 8061
- increment by 1
- cache 20;
插入自定义字段需要继承log4net里的基类,先看配置文件
- <?xml version="1.0" encoding="utf-8" ?>
- <configuration>
- <configSections>
- <section name="log4net" type="System.Configuration.IgnoreSectionHandler, log4net" />
- </configSections>
- <log4net>
- <logger name="RollingLogFileAppender">
- <level value="ALL" />
- <appender-ref ref="RollingLogFileAppender" />
- </logger>
- <logger name="AdoNetAppender_Oracle">
- <level value="ALL" />
- <appender-ref ref="AdoNetAppender_Oracle" />
- </logger>
- <logger name="WarningDatail_Oracle">
- <level value="ALL" />
- <appender-ref ref="WarningDatail_Oracle" />
- </logger>
- <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
- <!--日志的路径-->
- <file value="./GSGLAQYJLOG/ExecuteInfo.log" />
- <!--是否覆盖,默认是追加true-->
- <appendToFile value="true" />
- <!--按照文件的大小进行变换日志文件-->
- <rollingStyle value="Size" />
- <!--按照日期变换文件名称
- <rollingStyle value="Date" />
- <datePattern value="yyyyMMdd-HHmm'.log'" />
- -->
- <!--设置无限备份=-1 ,最大备份数为1000-->
- <maxSizeRollBackups value="-1" />
- <!--每个文件的最大2M-->
- <maximumFileSize value="2MB" />
- <!--日志文件名是否为静态-->
- <staticLogFileName value="false" />
- <!--输出文件格式-->
- <layout type="log4net.Layout.PatternLayout">
- <conversionPattern value="%d [%t] %-5p %c [%x] - %m [%r]%n" />
- </layout>
- <!--輸出文件格式説明:
- %d 输出当前语句运行的时刻
- %t 当前语句所在的线程
- %-数字:表示该项的最小长度,如果不够,则用空格填充
- %p 日志的当前优先级别,即DEBUG、INFO<、WARN…等
- %m 输出的日志消息,如ILog.Debug(…)>输出的一条消息
- %n 换行
- %r 運行的時間
- %c 当前日志对象的名称
- -->
- <!--Log4net 多线程写入-->
- <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
- </appender>
- <!--日志记录数据库-->
- <appender name="AdoNetAppender_Oracle" type="log4net.Appender.AdoNetAppender">
- <bufferSize value="1"/>
- <!--<connectionType value="System.Data.OracleClient.OracleConnection, System.Data.OracleClient, Version=4.0.30319.1, Culture=neutral, PublicKeyToken=b77a5c561934e089" />-->
- <connectionType value="Oracle.DataAccess.Client.OracleConnection, Oracle.DataAccess, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342" />
- <connectionString value="DATA SOURCE=//59.74.137.215:1521/GSGLAQYJ;USER ID=GSGLAQYJ;PASSWORD=GSGLAQYJ"/>
- <!--<commandText value="INSERT INTO LOG4NET (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)" />-->
- <commandText value="INSERT INTO SYSTEMLOG (LOG_ID, LOG_DATE,LOG_LEVEL,LOG_IDENTITY,LOG_MESSAGE,LOG_EXCEPTION,LOG_LOGGER,LOG_SOURCE,LOGINID,LOGINNAME,MENUNAME,ACTIONNAME,REMARK) VALUES
- (SYSTEMLOG_SEQ.nextval,:log_date,:log_level,:log_identity,:log_message,:log_exception,:logger,:source,:LoginID,:LoginName,:MenuName,:ActionName,:Remark)" />
- <parameter>
- <parameterName value=":log_date" />
- <dbType value="DateTime" />
- <layout type="log4net.Layout.RawTimeStampLayout" />
- </parameter>
- <parameter>
- <parameterName value=":log_level" />
- <dbType value="String" />
- <size value="10" />
- <layout type="log4net.Layout.PatternLayout">
- <conversionPattern value="%level" />
- </layout>
- </parameter>
- <parameter>
- <parameterName value=":log_identity" />
- <dbType value="String" />
- <size value="100" />
- <layout type="log4net.Layout.PatternLayout">
- <conversionPattern value="%identity" />
- </layout>
- </parameter>
- <parameter>
- <parameterName value=":log_message" />
- <dbType value="String" />
- <size value="4000" />
- <layout type="log4net.Layout.PatternLayout">
- <conversionPattern value="%m" />
- </layout>
- </parameter>
- <parameter>
- <parameterName value=":log_exception" />
- <dbType value="String" />
- <size value="4000" />
- <layout type="log4net.Layout.PatternLayout">
- <conversionPattern value="%exception" />
- </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=":source" />
- <dbType value="String" />
- <size value="1000" />
- <layout type="log4net.Layout.PatternLayout">
- <conversionPattern value="%file:%line" />
- </layout>
- </parameter>
- <!--自定义属性-->
- <parameter>
- <parameterName value=":LoginID" />
- <dbType value="String" />
- <size value="100" />
- <layout type="Log4netHandler.CustomLayout">
- <conversionPattern value="%LoginID" />
- </layout>
- </parameter>
- <parameter>
- <parameterName value=":LoginName" />
- <dbType value="String" />
- <size value="100" />
- <layout type="Log4netHandler.CustomLayout">
- <conversionPattern value="%LoginName" />
- </layout>
- </parameter>
- <parameter>
- <parameterName value=":MenuName" />
- <dbType value="String" />
- <size value="100" />
- <layout type="Log4netHandler.CustomLayout">
- <conversionPattern value="%MenuName" />
- </layout>
- </parameter>
- <parameter>
- <parameterName value=":ActionName" />
- <dbType value="String" />
- <size value="100" />
- <layout type="Log4netHandler.CustomLayout">
- <conversionPattern value="%ActionName" />
- </layout>
- </parameter>
- <parameter>
- <parameterName value=":Remark" />
- <dbType value="String" />
- <size value="1000" />
- <layout type="Log4netHandler.CustomLayout">
- <conversionPattern value="%Remark" />
- </layout>
- </parameter>
- </appender>
- <appender name="WarningDatail_Oracle" type="log4net.Appender.AdoNetAppender">
- <bufferSize value="1"/>
- <connectionType value="Oracle.DataAccess.Client.OracleConnection, Oracle.DataAccess, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342" />
- <connectionString value="DATA SOURCE=//59.74.137.215:1521/GSGLAQYJ;USER ID=GSGLAQYJ;PASSWORD=GSGLAQYJ"/>
- <commandText value="INSERT INTO SYSTEMLOG (LOG_ID, LOG_DATE,TERMINALNO,ORDERNO) VALUES (SYSTEMLOG_SEQ.nextval,:log_date,:terminalno,:orderno)" />
- <parameter>
- <parameterName value=":log_date" />
- <dbType value="DateTime" />
- <layout type="log4net.Layout.RawTimeStampLayout" />
- </parameter>
- <!--自定义属性:-->
- <parameter>
- <parameterName value=":terminalno" />
- <dbType value="String" />
- <size value="30" />
- <layout type="Log4netHandler.CustomLayout">
- <conversionPattern value="%TerminalNo" />
- </layout>
- </parameter>
- <parameter>
- <parameterName value=":orderno" />
- <dbType value="String" />
- <size value="10" />
- <layout type="Log4netHandler.CustomLayout">
- <conversionPattern value="%OrderNo" />
- </layout>
- </parameter>
- </appender>
- </log4net>
- </configuration>
- <logger name="RollingLogFileAppender">
- <level value="ALL" />
- <appender-ref ref="RollingLogFileAppender" />
- </logger>
- <logger name="AdoNetAppender_Oracle">
- <level value="ALL" />
- <appender-ref ref="AdoNetAppender_Oracle" />
- </logger>
- <logger name="WarningDatail_Oracle">
- <level value="ALL" />
- <appender-ref ref="WarningDatail_Oracle" />
- </logger>
写入文本的节点:
- <logger name="RollingLogFileAppender">
- <level value="ALL" />
- <appender-ref ref="RollingLogFileAppender" />
- </logger>
- <logger name="AdoNetAppender_Oracle">
- <level value="ALL" />
- <appender-ref ref="AdoNetAppender_Oracle" />
- </logger>
- <logger name="WarningDatail_Oracle">
- <level value="ALL" />
- <appender-ref ref="WarningDatail_Oracle" />
- </logger>
自定义节点如下:
- <!--自定义属性:-->
- <parameter>
- <parameterName value=":terminalno" />
- <dbType value="String" />
- <size value="30" />
- <layout type="Log4netHandler.CustomLayout">
- <conversionPattern value="%TerminalNo" />
- </layout>
- </parameter>
- <parameter>
- <parameterName value=":orderno" />
- <dbType value="String" />
- <size value="10" />
- <layout type="Log4netHandler.CustomLayout">
- <conversionPattern value="%OrderNo" />
- </layout>
- </parameter>
代码如下:
1.实现该属性的类
- internal sealed class TerminalNo : PatternLayoutConverter
- {
- // Methods
- protected override void Convert(TextWriter writer, LoggingEvent loggingEvent)
- {
- LogContent content = loggingEvent.MessageObject as LogContent;
- if (content != null)
- {
- writer.Write(content.TerminalNo);
- }
- }
- }
其他几个变量一样,都需要继承PatterLayoutConverter
2.反射
- namespace Log4netHandler
- {
- public class CustomLayout:PatternLayout
- {
- // Methods
- public CustomLayout()
- {
- base.AddConverter("TerminalNo", typeof(TerminalNo));
- }
- }
- }
- <layout type="Log4netHandler.CustomLayout">
3.封装节点
- public class OperaterLog
- {
- // Fields
- private static ILog logfile;
- private static ILog logoracle;
- private static ILog logwaring;
- // Methods
- public static ILog Login2File()
- {
- return (logfile = LogManager.GetLogger("文件节点"));
- }
- public static ILog Login2Oracle()
- {
- return (logoracle = LogManager.GetLogger("数据库节点1"));
- }
- public static ILog LoginWarning()
- {
- return (logwaring = LogManager.GetLogger("数据库节点2"));
- }
- }
- class Program
- {
- static void Main(string[] args)
- {
- Log4netHandler.LogContent msg = new Log4netHandler.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的排版,蛋疼。。