美文网首页
Log4J/Logback

Log4J/Logback

作者: 米刀灵 | 来源:发表于2016-10-14 12:23 被阅读103次

    slf4j是一系列的日志接口,而log4j logback是具体实现了的日志框架。slf4j译为简单日志门面(The Simple Logging Facade for Java ),是日志框架的抽象。而log4j和logback是众多日志框架中的几种。也就是说我们在具体开发中,需要绑定一个日志框架,才能正常的使用slf4j。
    而log4j和logback就是两个受欢迎的日志框架。

    • log4j是apache实现的一个开源日志组件。(Wrapped implementations)
    • logback同样是由log4j的作者设计完成的,拥有更好的特性,用来取代log4j的一个日志框架。是slf4j的原生实现。(Native implementations)

    log4j例子:
    pom.xml中添加:

    <!-- log4j support -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    

    添加log4j.properties:
    对于Java app, log4j.properties文件放在 project/classes/ 目录。
    对于Java web applications, log4j.properties文件放在 WEB-INF/classes/或src/main/resource/ 目录。
    1.根日志的级别定义为 DEBUG,并将名为 stdout,D,E 的 appender 添加其上。

    log4j.rootLogger = debug,stdout,D,E
    

    2.将名为 stdout,D,E 的 appender 设置为合法的 appender。

    log4j.appender.stdout = org.apache.log4j.ConsoleAppender
    

    3.设置 appender stdout,D,E 的 layout。

    完整例子:

     ### 设置###
    log4j.rootLogger = debug,stdout,D,E
    
    ### 输出信息到控制抬 ###
    log4j.appender.stdout = org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.Target = System.out
    log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
    
    ### 输出DEBUG 级别以上的日志到=/home/duqi/logs/debug.log ###
    log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
    log4j.appender.D.File = /home/duqi/logs/debug.log
    log4j.appender.D.Append = true
    log4j.appender.D.Threshold = DEBUG 
    log4j.appender.D.layout = org.apache.log4j.PatternLayout
    log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
    
    ### 输出ERROR 级别以上的日志到=/home/admin/logs/error.log ###
    log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
    log4j.appender.E.File =/home/admin/logs/error.log 
    log4j.appender.E.Append = true
    log4j.appender.E.Threshold = ERROR 
    log4j.appender.E.layout = org.apache.log4j.PatternLayout
    log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
    

    使用:
    日志分别记录到了控制台(三条),debug.log(两条)和error.log(一条)。

    public class Log4JTest {
        private static final Logger logger = LoggerFactory.getLogger(Log4JTest.class);
    
        public static void main(String[] args) {
            // 记录debug级别的信息
            logger.debug("This is debug message.");
            // 记录info级别的信息
            logger.info("This is info message.");
            // 记录error级别的信息
            logger.error("This is error message.");
            /*try{
                  obj.divide();
              }catch(ArithmeticException ex){
                  logger.error("Sorry, something wrong!", ex);
            }*/
        }
    

    配置文件:
    log4j.rootLogger = [ level ] , appenderName, appenderName, …
    日志级别从低到高为:ALL,TRACE,DEBUG,INFO,WARN,ERROR,FATAL。比如定义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来。如果不在appender中过滤自己的level(大于等于root level),默认使用rootLogger的level。

    log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
    Log4j提供的appender有以下几种:

    • org.apache.log4j.ConsoleAppender(控制台),
    • org.apache.log4j.FileAppender(文件),
    • org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),
    • org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件),
    • org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

    log4j.appender.D.layout = org.apache.log4j.PatternLayout
    Appender的layout有以下几种:

    • org.apache.log4j.HTMLLayout(以HTML表格形式布局),
    • org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
    • org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
    • org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
    其他参数
    记录Mybatis语句:
    如果你的应用部署在一个包含Commons Logging的环境(如:Tomcat,Websphere), 而你又想用其他的日志框架,你可以通过在MyBatis的配置文件mybatis-config.xml里面添加一项setting(配置)来选择一个不同的日志实现。
    在ApplicationConetxt.xml中:
    <configuration>  
        <properties>  
            <property name="dialect" value="mysql" />  
        </properties>  
        <settings>  
            <setting name="logImpl" value="LOG4J" />    
        </settings>  
    </configuration> 
    

    log4j.properties:

    log4j.rootLogger=info,stdout
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender  
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  
    log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] -%m%n  
    # 打印sql语句:debug; 执行结果:trace
    ## 指定mapper配置文件中的namespace
    log4j.logger.MyMapperNS =TRACE
    

    mapper的配置文件:

    <mapper namespace="MyMapperNS.user">
        <select id="selectUser" parameterType="int" resultType="User">  
            <![CDATA[  
                select * from user where id = #{id}  
            ]]>
        </select>
    </mapper>  
    

    你也可以只记录一个方法:log4j.logger.org.mybatis.example.BlogMapper.user.selectUser=TRACE
    与此相对,可以对一组mapper接口记录日志,只要对mapper接口所在的包开启日志功能即可:

    log4j.logger.MyMapperNS=TRACE
    

    某些查询可能会返回大量的数据,只想记录其执行的SQL语句该怎么办?为此,Mybatis中SQL语 句的日志级别被设为DEBUG(JDK Logging中为FINE),结果日志的级别为TRACE(JDK Logging中为FINER)。所以,只要将日志级别调整为DEBUG即可达到目的:

    log4j.logger.MyMapperNS=DEBUG
    

    logback例子:
    pom.xml添加依赖

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.13</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.1.7</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.1.7</version>
        </dependency>
    

    用法和slf4j+logback一致:

        import org.slf4j.Logger;
        import org.slf4j.LoggerFactory;
        public class SimpleDemo {
    
            private static final Logger logger = LoggerFactory.getLogger(SimpleDemo.class);
    
            public static void main(String[] args) {
                logger.info("111");
                logger.debug("222");
                logger.error("3333");
                logger.trace("4444");
            }
        }
    

    配置文件logback.xml。文件须放下在 resources 根目录下,文件名不能修改:

        <?xml version="1.0" encoding="UTF-8"?>
        <!-- 根标签 -->
        <!-- 三个属性 
             scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
            scanPeriod: 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
            debug: 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 
        -->
        <configuration scan="true" scanPeriod="30 seconds">
    
            <!-- 用来全局定义变量值,它有两个属性name和value,通过<property>定义的值会被插入到logger上下文中,可以使“${}”来使用变量 -->
            <!-- 日志文件保存路径 -->
            <property name="logPath" value="d:\\log"/>
    
    
            <!-- 子节点<appender>:负责写日志的组件,它有两个必要属性name和class。name指定appender名称,class指定appender的全限定名-->
           <!-- ConsoleAppender 把日志输出到控制台,有以下子节点:  -->
    
            <!-- 控制台输出 -->
            <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
                <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                    <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
                    <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
                </encoder>
            </appender>
    
            <!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。有以下子节点:
              <file>:被写入的文件名,可以是相对目录,也可以是绝对目录,如果上级目录不存在会自动创建,没有默认值。
              <append>:如果是 true,日志被追加到文件结尾,如果是 false,清空现存文件,默认是true。    
              <rollingPolicy>:当发生滚动时,决定RollingFileAppender的行为,涉及文件移动和重命名。属性class定义具体的滚动策略类-->
             <!-- 记录日志文件 -->
            <appender name="testLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
                <file>${logPath}/test.log</file>
                <append>true</append>
                <!-- class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy": 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动。有以下子节点:
                    <fileNamePattern>:必要节点,包含文件名及“%d”转换符,“%d”可以包含一个java.text.SimpleDateFormat指定的时间格式,如:%d{yyyy-MM}。
                    如果直接使用 %d,默认格式是 yyyy-MM-dd。RollingFileAppender的file字节点可有可无,通过设置file,可以为活动文件和归档文件指定不同位置,当前日志总是记录到file指定的文件(活动文件),活动文件的名字不会改变;
                    如果没设置file,活动文件的名字会根据fileNamePattern 的值,每隔一段时间改变一次。“/”或者“\”会被当做目录分隔符。     
                -->
                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                    <!--日志文件输出的文件名-->
                    <FileNamePattern>${logPath}/TestWeb.log.%d{yyyy-MM-dd}.log</FileNamePattern>
                    <!-- <maxHistory>可选节点,
                        控制保留的归档文件的最大数量,超出数量就删除旧文件。
                        假设设置每个月滚动,且<maxHistory>是6,则只保存最近6个月的文件,删除之前的旧文件。
                        注意,删除旧文件是,那些为了归档而创建的目录也会被删除。
                     -->
                    <!--日志文件保留天数-->
                    <MaxHistory>30</MaxHistory>
                </rollingPolicy>
                <!-- 
                    <encoder>:对记录事件进行格式化。负责两件事,一是把日志信息转换成字节数组,二是把字节数组写入到输出流。
                    PatternLayoutEncoder 是唯一有用的且默认的encoder ,
                    有一个<pattern>节点,用来设置日志的输入格式。使用“%”加“转换符”方式,如果要输出“%”,则必须用“\”对“\%”进行转义。
                 -->
                <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                    <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
                    <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
                </encoder>
                <!--日志文件最大的大小-->
                <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
                    <MaxFileSize>10MB</MaxFileSize>
                </triggeringPolicy>
            </appender>
    
            <!-- 
                子节点<loger>:用来设置某一个包或具体的某一个类的日志打印级别、以及指定<appender>。
                <loger>仅有一个name属性,一个可选的level和一个可选的addtivity属性。
                可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个loger
                name: 用来指定受此loger约束的某一个包或者具体的某一个类。
                level: 用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL和OFF,还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。 如果未设置此属性,那么当前loger将会继承上级的级别。
                addtivity: 是否向上级loger传递打印信息。默认是true。同<loger>一样,可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个loger。
             -->
            <logger name="testLog" additivity="false" level="INFO">
                <appender-ref ref="STDOUT" />//大小写敏感,和appender的name一致
                <appender-ref ref="testLogAppender" />
            </logger>
    
            <!-- 
                子节点<root>:它也是<loger>元素,但是它是根loger,是所有<loger>的上级。
                只有一个level属性,因为name已经被命名为"root",且已经是最上级了。
                level: 用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL和OFF,
                不能设置为INHERITED或者同义词NULL。 默认是DEBUG。    
             -->
            <!-- 日志输出级别 -->
            <root level="INFO">
                <appender-ref ref="STDOUT" />
            </root>
        </configuration>
    

    其他:
    避免重复打印日志,浪费磁盘空间,务必在log4j.xml中设置additivity=false。additivity默认为true,即通过该logger输出的日志会同时输出到root logger,如果还为该logger指定了独立的appender,就会导致这部分日志重复输出。

    异常信息应该包括两类信息:案发现场信息和异常堆栈信息。如果不处理,那么通过关键字throws往上抛出。
    正例:

        logger.error(各类参数或者对象toString + "_" + e.getMessage(), e);             
    

    记录异常日志的常见错误:

        logger.error(e);
        logger.error(e.getMessage());
        logger.error("上下文"+e.getMessage());        
    

    上面这几种都是错的!请确保使用的是两个入参的API,如error(String s, Throwable t)。


    参考:
    https://mengkang.net/594.html
    http://www.jianshu.com/p/c6c543e4975e
    http://wiki.jikexueyuan.com/project/log4j/logging-files.html
    https://www.mkyong.com/logging/log4j-hello-world-example/

    相关文章

      网友评论

          本文标题:Log4J/Logback

          本文链接:https://www.haomeiwen.com/subject/wbvgyttx.html