spring log4j日志处理

  Log4j 是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务器、NT的事 件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就 是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

  如此强大的优越性,实际上手并不难,尤其在spring框架下,使用log4j更是容易,下面介绍一下spring下的log4j应用。

 <一>如何配置日志环境

  (1)在web工程冲导入log4j-xxx.jar 

  (2)在spring的配置文件web.xml加入如下配置

    <!-- 配置日志监听器 -->
    <context-param>
      <param-name>webAppRootKey</param-name>
      <param-value>weChat.root</param-value>
    </context-param>
    <context-param>
      <param-name>log4jConfigLocation</param-name>
      <param-value>/WEB-INF/classes/log4j.properties</param-value><!--指定日志配置文件的所在位置-->
    </context-param>
    <listener>
      <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>

    说明: 在上文的配置里,在上文的配置里,Log4jConfigListener会去WEB- INF/props/log4j.propeties 读取配置文件;

       开一条watchdog线程每60秒扫描一下配置文件的变化(这样在web服务启动后再去修改配置文件也不用重新启动web服务了);

        并把 web目录的路径压入一个叫webapp.root的系统变量(webapp.root将在log4j.properties文件中使用)。

  (3)在项目中加入日志配置文件(放入上面配置中指定的位置)

    log4j.properties内容如下:

    #将ibatis log4j运行级别调到DEBUG可以在控制台打印出ibatis运行的sql语句
    #trace<debug<info<warn<error<fatal
    #指定日志有的输出的级别和要输出的方式
    log4j.rootLogger=info,stdout,logfile,db

    #指定日志输出到控制台
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    #log4j.appender.stdout.Target=System.err
    log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout

    #指定日志输出到文件
    log4j.appender.logfile=org.apache.log4j.FileAppender
    #指定日志输出的位置(这里使用${weChat.root}指定当前项目根目录)
    log4j.appender.logfile.File=${weChat.root}/logs/mylog.log
    #指定日志文件的大小
    log4j.appender.logfile.MaxFileSize=1024KB
    #指定日志输出的布局
    log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
    #指定日志的输出内容
    log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %F %p %m%n

    #指定将日志写入数据库中
    log4j.appender.db = com.cdjp.util.Log4jJDBCAppender
    #缓存,这里是有一条日志就存入数据库(较浪费性能)
    log4j.appender.db.BufferSize=1
    #指定数据库的驱动
    log4j.appender.db.driver=oracle.jdbc.driver.OracleDriver
    #指定数据库的链接
    log4j.appender.db.URL=jdbc:oracle:thin:@localhost:1521:xe
    #指定数据库的用户名
    log4j.appender.db.user=system
    #指定数据库的密码
    log4j.appender.db.password=123456
    #写入数据的sql语句
    log4j.appender.db.sql=insert into reslog(logId,class,method,createDate,logLevel,msg) values(reslog_seq.nextval,'%C','%M',

    to_date('%d{yyyy-MM-dd HH:mm:ss}','yyyy-MM-dd HH24:mi:ss'),'%p','%m')
    #指定日志的输出布局方式
    log4j.appender.db.layout=org.apache.log4j.PatternLayout

  

    注意:

      原本上面这个属性 log4j.appender.db = org.apache.log4j.jdbc.JDBCAppender

      可是将数据写入数据库时,部分数据中存在单引号(需要转义),这样在够构成写入数据库的sql语句就会产生错误。例如%m中含有单引号,因而就如发生SQLException:缺失逗号。

      这里错误的原因是JDBCAppender这个类,官方已经不建议使用,它不会对数据中的单引号进行特殊处理(原理网上有,不过我看不懂,大家自行研究)

      建议重写org.apache.log4j.jdbc.JDBCAppender, 代码如下:

        1.就是自己写一个类扩展LoggingEvent,重写它的getThreadName方法,代码如下:

      public class BPSLoggingEvent extends LoggingEvent {

        private static final long serialVersionUID = -1405129465403337629L;

          public BPSLoggingEvent(String fqnOfCategoryClass, Category logger, Priority level, Object message, Throwable throwable) {
              super(fqnOfCategoryClass, logger, level, message, throwable);
          }

          public String getThreadName() {
              String thrdName=super.getThreadName();
              if(thrdName.indexOf("'")!=-1){
                  thrdName=thrdName.replaceAll("'", "''");
              }
              return thrdName;
          }

    
          public String getRenderedMessage() {
              String msg=super.getRenderedMessage();
              if(msg.indexOf("'")!=-1){
                   msg=msg.replaceAll("'", "''");
              }
              return msg;
          }
    }

       2.扩展JDBCAPPend了,覆盖里面的getLogStatement方法,代码如下:

      public class BPSJDBCAppender extends JDBCAppender {

        protected String getLogStatement(LoggingEvent event) {

           String fqnOfCategoryClass=event.fqnOfCategoryClass;

           Category logger=Category.getRoot();

           Priority level=event.level;

           Object message=event.getMessage();

           Throwable throwable=null;

            BPSLoggingEvent bEvent=new BPSLoggingEvent(fqnOfCategoryClass,logger,level,message,throwable);

                 return super.getLogStatement(bEvent);

             }
         }

      3. log4j.appender.db = org.apache.log4j.jdbc.JDBCAppender 指定成上面BPSJDBCAppender(全称),就可以了。

