<!-- logback+slf4j --> <!-- slf4j依赖 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.6.0</version> <type>jar</type> <scope>compile</scope> </dependency> <!-- logback依赖 --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>0.9.28</version> <type>jar</type> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>0.9.28</version> <type>jar</type> </dependency>
<listener> <listener-class>ch.qos.logback.ext.spring.web.LogbackConfigListener</listener-class> </listener> <context-param> <param-name>logbackConfigLocation</param-name> <param-value>classpath:logback.xml</param-value> </context-param>
注意: logback.xml的文件html
<?xml version="1.0" encoding="UTF-8"?> <!-- 从高到地低 OFF 、 FATAL 、 ERROR 、 WARN 、 INFO 、 DEBUG 、 TRACE 、 ALL --> <!-- 日志输出规则 根据当前ROOT 级别,日志输出时,级别高于root默认的级别时 会输出 --> <!-- 如下 每一个配置的 filter 是过滤掉输出文件里面,会出现高级别文件,依然出现低级别的日志信息,经过filter 过滤只记录本级别的日志--> <!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false --> <!-- scan:配置文件若是发生改变,是否被从新加载,默认为true。 --> <!-- scanPeriod:设置检测配置文件是否有修改的时间间隔,若是没有给出时间单位,默认单位是毫秒,默认的时间间隔为1分钟。当scan为true时,此属性生效。 --> <configuration debug="true" scan="true" scanPeriod="30 seconds"> <!--定义变量--> <property name="APP_NAME" value="instSite" /> <!-- PROJECT_NAME=项目名称 LOG_HOME=日志输出 LOG_LEVEL=日志级别 --> <contextName>${APP_NAME}</contextName> <!-- 时间戳定义,timeReference:使用日志产生日期为时间基准 --> <timestamp key="byDay" datePattern="yyyy-MM-dd" timeReference="contextBirth"/> <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径,可使用系统变量 --> <!--<property name="LOG_OUTPUT" value="日志输入路径"/>--> <!-- ===================================================================== --> <!-- 如下是appender的定义 --> <!-- ===================================================================== --> <!-- 控制台输出,生产环境将请stdout去掉 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- 过滤器,一个appender能够有多个 --> <!-- 阈值过滤,就是log行为级别过滤,debug及debug以上的信息会被打印出来 --> <!--ThresholdFilter: 临界值过滤器,过滤掉低于指定临界值的日志。当日志级别等于或高于临界值时,过滤器返回NEUTRAL;当日志级别低于临界值时,日志会被拒绝。例如:过滤掉全部低于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变量,你们可打开该pattern进行输出观察 --> <!-- <pattern> %d{yyyy-MM-dd HH:mm:ss} [%level] - %msg%n Logger: %logger Class: %class File: %file Caller: %caller Line: %line Message: %m Method: %M Relative: %relative Thread: %thread Exception: %ex xException: %xEx nopException: %nopex rException: %rEx Marker: %marker %n </pattern> --> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度,%msg:日志消息,%n是换行符 --> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> <!--<pattern>%d %contextName %msg%n</pattern>--> <!--<pattern>%-4d [%green(%thread)] %highlight(%-5level) %cyan(%logger).%-10method - %message%n</pattern>--> </encoder> </appender> <!-- ===================================================================== --> <!-- 按照天天生成日志文件 --> <!--RollingFileAppender起做用,必须同时设置 RollingPolicy 和 TriggeringPolicy。不过,若是 RollingPolicy 也实现了 TriggeringPolicy 接口,那么只须要设置 RollingPolicy。--> <appender name="OTHER_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 日志输出文件 --> <file>${LOG_HOME}/${PROJECT_NAME}.log</file> <!-- 追加日志到原文件结尾,默认为true --> <append>true</append> <!--<filter>标签。 过滤器,执行一个过滤器会有返回个枚举值,即DENY,NEUTRAL,ACCEPT其中之一。 返回DENY,日志将当即被抛弃再也不通过其余过滤器; 返回NEUTRAL,有序列表里的下个过滤器过接着处理日志; 返回ACCEPT,日志会被当即处理,再也不通过剩余过滤器。 过滤器被添加到<Appender> 中,为<Appender> 添加一个或多个过滤器后,能够用任意条件对日志进行过滤。<Appender> 有多个过滤器时,按照配置顺序执行。 --> <!--不打印 INFO and ERROR 级别的日志--> <!--LevelFilter: 级别过滤器,根据日志级别进行过滤。若是日志级别等于配置级别,过滤器会根据onMath 和 onMismatch接收或拒绝日志。--> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!--设置过滤级别--> <level>INFO</level> <!--用于配置符合过滤条件的操做--> <onMatch>DENY</onMatch> <!--用于配置不符合过滤条件的操做--> <onMismatch>NEUTRAL</onMismatch> </filter> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>DENY</onMatch> <onMismatch>ACCEPT</onMismatch> </filter> <!-- timebasedrollingpolicy:演示时间和大小为基础的日志文件归档 --> <!--RollingPolicy,负责滚动。第二个是 TriggeringPolicy,决定是否以及什么时候进行滚动--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 归档的日志文件的路径,例现在天是2013-12-21日志,当前写的日志文件路径为file节点指定。 --> <!--能够将此文件与file指定文件路径设置为不一样路径,从而将当前日志文件或归档日志文件置不一样的目录。 --> <!--而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 --> <!-- 文件滚动日期格式:天天:.YYYY-MM-dd(默认);每星期:.YYYY-ww;每个月:.YYYY-MM --> <!-- 每隔半天:.YYYY-MM-dd-a;每小时:.YYYY-MM-dd-HH;每分钟:.YYYY-MM-dd-HH-mm --> <!-- %i 第几个文件,固定大小后,同一天可能有多个--> <!--"fileNamePattern"表明归档(滚动)记录文件的文件名模式。该选项是必需的,且必需在模式的某处包含标志"%i"--> <fileNamePattern>${LOG_HOME}/${PROJECT_NAME}.log.%d{yyyy-MM-dd}-%i</fileNamePattern> <!-- 控制归档文件的最大数量的保存,删除旧的文件,默认单位天数 --> <MaxHistory>30</MaxHistory> <!-- 设置当前日志的文件的大小,决定日志翻滚 --> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <!-- 除按日志记录以外,还配置了日志文件不能超过200M(默认),若超过200M,日志文件会以索引0开始, --> <maxFileSize>200MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <!-- encoders 做用是将logger事件转换成字节数组,并将字节数组写入到输出流--> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %class{50} #%line - %msg%n</pattern> <charset>utf-8</charset> </encoder> </appender> <!-- 能够写多个日志文件appender,而后区分多个模块的日志 或者 分离不一样级别的日志 --> <appender name="INFO_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/${PROJECT_NAME}_info.log</file> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/${PROJECT_NAME}_info.log.%d{yyyy-MM-dd}-%i</fileNamePattern> <MaxHistory>30</MaxHistory> <!--日志文件最大的大小 --> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>200MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %class{50} #%line - %msg%n</pattern> <charset>utf-8</charset> </encoder> </appender> <appender name="ERROR_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/${PROJECT_NAME}_error.log</file> <!--过滤到ERROR级别的日志--> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/${PROJECT_NAME}_error.log.%d{yyyy-MM-dd}-%i</fileNamePattern> <MaxHistory>30</MaxHistory> <!--日志文件最大的大小 --> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>200MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %class{50} #%line - %msg%n</pattern> <charset>utf-8</charset> </encoder> </appender> <!-- ===================================================================== --> <!-- FileAppender 输出到文件 --> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <!-- 文件存放位置 %{xxx} 就是以前定义的属性xxx --> <file>${LOG_HOME}/myApp1log-${byDay}.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>${LOG_HOME}/test.html</file> </appender> <!-- ===================================================================== --> <!-- 如下是logger的定义 --> <!-- ===================================================================== --> <!-- Root logger的定义 --> <!-- root, 只有在level及以上级别的日志会被输出 --> <!-- 例如: 当root level设置为INFO时, appender DEBUG中没法获取到DEBUG级别的日志事件, 则DEBUG日志信息也不会写入debug.log中. --> <root> <level value="${LOG_LEVEL}"/> <appender-ref ref="STDOUT"/> </root> <!-- 为单独的包配置日志级别,若root的级别大于此级别, 此处级别也会输出 应用场景:生产环境通常不会将日志级别设置为trace或debug,可是为详细的记录SQL语句的状况, 可将hibernate的级别设置为debug,如此一来,日志文件中就会出现hibernate的debug级别日志, 而其它包则会按root的级别输出日志,OFF 不输出日志 --> <logger name="org.hibernate.SQL" level="OFF"/> <logger name="org.hibernate.jdbc" level="DEBUG"/> <logger name="org.springframework" level="DEBUG"/> <!-- 指定一个包,name必填,additivity选填:控制是否继承父类appender,默认true --> <!-- level选填,若是没有指定从最近的父类继承,顶级为root的级别 --> <logger name="com.jv.messagecenter.servlet" level="DEBUG" additivity="true"> <level>debug</level> <appender-ref ref="INFO_LOG"/> <appender-ref ref="ERROR_LOG"/> <appender-ref ref="OTHER_LOG"/> <appender-ref ref="FILE"/> <appender-ref ref="HTMLFILE"/> </logger> </configuration>
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF(屏蔽),java
EvaluatorFilter: 求值过滤器,评估、鉴别日志是否符合指定条件。有一会儿节点:<evaluator>:鉴别器,经常使用的鉴别器是JaninoEventEvaluato,也是默认的鉴别器,它以任意的java布尔值表达式做为求值条件,求值条件在配置文件解释过成功被动态编译,布尔值表达式返回true就表示符合过滤条件web
自定义过滤器spring
import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.filter.Filter; import ch.qos.logback.core.spi.FilterReply; public class LinkinFilter extends Filter<ILoggingEvent>{ @Override public FilterReply decide(ILoggingEvent event) { if (event.getMessage().contains("LinkinPark")) { return FilterReply.ACCEPT; }else{ return FilterReply.DENY; } } }
logback内置的日志字段仍是比较少,自定义的一些数据,须要借助logback MDC机制,,即将一些运行时的上下文数据经过logback打印出来;此时咱们须要借助org.sl4j.MDC类。api
MDC类基本原理其实很是简单,其内部持有一个InheritableThreadLocal实例,用于保存context数据,MDC提供了put/get/clear等几个核心接口,用于操做ThreadLocal中的数据;ThreadLocal中的K-V,能够在logback.xml中声明,最终将会打印在日志中。数组
logback 中 MDC 的过滤器session
ch.qos.logback.classic.helpers.MDCInsertingServletFilter
一个 Spring 的环绕切面app
@Around("execution(* com.wuage.payway.shared.api.account.service.*.*(..))") public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint){ MDC.put("sessionId", UUID.randomUUID().toString()); System.out.println("环绕通知的目标方法名 Start:"+proceedingJoinPoint.getSignature().getName()); try { Object obj = proceedingJoinPoint.proceed(); return obj; } catch (Throwable throwable) { throwable.printStackTrace(); } MDC.remove("sessionId"); // MDC.clear(); return null; }
<pattern>%X{sessionId} %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %class{50} #%line - %msg%n</pattern>
logback的官方网站: http://logback.qos.chdom
SLF4J的官方网站:http://www.slf4j.orgide
LogBack中文手册
http://blog.csdn.net/shift_alt_ctrl/article/details/69944606
https://my.oschina.net/CasparLi/blog/822253
http://www.cnblogs.com/softidea/p/5642174.html
http://blog.csdn.net/u011794238/article/details/50770557#t7
http://blog.csdn.net/u011794238/article/details/50767869