关于使用Log4Net将日志插入oracle数据库中

1.关于配置文件。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section   name="log4net"   type="System.Configuration.IgnoreSectionHandler"   />
  </configSections>
  <log4net>
    <root>
      <level value="ALL" />
      <appender-ref ref="rollingFile" />
      <appender-ref ref="ADONetAppender"/>
    </root>
    <logger name="Presin_log">
      <level value="ALL" />
      <appender-ref ref="PresinLoging" />
    </logger>
    <logger name="Oracle_DB">
      <level value="ALL" />
      <appender-ref ref="OracleDB" />
    </logger>
    <logger name="flowseting_log">
      <level value="ALL" />
      <appender-ref ref="flowsetingLoging" />
    </logger>
    <!--Presin日志-->
    <appender name="PresinLoging" type="log4net.Appender.RollingFileAppender,log4net" >
      <param name="File" value="Log\Presin\" />
      <param name="AppendToFile" value="true" />
      <param name="RollingStyle" value="Composite" />
      <param name="DatePattern" value="yyyy-MM-dd.‘.txt‘" />
      <param name="MaximumFileSize" value ="5MB"/>
      <param name="StaticLogFileName" value="false" />
      <layout type="log4net.Layout.PatternLayout,log4net">
        <conversionPattern value="%date %-5level %newline %logger - %message%newline %newline" />
      </layout>
    </appender>
    <appender name="OracleDB" type="log4net.Appender.AdoNetAppender,log4net" >
      <bufferSize value="20"/>
      <connectionType value="System.Data.OracleClient.OracleConnection, System.Data.OracleClient, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
      <connectionString value="Data Source=ORCl;User ID=sa;Password=sa;" />
      <commandText value="INSERT INTO LogDetails (LogDate,loglevel,loglogger,LogMessage,logfunctionname,logbusinessname) VALUES (:log_date,:log_level,:logger,:message,:FunctionName,:BusinessName)" />
      <parameter>
        <parameterName value=":log_date" />
        <dbType value="DateTime" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%date{yyyy-MM-dd HH:mm:ss}" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value=":log_level" />
        <dbType value="String" />
        <size value="200" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%p" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value=":logger" />
        <dbType value="String" />
        <size value="200" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%logger" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value=":message" />
        <dbType value="String" />
        <size value="2000" />
        <layout type="MapgisEgovLog4_WriteLog.MyLayout">
          <conversionPattern value="%property{Message}" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value=":FunctionName" />
        <dbType value="String" />
        <size value="200" />
        <layout type="MapgisEgovLog4_WriteLog.MyLayout">
          <conversionPattern value="%property{FunctionName}" />
        </layout>
      </parameter>
    <parameter>
        <parameterName value=":BusinessName" />
        <dbType value="String" />
        <size value="200" />
        <layout type="MapgisEgovLog4_WriteLog.MyLayout">
          <conversionPattern value="%property{BusinessName}" />
        </layout>
      </parameter>
    </appender>
    <!--flowseting日志-->
    <appender name="flowsetingLoging" type="log4net.Appender.RollingFileAppender,log4net" >
      <param name="File" value="Log\flowseting\" />
      <param name="AppendToFile" value="true" />
      <param name="RollingStyle" value="Date" />
      <param name="DatePattern" value="yyyyMMdd" />
      <param name="StaticLogFileName" value="true" />
      <layout type="log4net.Layout.PatternLayout,log4net">
        <conversionPattern value="%date %-5level %newline %logger - %message%newline %newline"  />
      </layout>
    </appender>
  </log4net>
</configuration>

a.在配置文件中,root节点下需要增加<appender-ref ref="ADONetAppender"/>代表允许将日志插入数据库中。

<root>
      <level value="ALL" />
      <appender-ref ref="rollingFile" />
      <appender-ref ref="ADONetAppender"/>
    </root>

rollingFile是将日志写入文件中,在这里不做讨论。

ADONetAppender是将日志写入数据库中,然后log4Net会根据接下来的配置connectionType和connectionString判断插入何种数据库和哪个数据库

b.增加一个logname,方便进一步添加属性

<logger name="Oracle_DB">
      <level value="ALL" />
      <appender-ref ref="OracleDB" />
 </logger>

c.进一步配置OracleDB

