zoukankan      html  css  js  c++  java
  • 日志框架logj的使用


    log4j

    简介

    • 是什么?
      Apache的一个开源的、轻量级的、用于日志管理的框架
    • 有什么?
      Log4j由三个重要的组件构成:日志信息的输出格式,日志信息的优先
      级,日志信息的输出目的地。
      1,日志信息的优先级用来指定这条日志信息的重要程度;
      2,日志信息的输出目的地指定了日志将打印到控制台还是文件中(或其它组件中);
      3,输出格式则控制了日志信息的显示内容 。
    • 能干什么?
      主要用来进行日志记录的管理,包括对日志输出的目的地,输出的信息级别和输出的格式等。

      日志级别

    OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,可以控制到应用程序中相应级别的日志信息的开关。
    几个重要规则
    1:级别的控制,就是只要大于等于指定的控制级别,就可以输出
    2:如果有多个logger,都可以匹配输出,则每个logger都产生输出,其中根logger匹配所有的输出;而级别控制来源于路径最详细的logger。

    输出源

    Log4j允许日志请求被输出到多个输出源。用Log4j的话说,一个输出源被称做一个Appender 。一个logger可以设置超过一个的appender。

    常见Appender
    org.apache.log4j.ConsoleAppender(控制台)
    org.apache.log4j.FileAppender(文件)
    org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)
    org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)
    org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
    org.apache.log4j.jdbc.JDBCAppender(把日志用JDBC记录到数据库中)

    布局

    布局就是指输出信息的格式。在Log4j中称作Layout

    常见Layout
    org.apache.log4j.HTMLLayout(以HTML表格形式布局),
    org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
    org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
    org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

    常用的PatternLayout

    %m 输出代码中指定的消息
    %p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
    %r 输出自应用启动到输出该log信息耗费的毫秒数
    %c 输出所属的类目,通常就是所在类的全名
    %t 输出产生该日志事件的线程名
    %n 输出一个回车换行符,Windows平台为“ ”,Unix平台为“ ”
    %d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日22:10:28,921
    %l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)

    配置示例

    配置
    Log4j有两种配置方式,一种是xml格式,一种是properties格式。都是放置到classpath下面。默认名称分别是:log4j.xml和log4j.properties
    1,properties配置方式

    # non-root loggers    
    # log4j.rootLogger = debug,ydc.File,ydc.Console
    # 这是一个输出目的地,目的地是按天卷动的文件
    # key都是可以用.分开的
    # 【log4j都是给log4j用的】.【appneder【目的地】/logger【控制单元】本质】
    # appender【变量名】.【给这个变量的setter】
    # Appender javass.File = new org.apache.log4j.DailyRollingFileAppender();
    log4j.appender.javass.File=org.apache.log4j.DailyRollingFileAppender  
    # javass.File.setFile("palmpay.log")  
    log4j.appender.javass.File.file=javass.log
    # javass.File.setDatePattern(".yyyy-MM-dd")    
    log4j.appender.javass.File.DatePattern=.yyyy-MM-dd
    # Layout layout = new org.apache.log4j.PatternLayout();
    # javass.File.setLayout(layout);
    log4j.appender.javass.File.layout=org.apache.log4j.PatternLayout
    # layout.setConversionPattern("%d{HH:mm:ss,SSS} %5p (%C{1}:%M) - %m%n");
    log4j.appender.javass.File.layout.ConversionPattern=%d{HH:mm:ss,SSS} %5p (%C{1}:%M) - %m%n
    #输出的目的地,输出到哪儿,Daily【按天】Rolling【滚动】File【文件】Appender【目的地】
    #今天的日志打印到palmpay.log
    #以前天的日志,各自打印到对应的天数的文件里
    #日志输出的信息,【%m%n代表信息本身】【%d{HH:mm:ss,SSS} %5p (%C{1}:%M) -附加在信息之前的其他东西】%d{HH:mm:ss,SSS} %5p (%C{1}:%M) - %m%n
    #【%d{HH:mm:ss,SSS}【时间】 %5p【级别】 (%C{1}:%M)【类、方法】】
    log4j.appender.javass.Console=org.apache.log4j.ConsoleAppender 
    log4j.appender.javass.Console.layout=org.apache.log4j.PatternLayout    
    log4j.appender.javass.Console.layout.ConversionPattern=%d{HH:mm:ss,SSS} %5p (%C:%M) - %m%n 
    #目的地和格式之间的关系了,每个目的地各自制定各自的格式
    
    #logger,是控制日志输出的最小单元
    # key的剩余部分,是个包名,管理它和它的子包下的所有类
    # value的部分 = 一个级别和对多个目的地的引用【拿,分开】
    
    #log4j.rootLogger = debug,javass.File,javass.Console
    log4j.logger.cn.javass=warn,javass.Console,javass.File
    #log4j.logger.cn.javass.dao=info,javass.File,javass.Console
    #log4j.logger.org.apache.struts2=error,javass.File,javass.Console
    #log4j.logger.com.opensymphony.xwork2=error,javass.File,javass.Console
    #log4j.logger.org.springframework=ERROR,ydc.File,ydc.Console
    #log4j.logger.org.hibernate=ERROR,ydc.File,ydc.Console

    2,xml配置方式

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
    <!-- in java cmd add -Dlog4j.configuration=logging.xml -->
    <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    
        <appender name="log.console" class="org.apache.log4j.ConsoleAppender">
            <layout class="org.apache.log4j.PatternLayout">
                <param name="ConversionPattern" value="%d{HH:mm:ss,SSS} %5p (%C{1}:%M) - %m%n" />
            </layout>
        </appender>
    
        <appender name="log.file" class="org.apache.log4j.DailyRollingFileAppender">
            <param name="File" value="javass.log" />
            <param name="Append" value="true" />
            <param name="DatePattern" value="'.'yyyy-MM-dd" />
            <layout class="org.apache.log4j.PatternLayout">
                <param name="ConversionPattern" value="%d{HH:mm:ss,SSS} %5p (%C{1}:%M) - %m%n" />
            </layout>
            <filter class="org.apache.log4j.varia.LevelRangeFilter">
                <param name="levelMin" value="info" />
                <param name="levelMax" value="info" />
                <param name="AcceptOnMatch" value="true" />
            </filter>
        </appender>
    
        <logger name="cn.javass" additivity="false">
            <level value="debug" />
            <appender-ref ref="log.console" />
            <appender-ref ref="log.file" />
        </logger>
    
        <logger name="cn.javass.dao" additivity="false">
            <level value="info" />
            <appender-ref ref="log.console" />
            <appender-ref ref="log.file" />
        </logger>
    
        <!-- 
        <root>
            <level value="debug" />
            <appender-ref ref="log.console" />
            <appender-ref ref="log.file" />
        </root>
         -->
    
    </log4j:configuration>
    

    3,java使用示例

    /**
     * 1、如何取logger
     *  这个logger可以被几个log4j.logger管理
     * 2、用什么样的级别打印
     * @author Administrator
     *
     */
    public class Test1 {
    
        //用类对象来取得logger,就相当于是用全类名
        private static final Logger logger = Logger.getLogger(Test1.class);
    
        public static void main(String[] args) {
    
            logger.debug("debug");
            logger.info("info");
            logger.warn("warn");
            logger.error("error");
    
        }
    
    }
    public class Test2 {
        /**
         * Logger for this class
         */
        private static final Logger logger = Logger.getLogger(Test2.class);
    
        private static void test1(int x){
            if (logger.isDebugEnabled()) {
                logger.debug("test1(int) - start");
            }
    
            String xx = "y";
            if (logger.isInfoEnabled()) {
                logger.info("test1(int) - String xx=" + xx);
            }
    
    
            if (logger.isDebugEnabled()) {
                logger.debug("test1(int) - end");
            }
        }
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
    
        }
    
    }

    4,自己项目中使用的方式
    log4j.properties

    #
    log4j.rootLogger=INFO, console
    
    log4j.category.com.means=all
    
    # 
    log4j.appender.stdout = org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.Target = System.out
    log4j.appender.stdout.Encoding=UTF-8
    log4j.appender.stdout.ImmediateFlush=true
    log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern = [%d{yyyy-MM-dd HH/:mm/:ss}]%-5p %c(line/:%L) %x-%m%n
    
    
    #
    log4j.appender.f =org.apache.log4j.FileAppender
    log4j.appender.f.File=/HYAQ_APP_LOG.log
    log4j.appender.f.Append=true
    log4j.appender.f.layout=org.apache.log4j.PatternLayout
    log4j.appender.f.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS}[%C]-[%p] %m%n
    
    log4j.appender.rolling_file=org.apache.log4j.RollingFileAppender
    log4j.appender.rolling_file.File=log/hyaq_rolling.log
    log4j.appender.rolling_file.Append=true
    log4j.appender.rolling_file.MaxFileSize=1000KB
    log4j.appender.rolling_file.MaxBackupIndex=100
    log4j.appender.rolling_file.layout=org.apache.log4j.PatternLayout
    log4j.appender.rolling_file.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS}[%C]-[%p] %m%n
    
    
    # config about ibatis
    log4j.logger.com.ibatis=DEBUG
    log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
    log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG
    log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
    log4j.logger.java.sql.Connection=DEBUG
    log4j.logger.java.sql.Statement=DEBUG
    log4j.logger.java.sql.PreparedStatement=DEBUG
    log4j.logger.java.sql.ResultSet=DEBUG
    
    #log4j
    log4j.appender.console=org.apache.log4j.ConsoleAppender
    log4j.appender.console.layout=org.apache.log4j.PatternLayout
    log4j.appender.console.layout.ConversionPattern=%d{ISO8601} - %p - %m%n
    
    public class TxxDAOImpl extends SqlMapClientDaoSupport implements TxxDAO {  
        static Logger log = Logger.getLogger(TxxDAOImpl.class);
        public TxxDAOImpl() {
                super();
            }
        public boolean insert(Txx record) {
    
            boolean bFlag = false;
            try{
                getSqlMapClientTemplate().insert("XX_XXY.insert", record);
                bFlag = true;
            }catch(Exception e) {
                log.error("TPermitDAOImpl新增***增发申请信息方法异常");
                log.error("异常信息:" + e.getMessage());
            }
            return bFlag;
         }
    }

    Appender、Layout、Logger三者之间的关系

    每个Appender都要引用自己的Layout。
    每个Logger都可以指定一个级别,同时引用多个Appender;而一个Appender也同时可以被多个Logger引用。

    xml vs properties

    首先要注意,log4j.xml优先于log4j.properties,如果同时存在log4j.xml和log4j.properites,以log4j.xml为准。
    在log4j.properties里,控制级别的时候,只能打印出大于指定级别的所有信息;但是在log4j.xml中可以通过filter来完成过滤:典型的引用是只打印出某种级别的信息。

    <appender name="log.file" 
    class="org.apache.log4j.DailyRollingFileAppender">
        <filter class="org.apache.log4j.varia.LevelRangeFilter">
        <param name="levelMin" value="info" />
        <param name="levelMax" value="info" />
        <param name="AcceptOnMatch" value="true" />
    </filter>
    </appender>

    可以通过logger的additivity=“false”属性,来设置多个logger是否重复输出同一条信息

    <logger name="cn.javass1" additivity="false">
        <level value="debug" />
        <appender-ref ref="log.console" />
        <appender-ref ref="log.file" />
    </logger>

    看似奇怪的重复级别判断:我们在看一些成熟框架的源代码中,经常看到如下代码:

    if (logger.isDebugEnabled()){
        logger.debug(“debug:“+name);
    }

    为什么不是直接logger.debug(“debug:“+name);呢?
    在配置文件中虽然可以使用控制级别为比debug级别更高的级别,而不输出debug信息;但是,这里的字符串连接操作仍然会影响运行效率;如果先判断当前logger的级别,如果级别不合适的话,连这句字符串连接都可以不做了。

    在java中使用log4j时,我们可以使用它的eclipse插件log4e。它的官方网址是:http://log4e.jayefem.de/,分为商业版本和免费版本。我们只需要使用其免费版本,就可以极大的帮我们提高开发效率。比如:在一个类中声明一个logger;帮我们写麻烦的logger.isDebugEnabled();在一个方法开始的时候打印所有的参数;输出一个变量等等。

    使用classpath下的logging.properties

    如果想使用自定义的logging.properties,只需要保证这段代码运行在getLogger之前即可:

    ClassLoader classLoader = 
    Thread.currentThread().getContextClassLoader();
    InputStream inputStream = 
    classLoader.getResourceAsStream("logging.properties");
    if (inputStream != null) {
        try {
        LogManager.getLogManager().readConfiguration(inputStream);
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
  • 相关阅读:
    MyBatis学习教程
    【转载】Spring MVC 整合 Freemarker
    Java高效编程之四【C语言结构的替代】
    String相关的问题
    接口与抽象类的区别
    Java Garbage Collection基础详解------Java 垃圾回收机制技术详解
    数据库事物、隔离等级及数据库锁机制
    hadoop 多表join:Map side join及Reduce side join范例
    Java IO设计模式彻底分析 (转载)
    傅里叶变换的智慧[转]
  • 原文地址:https://www.cnblogs.com/jpfss/p/10058073.html
Copyright © 2011-2022 走看看