Sfl4j及logback的基本使用
Appender的内容可以和后面xml配置结合食用,眼尖的童鞋应该可以看到里面的内容和xml的标签相对应
Slf4j
是一个接口,器具体实现可有有很多其他日志(如logback、log4j等),logback与slf4j天然集成,推荐logback,官方也说这个较其他更好
引入依赖
<!--到maven仓库看-->
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-core -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>test</scope>
</dependency>
几个关键内容
Appender(在logback-core包里)
日志打印去处,包括console、file、remote socket server、MySQL、PostgreSQL、Oracle 或者其它的数据库、JMS、remote UNIX Syslog daemons
一个logger可以有多个appender
appender具有叠加性,及有本身的appender和器父logger的appender,可以通过设置 additivity = false来去掉叠加性(对root logger不适用,因为他是最高父日志)
-
Appender接口
-
UnsynchronizedAppenderBase抽象类,实现了Appender接口
-
OutPutStreamAppender类,继承了UnsynchronizedAppenderBase抽象类,是ConsoleAppender、FileAppender、RolliingFileAppender的父类
- encoder属性:设置一些输出格式
- immediateFlush属性:为true时(默认),即时刷新,可以防止一些意外原因导致日志没有输出到目的地,或保存
-
ConsoleAppender:输出到控制台,基于System.out或System.err输出
- encoder:
- target:定义System.out(默认),System.err
-
FileAppender:输出到文件,是RollingFileAppender父类
- file:设置日志输出到哪个文件,可以绝对路径,也可以相对于classpath
- encoder
- append:日志是否追加到文件中,默认true(追加)
- prudent:严格模式(依赖排他文件锁),默认false(不开启),开启了该模式的时候,会默认把append设置为true,此时日志会安全的写入文件,但耗时是平时3倍
-
RolliingFileAppender:轮转日志文件(当要区分出多个日志文件时使用,一般是防止一个文件中内容太多导致查看较难,此时需要将此文件分为多个)
- file
- append
- encoder:将日志时间转化为字节数组,并写入到输出流中
- RollingPolicy:当轮转发生时,要用这个,轮转方式移动和修改文件
- TimeBasedRollingPolicy(在RollingFileAppender标签的class的属性,支持文件自动压缩(在命名日志的时候加.zip或.gz))
- fileNamePattern(TimeBasedRollingPolicy中必配):日志文件命名规范,由文件名+%d{这个时间格式化可有可无,默认yyyy-MM-dd},轮转周期由这个推断出来,
\
和/
都会被解析为目录分隔符,%d可以有多个(但支配轮转规则的只能有一个,其余的要加上aux,用处:充当目录,方便查看) - maxHistory:设置最大日志文件数,当超过这个数量时(不能说数量,当%d格式化到日时,表示天数,为月时,表示月数),会删除掉旧的文件
- totalSizeCap:设置日志文件总大小,当超过这个大小时,会删掉旧文件。设置这个标签前必须先设置maxHistory,并且优先满足maxHistory标签
- fileNamePattern(TimeBasedRollingPolicy中必配):日志文件命名规范,由文件名+%d{这个时间格式化可有可无,默认yyyy-MM-dd},轮转周期由这个推断出来,
- SizeAndTimeBasedRoliingPolicy:
- TimeBasedRoliingPolicy的一些属性,在fileNamePattern中还可以加**%i**(和maxFileSize搭配使用,下标由0开始)
- maxFileSize:单个文件大小,当一个日志文件达到这个大小时,会生成另外一个文件,命名规则看上面(%i)
- FixedWindowRollingPolicy:根据固定窗口算法重命名文件
- fileNamePattern:必须要有%i
- minIndex:窗口索引下界
- maxindex:窗口索引上界
- TimeBasedRollingPolicy(在RollingFileAppender标签的class的属性,支持文件自动压缩(在命名日志的时候加.zip或.gz))
- triggeringPolicy:什么条件下会导致轮转
- SizeBasedTriggeringPolicy:当文件大于maxFileSize时触发
- maxFileSize:
- SizeBasedTriggeringPolicy:当文件大于maxFileSize时触发
- prudent:FixedWindowRollingPolicy不支持该属性。RollingFileAppender 在使用严格模式时要与 TimeBasedRollingPolicy结合使用,但是有两个限制:
- 在严格模式下,不允许文件压缩(我们不能让一个 JVM 在写入文件时,另一个 JVM 在压缩该文件)
- 不能对FileAppender的file属性进行设置。实际上,大多数的操作系统不允许在有进程操作文件的情况下对文件改名。其它的参考
FileAppender
Logger(在logback-classic包里)
日志接口
Layout(在logback-core包里)
日志打印样式
Level
日志的一些等级常量什么的
获取日志
//LoggerFactory,工厂方法,获取实例什么的,?可以是字符串,也可以是Class
//如果是字符串,有父子关系的话,可以用com.log表示(中间加.),log继承自com,此时如果log不定义日志级别,则默认用com的日志级别
Logger logger = LoggerFactory.getLogger(?);
获取日志本身信息
LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory();
StatusPrinter.print(lc);
定义日志级别
//不设置则默认DEBUG
logger.setLever(Level.?);
日志级别
- error
- warm
- info
- debug
- trace
配置
优先级
- logback-test.xml>logback.groovy>logback.xml>系统默配置
一些日志输出的格式
- %d{}:日期,可以不用花括号(默认yyyy-MM-dd,主要是来格式化其日期),对于不能影响轮转规则的可以**{日期格式,aux}**
- %i:对于基于大小轮转的一些轮转策略,在定义了单个文件大小限制后,可以用这个来分割日志,开始下标为0
- %thred或者**%t**:当前线程
- %logger{?}:日志名,对于用class从工厂方法获取日志的,是其全类名,花括号可以不要,主要是对其输出长度做限制(默认无限制),当限制了其长度且超出其限制时,会用包名首字母.类名显示,但有时候会把类名也取首字母(类名取首字母没搞懂,有大神指教一下吗)
- %C:取类名(全类名),也可以加花括号,和上面一致
- %M:取方法名
- %L:在多少行
- %msg:日志内容
- %n:换行
- -n:-代表左对齐,n为长度限制,当超过长度限制时,默认左对齐
xml
<!--scan为true时,会在程序运行时,如果此配置文件内容有修改,会自动扫描,其扫描周期默认为1分钟 scanPeriod可以通过这个来设置扫描周期,如果不带单位,默认毫秒-->
<configuration scan="true" scanPeriod="30 seconds">
<!--如果有日志文件有问题,这时候可能通过StatusPrinter.print()无法输出日志内部状态,可以通过设置这个来强制输出状态信息-->
<statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener"></<statusListener>
<!--设置当前配置文件的名字,当有多个配置文件时,可以通过LoggerContext lc....,lc.setName("你取的名字")来指定用哪个,setName名字必须正确,不然会报错-->
<contextName>?</contextName>
<!--后面可以通过${?}来取出值,这样便于统一配置,只需要改一处就行-->
<property name="?" value="?"></property>
<!--这里class的内容可以到依赖导入的jar包中找到对应appender类,复制其全路径-->
<appender name = "?" class = "...">
<!--当class里为FileAppender时可以设置这个,可以把日志输出到指定文件-->
<file>?</file>
<!--指定ConsoleAppend的输出方法,这里以System.out执行-->
<target>System.out</target>
<encoder>
<!--%d日期格式转化 %thread当前线程 %level日志级别(-5表示左对齐,且输出长度为5个字符) %logger日志名称 %msg日志内容-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} | %thread | %-5level | %logger{36} | %mag%n</pattern>
</encoder>
</appender>
<!--root根日志,除了root根日志外,还有其余日志,标签为logger,其余一样 level日志级别 -->
<root level="?">
<!--该日志输出位置 ref为appender标签name,表示用哪种输出-->
<appender-ref ref = "?"/>
</root>
<!--additivity="false表示不继承父日志的日志级别"-->
<logger name="?" level="?" additivity="false">
<!--该日志输出位置 ref为appender标签name,表示用哪种输出-->
<appender-ref ref = "?"/>
</logger>
<!--引入文件,file引入外部文件,为绝对路径或相对路径(一般用绝对) resource为项目中文件,classpath下全路径 url为网络链接-->
<include file="" resource="" url=""></include>
</configuration>