logback 入门

零. Logback 概述 
Logback 的诞生就是为了取代当下最火的 Log4j

Logback 的架构足够通用所以可以应用于不同环境。当前,Logback 被切为三个模块, logback-core,logback-classic and logback-access.

logback-core 是其他两个模块的公共基础模块。logback-classic 可以认为是一个加强版的 log4j。而且,logback-classic 原生实现 SLF4J API ( 即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统。)所以你可以方便地切换 logback 和其他的日志框架,比如 log4j。

logback-access 模块和 Servlet 容器集成,如 Tomcat 和 Jetty,来提供 HTTP 访问 log 的功能。我们可以 logback-core 上建立自己的模块。


一. 行为级别
OFFFATALERRORWARNINFODEBUGALL

当选择了其中一个级别,则该级别向下的行为是不会被打印出来。
举个例子,当选择了INFO级别,则INFO以下的行为则不会被打印出来。


二. slf4j 和 logback 配置

第一步引入jar包
slf4j-api
logback-core

logback-classic(原生实现 SLF4J API

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.wenniuwuren</groupId>
    <artifactId>something</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.12</version>
        </dependency>
        <!-- logback -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.1.3</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.1.3</version>
        </dependency>
    </dependencies>
</project>




第二步编写简单的logback配置文件

<!-- scan 是否定期扫描xml文件, scanPeriod是说扫描周期是30秒-->
<configuration scan="true" scanPeriod="30 seconds" debug="false" packagingData="true">
    <!-- 项目名称 -->
    <contextName>myApp1 contextName</contextName>
    <!-- 属性 -->
    <property name="USER_HOME" value="./log"/>

    <!-- Insert the current time formatted as "yyyyMMdd'T'HHmmss" under
       the key "bySecond" into the logger context. This value will be
       available to all subsequent configuration elements. -->
    <timestamp key="bySecond" datePattern="yyyyMMdd" timeReference="contextBirth"/>

    <!-- appender很重要,一个配置文件会有多个appender -->
    <!-- ConsoleApperder意思是从console中打印出来 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 过滤器,一个appender可以有多个 -->
        <!-- 阈值过滤,就是log行为级别过滤,debug及debug以上的信息会被打印出来 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>debug</level>
        </filter>

        <!-- encoders are assigned the type
             ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
        <!-- encoder编码规则 -->
        <encoder>
            <!--<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>-->
            <!--<pattern>%d %contextName %msg%n</pattern>-->
            <!-- pattern模式 %d时间 %thread 线程名 %level行为级别 %logger logger名称 %method 方法名称 %message 调用方法的入参消息 -->
            <pattern>%-4d [%thread] %highlight%-5level %cyan%logger.%-10method - %message%n</pattern>
        </encoder>
    </appender>

    <!-- FileAppender 输出到文件 -->
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <!-- 文件存放位置 %{xxx} 就是之前定义的属性xxx -->
        <file>${USER_HOME}/myApp1log-${bySecond}.log</file>

        <encoder>
            <!-- %date和%d是一个意思 %file是所在文件 %line是所在行 -->
            <pattern>%date %level [%thread] %logger{30} [%file:%line] %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 输出到HTML格式的文件 -->
    <appender name="HTMLFILE" class="ch.qos.logback.core.FileAppender">
        <!-- 过滤器,这个过滤器是行为过滤器,直接过滤掉了除debug外所有的行为信息 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>debug</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>

        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <!-- HTML输出格式 可以和上边差不多 -->
            <layout class="ch.qos.logback.classic.html.HTMLLayout">
                <pattern>%relative%thread%mdc%level%logger%msg</pattern>
            </layout>
        </encoder>
        <file>${USER_HOME}/test.html</file>
    </appender>

    <!-- 滚动日志文件,这个比较常用 -->
    <appender name="ROLLINGFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 当project等于true的时候file就不会起效果-->
        <prudent>true</prudent>
        <!--<file>${USER_HOME}/logFile.log</file>-->
        <!-- 按天新建log日志 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- daily rollover -->
            <fileNamePattern>${USER_HOME}/logFile.%d{yyyy-MM-dd}_%i.log</fileNamePattern>
            <!-- 保留30天的历史日志 -->
            <maxHistory>30</maxHistory>

            <!-- 基于大小和时间,这个可以有,可以没有 -->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- or whenever the file size reaches 100MB -->
                <!-- 当一个日志大小大于10KB,则换一个新的日志。日志名的%i从0开始,自动递增 -->
                <maxFileSize>10KB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>

        <encoder>
            <!-- %ex就是指抛出的异常,full是显示全部,如果在{}中写入数字,则表示展示多少行 -->
            <pattern>%-4date [%thread] %-5level %logger{35} - %msg%n%ex{full, DISPLAY_EX_EVAL}</pattern>
        </encoder>
    </appender>

    <!-- 重点来了,上边都是appender输出源。这里开始就是looger了 -->
    <!-- name意思是这个logger管的哪一片,像下面这个管的就是log/test包下的所有文件 level是只展示什么行为信息级别以上的,类似阈值过滤器 additivity表示是否再抛出事件,就是说如果有一个logger的name是log,如果这个属性是true,另一个logger就会在这个logger处理完后接着继续处理 -->
    <logger name="log.test" level="INFO" additivity="false">
        <!-- 连接输出源,也就是上边那几个输出源 ,你可以随便选几个appender-->
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="ROLLINGFILE"/>
        <appender-ref ref="HTMLFILE"/>
    </logger>
    <!-- 这个logger详细到了类 -->
    <logger name="log.test.Foo" level="debug" additivity="false">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="ROLLINGFILE"/>
        <appender-ref ref="HTMLFILE"/>
    </logger>

    <!-- Strictly speaking, the level attribute is not necessary since -->
    <!-- the level of the root level is set to DEBUG by default.       -->
    <!-- 这就是上边logger没有管到的情况下 root默认接管所有logger -->
    <root level="debug">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

文件位置位于src/main/resources下,名字默认为logback.xml
当然,logback也支持groovy格式的配置文件,如果你会用那更好。
调用一下logger:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by hzzhuyibin on 2016/7/28.
 */
public class LogbackTest {
    static Logger logger = LoggerFactory.getLogger(LogbackTest.class);
    public static void main (String[] args) {
        logger.debug("hi logback");

        logger.debug("bye logback");

        try {
            int i = 1 / 0;

        } catch (Exception e) {
            logger.error("error:", e);
        }
    }
}


最后的结果是:
Connected to the target VM, address: '127.0.0.1:54896', transport: 'socket'
2016-07-28 14:43:41,283 [main] DEBUG LogbackTest.main       - hi logback
2016-07-28 14:43:41,287 [main] DEBUG LogbackTest.main       - bye logback
Disconnected from the target VM, address: '127.0.0.1:54896', transport: 'socket'
2016-07-28 14:43:41,290 [main] ERROR LogbackTest.main       - error:
java.lang.ArithmeticException: / by zero
    at LogbackTest.main(LogbackTest.java:21) ~[classes/:na]

Process finished with exit code 0


三. 过滤器的使用
Logback的过滤器基于三值逻辑,允许把它们组装或成链,从而组成任意的复合过滤策略。过滤器很大程度上受到Linux的iptables启发。这里的所谓三值逻辑是说,过滤器的返回值只能是ACCEPT、DENY和NEUTRAL的其中一个。
如果返回DENY,那么记录事件立即被抛弃,不再经过剩余过滤器;
如果返回NEUTRAL,那么有序列表里的下一个过滤器会接着处理记录事件;
如果返回ACCEPT,那么记录事件被立即处理,不再经过剩余过滤器。

不输出包含 bye 字符的日志:
package com.wenniuwuren;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.spi.FilterReply;

/**
 * Created by hzzhuyibin on 2016/7/28.
 */
public class SomeLogFilter extends Filter<ILoggingEvent> {


    @Override
    public FilterReply decide(ILoggingEvent iLoggingEvent) {
        if (iLoggingEvent.getMessage().contains("bye")) {
            return FilterReply.DENY;
        }
        return FilterReply.ACCEPT;
    }
}

可以选择任意几个输出源加入这个filter
比如我加到 STDOUT 输出源里:
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- 过滤器,一个appender可以有多个 -->
    <!-- 阈值过滤,就是log行为级别过滤,debug及debug以上的信息会被打印出来 -->
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>debug</level>
    </filter>
    <filter class="com.wenniuwuren.SomeLogFilter" />
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <!-- encoder编码规则 -->
    <encoder>
        <!--<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>-->
        <!--<pattern>%d %contextName %msg%n</pattern>-->
        <!-- pattern模式 %d时间 %thread 线程名 %level行为级别 %logger logger名称 %method 方法名称 %message 调用方法的入参消息 -->
        <pattern>%-4d [%thread] %highlight%-5level %cyan%logger.%-10method - %message%n</pattern>
    </encoder>
</appender>

最后程序日志结果: 可以看到 bye 日志消失
Connected to the target VM, address: '127.0.0.1:55111', transport: 'socket'
2016-07-28 15:02:27,218 [main] DEBUG com.wenniuwuren.LogbackTest.main       - hi logback
Disconnected from the target VM, address: '127.0.0.1:55111', transport: 'socket'
2016-07-28 15:02:27,227 [main] ERROR com.wenniuwuren.LogbackTest.main       - error:
java.lang.ArithmeticException: / by zero
    at com.wenniuwuren.LogbackTest.main(LogbackTest.java:22) ~[classes/:na]

Process finished with exit code 0


四. 控制第三方框架日志输出
logback.xml 中
<logger name="org.mybatis" level="WARN"/>
<logger name="org.springframework" level="WARN"/>
<logger name="org.apache.shiro.web" level="WARN"/>
<logger name="org.quartz.core" level="WARN"/>



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值