目录
四、 springboot+logback 部署到 Linux 服务器上
一、常见的日志框架
日志抽象框架:
- JCL
- SLF4j:与 Log4j 和 Logback 同源
- jboss-logging
日志实现框架:
- Log4j:存在性能问题
- JUL
- Log4j2:apache公司出品,但与其他框架的兼容性不足
- Logback
最终选择:
抽象框架: SLF4j 实现框架: Logback
二、日志输出格式解析
格式:
- %d: 表示日期时间
- %thread: 表示线程名
- %-5level: 级别从左显示5个字符宽度
- %logger{50}:表示 logger 名字最长50个字符,否则按照句点分割
- %msg: 日志消息
- %n:换行符
例子:
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} === [%thread] === %-5level === %logger{50} === %msg%n
三、SpringBoot 整合logback日志框架
3.1 查看是否需要引入 logback
springboot 框架默认引入了 logback 相关的依赖,我们无需专门引入 logback。
下图中可以看出,在 spring-boot-stater 中就已经将 logback 引入了
3.2 整合 logback
3.2.1 增加配置文件
在 resources 下新增 logback-spring.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<!-- scan="true" 开启自动扫描
scanPeriod="30 seconds" 设置自动扫描时间 30s一次
-->
<configuration scan="true" scanPeriod="30 seconds">
<!-- 定义日志目录的路径 -->
<property name="LOG_PATH" value="logs"/>
<!--设置系统日志目录-->
<property name="APPDIR" value="app"/>
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 日志记录器,日期滚动记录 -->
<appender name="FILEINFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 主动创建文件!!! -->
<file>${LOG_PATH}/api.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/info/api-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>50MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} - %logger{50} %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 此日志文件只记录info级别以上的 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
</appender>
<logger name="org.springframework.aop.aspectj" level="ERROR"/>
<logger name="org.mongodb" level="ERROR"/>
<logger name="io.netty" level="ERROR"/>
<logger name="org.redisson" level="ERROR"/>
<logger name="org.springframework" level="ERROR"/>
<logger name="org.tio.client.TioClient" level="ERROR"/>
<!-- <root level="DEBUG"> -->
<root level="INFO">
<appender-ref ref="FILEINFO"/>
<appender-ref ref="STDOUT"/>
</root>
</configuration>
3.2.2 使用和测试
编写一个控制器进行测试
@Controller
public class HelloController {
// 使用日志工厂生成这个类的日志对象,并使用
private Logger logger = LoggerFactory.getLogger(this.getClass());
@RequestMapping("/testlog")
@ResponseBody
public void testLog() {
logger.trace("这是trace日志...");
logger.debug("这是debug日志...");
logger.info("这是info日志...");
logger.warn("这是warn日志...");
logger.error("这是error日志...");
}
}
调用请求:
结果为:
3.2.3 开启 logback 自动重新加载配置文件
在生成环境中,需要根据实际情况决定日志的开启级别。当线上正常运行时由于写日志会消耗一定的服务器性能,故日志级别应调到 WARN ,只打印必要日志。
那么当出现问题时,我们要如何通过日志来获取更多信息呢?相较于修改日志配置文件,并重启服务器,logback 支持我们自动重新加载配置文件,无需重启服务器。
<?xml version="1.0" encoding="UTF-8"?>
<!-- scan="true" 开启自动扫描
scanPeriod="30 seconds" 设置自动扫描时间 30s一次
-->
<configuration scan="true" scanPeriod="30 seconds">
......
......
......
</configuration>
四、 springboot+logback 部署到 Linux 服务器上
4.1 外置 tomcat
4.1.1 修改依赖文件
由于 springboot 自带了 tomcat,故使用外置 tomcat 时,需要修改 pom.xml 文件,去掉自带的 tomcat,并将打包方式改为 war 包。
// pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
...
<!-- 修改打包格式为 war ->
<packaging>war</packaging>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
......
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 去掉内置的tomcat ->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 引入servlet容器的支持 ->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
......
</dependencies>
<build>
<!-- 可以通过 finalName 指定打包后的项目名 ->
<finalName>sp</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
4.1.2 修改启动类
// 继承 SpringBootServletInitializer 类
@SpringBootApplication
public class SpringbootJdbc01Application extends SpringBootServletInitializer {
// 重写配置方法
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(SpringbootJdbc01Application.class);
}
public static void main(String[] args) {
SpringApplication.run(SpringbootJdbc01Application.class, args);
}
}
4.1.3 打包
放到服务器上的 tomcat 中,并运行 tomcat
发出请求测试
4.1.4 动态重新加载日志配置文件
进入 tomcat 下 webapp 内,找到
/usr/local/tomcat/webapps/sp/WEB-INF/classes
修改 root 定义的日志级别
等待设置的时间后,重新测试
4.2 使用 springboot 自带的 tomcat
4.2.1 修改启动类
// 继承 SpringBootServletInitializer 类
@SpringBootApplication
public class SpringbootJdbc01Application extends SpringBootServletInitializer {
// 重写配置方法
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(SpringbootJdbc01Application.class);
}
public static void main(String[] args) {
SpringApplication.run(SpringbootJdbc01Application.class, args);
}
}
4.2.2 将配置文件移动到 Linux 服务器上
包括:
- application.properties: springboot 配置文件
- logback-spring.xml:日志配置文件
- start.sh:启动脚本
- stop.sh:关闭脚本
- logs:日志目录
- sp.war:打出的包
start.sh:
#!bin/sh
CRTDIR=/opt/lincya
nohup java -jar /opt/lincya/sp.war --spring.config.location=${CRTDIR}/application.properties --logging.config=${CRTDIR}/logback-spring.xml > /dev/null 2>&1 &
while( [ ! -e ${CRTDIR}/logs/api.log ] )
do
echo 'Wait for the api.log file to be generated...'
/usr/bin/sleep 2
done
tail -f ${CRTDIR}/logs/api.log
stop.sh:
#!bin/sh
CRTDIR=/opt/lincya
count=`ps -ef | grep sp.war | grep -v "grep" | wc -l`
if [ $count -gt 0 ]; then
echo "准备停止sp服务...."
ps -ef | grep sp.war | grep -v "grep" | awk '{printf $2}' | xargs kill -9
sleep 2
DATE=`date +%Y-%m-%d-%H-%M` #获取当前系统时间
if [ -e ${CRTDIR}/logs/api.log ]; then
mv ${CRTDIR}/logs/api.log ${CRTDIR}/logs/api_${DATE}.log
fi
echo "sp服务已停止"
else
echo "服务已处理停止状态,无需停止!"
fi
4.2.3 启动/关闭项目
相关命令:
# 给 start 和 stop 文件赋予执行权限
chmod +711 start.sh stop.sh
# 启动
sh start
# 关闭
sh stop
开启成功,使用8090端口访问
调用接口:
4.2.4 动态加载日志文件配置
直接修改外部的日志配置文件
等待30秒,重新请求,不再显示info信息