<appender name="OracleDB" type="log4net.Appender.AdoNetAppender,log4net" >
      <bufferSize value="20"/>
      <connectionType value="System.Data.OracleClient.OracleConnection, System.Data.OracleClient, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
      <connectionString value="Data Source=ORCl;User ID=sa;Password=sa;" />
      <commandText value="INSERT INTO LogDetails (LogDate,loglevel,loglogger,LogMessage,logfunctionname,logbusinessname) VALUES (:log_date,:log_level,:logger,:message,:FunctionName,:BusinessName)" />
      <parameter>
        <parameterName value=":log_date" />
        <dbType value="DateTime" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%date{yyyy-MM-dd HH:mm:ss}" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value=":log_level" />
        <dbType value="String" />
        <size value="200" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%p" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value=":logger" />
        <dbType value="String" />
        <size value="200" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%logger" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value=":message" />
        <dbType value="String" />
        <size value="2000" />
        <layout type="MapgisEgovLog4_WriteLog.MyLayout">
          <conversionPattern value="%property{Message}" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value=":FunctionName" />
        <dbType value="String" />
        <size value="200" />
        <layout type="MapgisEgovLog4_WriteLog.MyLayout">
          <conversionPattern value="%property{FunctionName}" />
        </layout>
      </parameter>
    <parameter>
        <parameterName value=":BusinessName" />
        <dbType value="String" />
        <size value="200" />
        <layout type="MapgisEgovLog4_WriteLog.MyLayout">
          <conversionPattern value="%property{BusinessName}" />
        </layout>
      </parameter>
    </appender>

其中需要注意的是:

(1).bufferSize,代表缓存的记录条数,设置为20,表示log4net会在有20条日志时调用数据库并插入。

(2).connectionType代表数据库类型,注意Version和PublicKeyToken一定要于自己系统调用的版本一致。oracle的2.0版本的System.Data.OracleClient一般是2.0.0.0和b77a5c561934e089

(3)commandText代表插入的语句,注意oracle的参数是:参数,而sqlserver是@参数,且此处一定要保证,sql语句正确,如数据库中无此表或表无此字段,log4Net都不会报错,但不会进行任何操作。

(4)通过parameter逐一将要插入数据库的参数进行赋值和格式化

如:日期格式化和赋值

<parameter>
        <parameterName value=":log_date" />
        <dbType value="DateTime" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%date{yyyy-MM-dd HH:mm:ss}" />
        </layout>
</parameter>

字符串默认格式化和赋值

      <parameter>
        <parameterName value=":logger" />
        <dbType value="String" />
        <size value="200" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%logger" />
        </layout>
      </parameter>

log4Net提供给我们的字段有:

log_date,log_level,logger,message等,其余的字段需要我们自定义

自定义字段格式化和赋值

      <parameter>
        <parameterName value=":FunctionName" />
        <dbType value="String" />
        <size value="200" />
        <layout type="MapgisEgovLog4_WriteLog.MyLayout">
          <conversionPattern value="%property{FunctionName}" />
        </layout>
      </parameter>

log4Net提供的字段,我们也可以通过自定义重载

      <parameter>
        <parameterName value=":message" />
        <dbType value="String" />
        <size value="2000" />
        <layout type="MapgisEgovLog4_WriteLog.MyLayout">
          <conversionPattern value="%property{Message}" />
        </layout>
      </parameter>

注意:layout Type中填写的是og4net的格式化类以及其命名空间。

conversionPattern中是使用扩展的格式化类中注册的格式化方法。

扩展格式化需要一些后台代码支持