<二>日志文件配置相关说明

    

  log4j使用的几个关键点

    根记录器(rootLogger),输出端(appenders)和布局(layouts) 

  a)定义根记录器的格式为 

    log4j.rootLogger = [ level ], appendName1, appendName2, …appendNameN。同一个记录器可有多个输出端。 

    PS:level的级别(此级别可以自定义,系统默认提供了以下级别) 

      ◆debug//调试信息 

      ◆info//一般信息 

      ◆warn//警告信息 

      ◆error//错误信息 

      ◆fatal//致命错误信息 

   上面列出的就是所谓log4j的输出级别,log4j建议只使用4个级别,它们从上到下分别为ERROR、WARN、INFO、DEBUG,假设你定义的级别是info,

   那么error和warn的日志可以显示而比他低的debug信息就不显示了。 

   b)定义一个appender的输出目的地的格式为 

     log4j.appender.appenderName = fully.qualified.name.of.appender.class。log4j提供了以下几种常用的输出目的地: 

      ◆org.apache.log4j.ConsoleAppender,将日志信息输出到控制台 

      ◆org.apache.log4j.FileAppender,将日志信息输出到一个文件 

      ◆org.apache.log4j.DailyRollingFileAppender,将日志信息输出到一个,并且每天输出到一个新的日志文件 

      ◆org.apache.log4j.RollingFileAppender,将日志信息输出到一个文件,通过指定文件的的尺寸,当文件大小到达指定尺寸的时候会自动把文件改名,如名为example.log的文件会改名为 example.log.1,同时产生一个新的example.log文件。如果新的文件再次达到指定尺寸,又会自动把文件改名为 example.log.2,同时产生一个example.log文件。依此类推,直到example.log. MaxBackupIndex, MaxBackupIndex的值可在配置文件中定义。 

      ◆org.apache.log4j.WriterAppender,将日志信息以流格式发送到任意指定的地方。 

      ◆org.apache.log4j.jdbc.JDBCAppender,通过JDBC把日志信息输出到数据库中。 

  c)输出格式(布局)layout 

     Log4j提供了一下几种布局: 

      ◆org.apache.log4j.HTMLLayout,以HTML表格形式布局 

      ◆org.apache.log4j.PatternLayout,可以灵活地指定布局模式 

      ◆org.apache.log4j.SimpleLayout,包含日志信息的级别和信息字符串 

      定义一个PatternLayout布局的语句为: 

      log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 

      log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1} - %m%n 

    PS:ConversionPattern参数的格式含义 

      %c 输出日志信息所属的类的全名 

      %d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy-MM-dd HH:mm:ss },输出类似:2002-10-18- 22:10:28 

      %f 输出日志信息所属的类的类名 

      %l 输出日志事件的发生位置,即输出日志信息的语句处于它所在的类的第几行 

      %m 输出代码中指定的信息,如log(message)中的message 

      %n 输出一个回车换行符,Windows平台为“ ”,Unix平台为“ ” 

      %p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL。如果是调用debug()输出的,则为DEBUG,依此类推 

      %r 输出自应用启动到输出该日志信息所耗费的毫秒数 

      %t 输出产生该日志事件的线程名 

  

  ps:这些记录大多是抄录于他人(给出了具体原理,自行观看)

    抄录一:Spring 配置log4j和简单介绍Log4J的使用

    抄录二:log4j重写

     

原文地址:https://www.cnblogs.com/gangbalei/p/6632611.html