springboot整合logback的误区
好多人在做springbott+logback整合的时候做了如下的引用
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
</dependency>
这并不是错的,只是这些操作多余了。
其实springboot默认已经整合了LogBack
在创建Spring Boot工程时引入的spring-boot-starter就已经包含了spring-boot-starter-logging,而spring-boot-starter-logging中引用了logback的依赖
下面翻开源码看一下
- Ctrl+鼠标右键点击
- 继续Ctrl+鼠标右键点击进入下一层
- 向下翻到大约480行左右
- 已经出现logging,继续Ctrl+右键进入下一层
下面开始介绍logback的使用
- 首先引入springboot中logback的最佳搭档 lombok
pom文件中增加 lombok 依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
- 然后编辑springboot启动类测试一下日志控制台打印
- 使用@Slf4j 注解 可以直接使用log().
package com.example.demo;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@Slf4j
@SpringBootApplication
@MapperScan({"com.example.demo.dao"})
public class DemoSpringbootMybatisApplication {
public static void main(String[] args) {
SpringApplication.run(DemoSpringbootMybatisApplication.class, args);
System.out.println("Hello Dyzz");
log.info("大眼直转!~info");
log.error("大眼直转!~error");
log.warn("大眼直转!~warn");
}
}
- 启动springboot 观察控制台输出
OK ! 调用logback打印控制台日志成功。
在springboot配置文件中的简单配置logback
编辑application.yml配置文件,增加
logging:
file: dyzz.log
level:
root: info
- 启动springboot
logback-spring.xml配置文件介绍
springboot是约定型框架,好多相关配置都是官方约定好的,比如说logback在springboot中的配置文件名
官方推荐为logback-spring.xml,当然这个命名不是spring官方拍脑袋随便给的,因为带spring后缀的配置文件可以使用这个标签。
下面介绍logback-spring.xml 相关配置
实现日志三级(info,warn,error)分开保存,日志10M三级切割,为期30天自动删除功能。
- 首先编写springboot配置文件将logback配置写入application.xml
logging:
config:
classpath: logback-spring.xml
- 然后在resources目录下创建logback-spring.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_HOME" value="/home/logs/"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度,%line:行号,%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} Line:%line ----------------> %msg%n
</pattern>
</layout>
</appender>
<!-- 按照每天生成日志文件 INFO_FILE-->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_HOME}/zyzz-info.log</file>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
<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}/zyzz-info-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<!--日志文件保留天数-->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} Line:%line ----------------> %msg%n
</pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 按照每天生成日志文件 WARN_FILE-->
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_HOME}/zyzz-warn.log</file>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/zyzz-warn-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<!--日志文件保留天数-->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} Line:%line ----------------> %msg%n
</pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 按照每天生成日志文件 ERROR_FILE-->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_HOME}/zyzz-error.log</file>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
<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}/zyzz-error-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<!--日志文件保留天数-->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} Line:%line ----------------> %msg%n
</pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<!--不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>512</queueSize>
<!--添加附加的appender,最多只能添加一个-->
<appender-ref ref="ERROR_FILE"/>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="WARN_FILE"/>
<appender-ref ref="ERROR_FILE"/>
<appender-ref ref="ASYNC"/>
</root>
</configuration>
编写测试类初步测试。
这里调用springboot 定时任务刷新一分钟日志后停止服务观察日志打印情况。
编写springboot启动类主要是为了增加定时任务
package com.example.demo;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@Slf4j
@SpringBootApplication
//定时任务
@EnableScheduling
@MapperScan({"com.example.demo.dao"})
public class DemoSpringbootMybatisApplication {
public static void main(String[] args) {
SpringApplication.run(DemoSpringbootMybatisApplication.class, args);
System.out.println("Hello Dyzz");
log.info("大眼直转!~info");
log.error("大眼直转!~error");
log.warn("大眼直转!~warn");
}
}
编写定时任务执行类–引用优快云大神趣味弄弄的注释画
package com.example.demo.scheduled;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* @author :hxg
* @ClassName DyzzScheduledService
* @date :Created in 2020/4/24 16:01
*/
@Async
@Component
@Slf4j
public class DyzzScheduledService {
@Scheduled(cron = "0/1 * * * * *")
public void DyzzScheduledForlog() {
log.info("/* .---. .-----------\n" +
"* / \\ __ / ------\n" +
"* / / \\( )/ -----\n" +
"* // ' \\/ ` ---\n" +
"* / // : : ---\n" +
"* // / / /` '--\n" +
"* // //..\\\\\n" +
"* ====UU====UU====\n" +
"* '//||\\\\`\n" +
"* ''``\n" +
"*/ \n" +
"/*\n" +
"* .-'-._\n" +
"* / e<\n" +
"* _.-'''; (\n" +
"* _______.-''-._.-' /\n" +
"* ====---:_''-' / _ _ %%%%\n" +
"* '-=. .-'` _(_)(_) %%|/%%%\n" +
"* _|_\\_ (_)(_)(_) %%%%%%%%%%\n" +
"* //\\\\//\\\\//\\\\//\\\\//\\\\%/_%%%%%%%\n" +
"* ____\\\\//\\\\//\\\\//\\\\//\\\\// |__|/__%%%\n" +
"* ________(___ \\\\/\\//\\\\//\\\\//\\\\//__//___%%%%%%%\n" +
"* / \\ \\_/ __ \\___//------\\--%%%%%%\n" +
"* _________/ \\____/ \\____/\\\\%%%%%%%%%%%%\n" +
"* \\_-%%%%%%%%\n" +
"*\n" +
"*/\n" +
"———————————————————————————————————————");
log.warn("// _,--. ,--._\n" +
"// \\ > `|>o<|' < /\n" +
"// `-. .-'\n" +
"// / 'e___e` \\\n" +
"// ( (o o) )\n" +
"// _\\_ `=' _/_\n" +
"// / /(`-._.-')\\ \\\n" +
"// / / `.___,' \\_\\\n" +
"// _/ / _____ \\ \\_\n" +
"// / _(_,--' `--._)_ \\\n" +
"// `' )______@______( `'\n" +
"// hjw / \\\n" +
"// /_________________\\\n" +
"// \\ )( /\n" +
"// \\ / \\ /\n" +
"// ) | | (\n" +
"// /`-'] [`-'\\\n" +
"// `--' `--'\n" +
"//\n" +
"————————————————————————————\n");
log.error("// _ooOoo_ \n" +
"// o8888888o \n" +
"// 88\" . \"88 \n" +
"// (| -_- |) \n" +
"// O\\ = /O \n" +
"// ____/`---'\\____ \n" +
"// . ' \\\\| |// `. \n" +
"// / \\\\||| : |||// \\ \n" +
"// / _||||| -:- |||||- \\ \n" +
"// | | \\\\\\ - /// | | \n" +
"// | \\_| ''\\---/'' | | \n" +
"// \\ .-\\__ `-` ___/-. / \n" +
"// ___`. .' /--.--\\ `. . __ \n" +
"// .\"\" '< `.___\\_<|>_/___.' >'\"\". \n" +
"// | | : `- \\`.;`\\ _ /`;.`/ - ` : | | \n" +
"// \\ \\ `-. \\_ __\\ /__ _/ .-` / / \n" +
"// ======`-.____`-.___\\_____/___.-`____.-'====== \n" +
"// `=---=' \n" +
"// \n" +
"// ............................................. \n" +
"// 佛祖保佑 永无BUG\n" +
"————————————————--------------------------------------\n" );
}
}
启动服务,观察运行结果–控制台
- 查看log存放路径
- 查看日志文件–error
- info
- warn
OK ,logback 集成测试成功。
转载至:大眼转转传送门