/// <summary>
    /// 包含了所有的自定字段属性
    /// </summary>
    public class LogContent
    {
        public LogContent(string sFunctionName, string sLogMessasge,string sLogBusinessName)
        {
            FunctionName = sFunctionName;
            Message = sLogMessasge;
            BusinessName = sLogBusinessName;
        }

        /// <summary>
        /// 方法名称
        /// </summary>
        public string FunctionName { get; set; }

        /// <summary>
        /// 日志描述信息
        /// </summary>
        public string Message { get; set; }

        /// <summary>
        /// 业务名称
        /// </summary>
        public string BusinessName { get; set; }
    }

    public class MyLayout : PatternLayout
    {
        public MyLayout()
        {
            this.AddConverter("property", typeof(LogInfoPatternConverter));
        }
    }

    public class LogInfoPatternConverter : PatternLayoutConverter
    {

        protected override void Convert(TextWriter writer, LoggingEvent loggingEvent)
        {
            if (Option != null)
            {
                WriteObject(writer, loggingEvent.Repository, LookupProperty(Option, loggingEvent));
            }
            else
            {
                WriteDictionary(writer, loggingEvent.Repository, loggingEvent.GetProperties());
            }
        }
        /// <summary>
        /// 通过反射获取传入的日志对象的某个属性的值
        /// </summary>
        /// <param name="property"></param>
        /// <returns></returns>  

        private object LookupProperty(string property, log4net.Core.LoggingEvent loggingEvent)
        {
            object propertyValue = string.Empty;
            PropertyInfo propertyInfo = loggingEvent.MessageObject.GetType().GetProperty(property);
            if (propertyInfo != null)
                propertyValue = propertyInfo.GetValue(loggingEvent.MessageObject, null);
            return propertyValue;
        }
    }

其中:

d.自定义字段的类

    public class LogContent
    {
        public LogContent(string sFunctionName, string sLogMessasge,string sLogBusinessName)
        {
            FunctionName = sFunctionName;
            Message = sLogMessasge;
            BusinessName = sLogBusinessName;
        }

        /// <summary>
        /// 方法名称
        /// </summary>
        public string FunctionName { get; set; }

        /// <summary>
        /// 日志描述信息
        /// </summary>
        public string Message { get; set; }

        /// <summary>
        /// 业务名称
        /// </summary>
        public string BusinessName { get; set; }
    }

e.扩展log4net的格式化方法

public class MyLayout : PatternLayout
    {
        public MyLayout()
        {
            this.AddConverter("property", typeof(LogInfoPatternConverter));
        }
    }

f.通过反射的方法获取LogContent中定义的字段

public class LogInfoPatternConverter : PatternLayoutConverter
    {

        protected override void Convert(TextWriter writer, LoggingEvent loggingEvent)
        {
            if (Option != null)
            {
                WriteObject(writer, loggingEvent.Repository, LookupProperty(Option, loggingEvent));
            }
            else
            {
                WriteDictionary(writer, loggingEvent.Repository, loggingEvent.GetProperties());
            }
        }
        /// <summary>
        /// 通过反射获取传入的日志对象的某个属性的值
        /// </summary>
        /// <param name="property"></param>
        /// <returns></returns>  

        private object LookupProperty(string property, log4net.Core.LoggingEvent loggingEvent)
        {
            object propertyValue = string.Empty;
            PropertyInfo propertyInfo = loggingEvent.MessageObject.GetType().GetProperty(property);
            if (propertyInfo != null)
                propertyValue = propertyInfo.GetValue(loggingEvent.MessageObject, null);
            return propertyValue;
        }
    }

调用示例

log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(strPath + "配置文件.xml"));
 ILog log = LogManager.GetLogger("Oracle_DB");
log.Info(new LogContent("Button1_Click", "测试成功","测试"));

参考:

http://blog.csdn.net/kongwei521/article/details/52242319

时间: 2024-12-13 18:46:31

关于使用Log4Net将日志插入oracle数据库中的相关文章

给Oracle数据库中CLOB字段插入空值

遇到往ORACLE数据库中插入数据时总是报ORA-01084 invalid argument in OCI call错误,经分析是因为表中的一个字段类型为CLOB,并且可为空,当在给该字段插入空值时引发的该错误.后来判断是否为空值,如果为空值使用DBNull.Value,以此解决了该问题. Null 指的是无效的对象引用:而 DBNull 是一个类, DBNull.Value 是它唯一的实例 .DBNull 的实例 DBNull.Value是数据库表中的空数据在 .Net 代码中的表现形式.我

解决getJdbcTemplate往oracle数据库中插入数据返回主键出错问题

