Logback学习笔记

2019-01-17  本文已影响0人  无知者云

知识点

案例项目

└── src
    └── main
        ├── java
        │   └── davenkin
        │       └── parent
        │           ├── Parent.java
        │           ├── child1
        │           │   └── Child1.java
        │           └── child2
        │               └── Child2.java
        └── resources
            └── logback.xml

Github地址: https://github.com/davenkin/logback-learning

其中Parent中main函数分别输出Parent,Child1和Child2的日志。

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="ROOT_FILE" class="ch.qos.logback.core.FileAppender">
        <file>root.log</file>
        <append>true</append>
        <encoder>
            <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="ROOT_FILE"/>
    </root>
</configuration>
package davenkin.parent;

import davenkin.parent.child1.Child1;
import davenkin.parent.child2.Child2;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Parent {
    private static final Logger logger = LoggerFactory.getLogger(Parent.class);

    public static void main(String[] args) {
        logger.info("info from parent");
        logger.debug("debug from parent");
        new Child1().hello();
        new Child2().hello();
    }

}

package davenkin.parent.child1;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Child1 {
    private static final Logger logger = LoggerFactory.getLogger(Child1.class);

    public void hello() {
        logger.info("info from child1");
        logger.debug("debug from child1");
    }
}
package davenkin.parent.child2;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Child2 {
    private static final Logger logger = LoggerFactory.getLogger(Child2.class);

    public void hello() {
        logger.info("info from child2");
        logger.debug("debug from child2");
    }
}

常用配置

以上例子是一个常见的日志配置,其中:没有为任何Logger显式配置Level与additivity属性,而只是配置了一个root logger,即表示所有日志最终都会打到root logger所对应的appender中,日志同时打到了命令行和文件中。root logger的Level设置成了INFO,表示debug的日志请求不会得到输出。这样的配置常见于生产环境,因为很多第三方类库都会输出大量的debug日志,这样会使得我们正常的INFO级别的业务记录日志淹没在debug日志中。

此时的命令行输出日志如下:

09:03:01.304 INFO  davenkin.parent.Parent - info from parent
09:03:01.306 INFO  davenkin.parent.child1.Child1 - info from child1
09:03:01.306 INFO  davenkin.parent.child2.Child2 - info from child2

为某个package下的日志设置单独的Level

有时为了调试方便,我们可能需要将某个package下的debug或者trace日志输出,比如在用Spring的WebserviceTemplate时,我们希望打印出请求和返回的XML数据,那么此时便可以显式地为对应logger设置Level:

   <logger name="org.springframework.ws.client.MessageTracing">
    <level value="TRACE"/> 
   </logger>
   <logger name="org.springframework.ws.server.MessageTracing">
    <level value="TRACE"/> 
   </logger>

对应到上面的案例项目,如果我们希望child1包下能够打印出debug级别的日志,那么可以修改logback.xml文件,在其中显式配置logger:

  <logger name="davenkin.parent.child1">
        <level value="DEBUG"/>
    </logger>

此时输出日志中便包含了child1下的DEBUG日志,但是不包含其他package下的DEBUG日志:

09:09:10.935 INFO  davenkin.parent.Parent - info from parent
09:09:10.938 INFO  davenkin.parent.child1.Child1 - info from child1
09:09:10.938 DEBUG davenkin.parent.child1.Child1 - debug from child1
09:09:10.938 INFO  davenkin.parent.child2.Child2 - info from child2

将不同logger的日志打入到不同的文件中

有时我们希望将某些logger的日志输出到单独的文件中,比如在做性能测试时,需要将所有性能测试的日志输出到perfomance.log中,这时需要为性能测试专门创建一个logger,比如名为perfomance-logger,我们需要做3件事情:

Logger performanceLogger = LoggerFactory.getLogger("performance-logger");
   <appender name="PERFORMANCE_LOG" class="ch.qos.logback.core.FileAppender">
        <file>performance.log</file>
        <encoder>
            <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
    </appender>

    <logger name="performance-logger" level="DEBUG" additivity="false">
        <appender-ref ref="PERFORMANCE_LOG"/>
    </logger>

对于,上面的例子项目,加入Child3:

package davenkin.parent.child3;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Child3 {
    private static final Logger logger = LoggerFactory.getLogger("performance-logger");

    public void hello() {
        logger.debug("debug from performance");
    }
}

在logback.xml中加入以下配置:


    <appender name="PERFORMANCE_LOG" class="ch.qos.logback.core.FileAppender">
        <file>performance.log</file>
        <append>true</append>
        <encoder>
            <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
    </appender>

    <logger name="performance-logger" level="DEBUG" additivity="false">
        <appender-ref ref="PERFORMANCE_LOG"/>
    </logger>

再修改Parent让其输出Child3的日志:

 public static void main(String[] args) {
        logger.info("info from parent");
        logger.debug("debug from parent");
        new Child1().hello();
        new Child2().hello();
        new Child3().hello();
    }

得到命令行输出:

09:38:58.301 INFO  davenkin.parent.Parent - info from parent
09:38:58.304 INFO  davenkin.parent.child1.Child1 - info from child1
09:38:58.304 DEBUG davenkin.parent.child1.Child1 - debug from child1
09:38:58.304 INFO  davenkin.parent.child2.Child2 - info from child2

可以看到,命令行中不包含performance日志,而在performance.log中得到了performance日志:

198  [main] DEBUG performance-logger - debug from performance

将不同Level的日志打到不同文件中

可以通过配置Filter的方式将不同Level的日志打到不同的文件中,Filter是配置在Appender中的,具体参考这里这里

最佳实践

    private static final Logger LOG = LoggerFactory.getLogger(Foo.class);
catch (NoSuchMethodException e) { LOG.error("Blah", e); throw e; }
上一篇 下一篇

猜你喜欢

热点阅读