什么是日志框架
日志框架的选择
Logback的使用与配置
定制输出目标
定制输出格式
携带上下文信息
运行时选择性输出
灵活的配置
优秀的性能
一般都有一个日志门面和一个日志实现,具体各类如下:
这么多日志框架,我们应该使用哪一个好呢?
我们用排除法,一个一个来
JUL:来自官方,实现过于简陋,经常被吐槽
jboss-logging:诞生就不是为了服务大众
SLF4J、log4j、Logback都是同一个人ceki写的。
为什么写三个呢?
那是因为ceki先写了log4j,但后面觉得log4j太烂了,他已经不想改了。
所以后面写了logback。
log4j2呢,从设计上来说很优秀,但太优秀了,太先进了,很多开源框架对其支持有限。(log4j2性能优于logback,但为了有高性能,设计得过于复杂,没必要,用logback就够了)
现在到了SLF4J和JCL的选择了。
SLF4J和logback是同一个作者写的,所以兼容性更好!!所以选择SLF4J不选JCL.
下面来一个测试案例:
package com.lbl; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; /** * Created by 廖师兄 * 2017-06-02 17:44 */ @RunWith(SpringRunner.class) @SpringBootTest @Slf4j public class LoggerTest { @Test public void test1() { log.debug("debug..."); log.error("error..."); log.warn("warn..."); } }运行结果:
有人可以会有两人问题:
为什么可以不用定义log变量,就可以直接使用log.debug("debug...");而不报错明明写了3条语句,为什么只输出了两条呢?问题一的解释:
问题二的解释:
首先,我们来看一下slog4j的源码:
可以看到有5个级别,而默认是info级别的。也就是说默认只会输出权值比info大的日志级别(包括info级别)
简单说,就是默认会输出info、warn、error这三个级别的日志。
说到这里,可能大家会发现了,如果是info级别,那么比info级别更高级别的日志,也会输出。
运行结果如下:
有两种配置方法:
application.ymllogback-spring.xml需求:
区分info和error日志每天产生一个日志文件修改console参数console: "%d - %msg%n"
还是上面的代码,没有做任何配置(其实前面的图片是已经配置过了的,我现在把配置都删除),运行图:
第一种方法:配置application.yml
配置完后的运行效果:(明显,少了很多东西)
配置path参数的目录path: F:/project/sell/logTest
如图:
再次运行上面的测试方法后,在logTest文件夹多了个spring.log的日志文件
打开看,可以看到是比较完整的日志格式。
设置file参数file: /var/log/tomcat/sell.log
如下图所示配置
运行效果:
修改level参数level: debug
默认info级别的springboot启动时如图:
配置整个项目为debug级别之后:
运行效果:
将root修改为debug之后,启动时,debug会输出很多文字,明显发现项目的启动速度都变慢了
运行效果:
一般都是用这第二种方法,使用logback-spring.xml文件,这种文件一般直接拷过来用就可以了。
修改一下路径,到指定路径就ok
<?xml version="1.0" encoding="UTF-8" ?> <configuration> <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern> %d - %msg%n </pattern> </layout> </appender> <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>DENY</onMatch> <onMismatch>ACCEPT</onMismatch> </filter> <encoder> <pattern> %msg%n </pattern> </encoder> <!--滚动策略--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--路径--> <fileNamePattern>F:/project/sell/log/info.%d.log</fileNamePattern> </rollingPolicy> </appender> <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ERROR</level> </filter> <encoder> <pattern> %msg%n </pattern> </encoder> <!--滚动策略--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--路径--> <fileNamePattern>F:/project/sell/log/error.%d.log</fileNamePattern> </rollingPolicy> </appender> <root level="info"> <appender-ref ref="consoleLog" /> <appender-ref ref="fileInfoLog" /> <appender-ref ref="fileErrorLog" /> </root> </configuration>