我们使用Spring中的JdbcDaoSupport往Mysql中插入数据并返回主键代码,我们使用的mysql数据库,主键在数据库中设置为自增长:该类继承自JdbcDaoSupport,所以能直接使用getJdbcTemplate() public int saveUser(String userName,int age,String password){ getJdbcTemplate().update(new PreparedStatementCreator() { public Prepa

向Oracle数据库中插入数据出错:ORA-01036 无效的变量名或数据

向Oracle数据库中插入数据出错: 经过排查,因为Update数据时没有出错,所以OracleHelper没有问题: 看异常信息提示:无效的变量和数据,应该是SQL语句的问题,调试时所传的实例UserInfo数据是正确的,所以只能是SQL语句的问题: 曾今一度怀疑这样使用Sequence是错误的,中途变换了触发器,弄了变天触发器也些错误了, 再次回到直接用序列,仔细之下,终于发现这个分号‘:’,这里应该为‘:’,实在是太小了,很难发现,以后这里最好留一个空格.

知方可补不足~利用LogParser将IIS日志插入到数据库

回到目录 LogParser是微软开发的一个日志分析工具,它是命令行格式的,我们通过这个工具,可以对日志文件进行操作,对于一个几百兆的log文件,使用记事本打开是件很残酷的事,所以,很多情况下,我们都会将大日志文件的内容插入到数据库中,这样有利于我们更好的去分析系统的日志. 脚本中心给它的定义 Log Parser 2.2 是一个功能强大的通用工具,它可对基于文本的数据(如日志文件.XML 文件和 CSV 文件)以及 Windows 操作系统上的重要数据源(如事件日志.注册表.文件系统和 Act

asp.net利用log4net写入日志到SqlServer数据库

asp.net利用log4net写入日志到SqlServer数据库 作者: Kein  来源: 博客园  发布时间: 2010-10-14 07:19  阅读: 6427 次  推荐: 6   原文链接   [收藏] 摘要:Log4net是一个开源的错误日志记录项目,asp.net利用log4net写入日志到SqlServer数据库.下面就我的安装部署log4net到MS sql server的经验与大家分享. asp.net利用log4net写入日志到SqlServer数据库,Log4net是

向Oracle数据库中CLOB插入数据报错问题

今天在项目中向数据库的CLOB属性插入一段篇文章(1000~2000)字就会报一个字符串过长的错误. 网上说用流来处理,没有这么做.这像是一个Bug,只要把插入的数据,默认扩充到2000以上就ok了. 下面是这段代码: if((temp.length()>=1000)&&(temp.length()<=2000)){ temp=StringUtils.rightPad(temp, 2008); } 使用StringUtils的rightPad方法使没超过2000的部分,在右边自

如何处理Oracle数据库中的坏块问题

本文主要介绍如何去处理在Oracle数据库中出现坏块的问题,对于坏块产生在不同的对象上,处理的方法会有所不同,本文将大致对这些方法做一些介绍.因为数据库运行时间长了,由于硬件设备的老化,出现坏块的几率会越来越大,因此,做为一个DBA,怎么去解决数据库出现的坏块问题就成了一个重要的议题了. 一:什么是数据库的坏块   首先我们来大概看一下数据库块的格式和结构 数据库的数据块有固定的格式和结构,分三层:cache layer,transaction layer,data layer.在我们对数据块进

Oracle数据库中的blob类型解析

Oracle的Blob字段比较特殊,他比long字段的性能要好很多,可以用来保存例如图片之类的二进制数据. 写入Blob字段和写入其它类型字段的方式非常不同,因为Blob自身有一个cursor,你必须使用cursor对blob进行操作,因而你在写入Blob之前,必须获得cursor才能进行写入,那么如何获得Blob的cursor呢? 这需要你先插入一个empty的blob,这将创建一个blob的cursor,然后你再把这个empty的blob的cursor用select查询出来,这样通过两步操作

Oracle数据库中序列(SEQUENCE)的用法详解

在Oracle数据库中,序列的用途是生成表的主键值,可以在插入语句中引用,也可以通过查询检查当前值,或使序列增至下一个值.本文我们主要介绍了序列的用法,希望能够对您有所帮助. AD: 在Oracle数据库中,什么是序列呢?它的用途是什么?序列(SEQUENCE)其实是序列号生成器,可以为表中的行自动生成序列号,产生一组等间隔的数值(类型为数字).其主要的用途是生成表的主键值,可以在插入语句中引用,也可以通过查询检查当前值,或使序列增至下一个值. 创建序列需要CREATE SEQUENCE系统权限