本篇文章前半部分都是概念性的东西,如果想直接用起来,那么动动手指划到最后哦,代码都给大家献上了🤭
目录
1.日志介绍
日志主要记录程序运行的情况,以便于程序在部署之后可以调错。健全及完整的日志在项目中是必不可少的,日志记录了系统行为的时间、地点、状态等相关信息,能够帮助我们了解并监控系统状态,同时在系统发生问题的时候,能够帮助我们快速定位,诊断并解决问题。
2.日志级别及优先级
java日志级别定义了8个级别的log,优先级从低到高分别是:ALL < TRACE < DEBUG < INFO < WARE < ERROR < FATAL < OFF。红色标注为常用到的
级别 | 名称 | 说明 |
低 到 高 | ALL | 最低等级,用于打开所有日志记录 |
TRACE | 这两种日志的规范应该由项目组自己定义,该级别日志的主要作用是对系统每一步的运行状态进行精确的记录。通过该日志可以查看某个操作的每一步执行过程,DEBUG日志也得注意规范日志格式,保证除开发人员外,其他人员例如运维和测试等也可以通过日志来定位问题。一般在项目中基本不用TRACE级别 | |
DEBUG | ||
INFO | 记录日志系统的正常运行状态,例如某个子系统的初始化,INFO日志不宜过多。 | |
WARE | 该日志表示系统可能出现的问题,对于WARE级别的日志,虽然不需要马上处理,但也要引起重视,进行及时查看和处理。这种日志尽可能不写,一般是系统日志 | |
ERROR | 该级别日志需要马上进行处理,当出现ERROR发生时,已经影响到了用户的正常访问。 | |
FATAL | 表示要立即被处理的系统级错误,要比ERROR严重。当该种错误发生时,表示服务已经出现某种程度的不可用 | |
OFF | 最高级别 用于关闭所有日志记录 |
总结:这几种日志定义,只需要简单读一读。在我所接触的项目中一般只会见到DEBUG、INFO、WARE、ERROR这四种(当然也不排除我接触的项目简单哈🤭)。在项目中除了设置控制台打印的日志,还要生成一个日志文件,日志文件中打印日志的级别、格式、大小、输出路径等等可根据自己的需求配置,具体配置方法后续会讲到。
3.常用的日志
常用的日志Logging、Commons Logging,SLF4J,Log4j,Log4j 2,Logback
(1)Logging
java自带的日志工具,从JDK1.5就有了,在java.util.logging包下。基本没人用,可以忽略
(2)Log4j
Log4j 是 Apache 的一个开源日志框架,也是市场占有率最多的一个框架。
注意:log4j 在 2015.08.05 这一天被 Apache 宣布停止维护了,用户需要切换到 Log4j2上面去。
(3)Commons Logging、SLF4J、Log4j2 、Logback之间的联系
commons-logging和slf4j是日志的门面接口,它也是Apache 最早提供的日志门面接口(门面模式是软件工程中常见的一种软件设计模式,它为子系统中的一组接口提供一个统一的高层接口,使得子系统更容易使用),可以简单的理解为接口与接口的实现,调用者只需要关注接口而无需关注具体的实现,做到解耦。log4j2和logback是具体的日志实现框架。
下图非常清晰的解释了他们之间的关系:
4.实践
先来了解在代码中添加日志的方法,两种日志接口定义方式:下面标红处需要注意二者的相似和不同
slf4j
(1) @slf4j注解 :想要用该注解 需要添加对应的依赖,如下图所示:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
(2) public static final Logger logger = LoggerFactory.getLogger(Demo2.class);
导包:
-
import org.slf4j.Logger;
-
import org.slf4j.LoggerFactory;
Commons-logging
public static final Log LOGGER = LogFactory.getLog(Demo2.class);
导包:
-
import org.apache.commons.logging.Log;
-
import org.apache.commons.logging.LogFactory;
示例一:commons-logging+log4j
--- 依赖的包;commons-logging-xx.jar,log4j-xxx.jar
现在commons-logging用的不多,就简单举个例子方便大家理解。代码如下:
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>${commons.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
package com.example.test;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class DemoApplicationTests {
public static final Log logger=LogFactory.getLog(DemoApplicationTests.class);
@Test
void contextLoads() {
logger.info("测试日志");
}
}
示例二:slf4j+log4j
注:如果@slf4j不能用那么需要给eclipse或这idea安装lomok插件
---依赖包:slf4j-api-1.7.21.jar、slf4j-log4j12-1.7.21.jar、log4j-1.2.17.jar
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
package com.example.test.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import lombok.extern.slf4j.Slf4j;
@RequestMapping("test")
@RestController
@Slf4j
public class TestController {
public static final Logger logger=LoggerFactory.getLogger(TestController.class);
@RequestMapping("/aa")
public String testMetod() {
log.info("slf4j注解打印的日志");
logger.info("哈哈");
return "哈哈";
}
}
打印结果:
示例三:slf4j+logback
---依赖包:slf4j-xxxx.jar
对于springboot项目,logback日志是自带的。直接添加@Slf4j注解,即可使用。
代码例子和示例二一样,只是只需要添加slf4j依赖
上面三个例子中,只是防止大家在项目中混掉,我之前就是导包和代码中用的没有对应起来,导致日志一直打印不出来。
5.日志的基本配置
【如何打印日志文件,以及控制台和日志文件的命名及格式】
log4j.properties
# Global logging configuration
log4j.rootLogger=info,stdout,dailyFile
# Console output...
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.org.springframework.scheduling=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
# 每天产生一个日志文件(dailyFile)
log4j.appender.dailyFile=org.apache.log4j.DailyRollingFileAppender
#当天的日志文件全路径
log4j.appender.dailyFile.File=/logs/work-order-system/log
#服务器启动日志是追加,false:服务器启动后会生成日志文件把老的覆盖掉
log4j.appender.dailyFile.Append=true
#日志文件格式
log4j.appender.dailyFile.layout=org.apache.log4j.PatternLayout
log4j.appender.dailyFile.layout.ConversionPattern=%-d{yyyy-MM-dd HH\:mm\:ss} [%c]-[%p] [%t] (%F\:%L) ->%m %n
log4j.appender.dailyFile.Threshold=INFO
#设置每天生成一个文件名后添加的名称,备份名称:年月日.log
log4j.appender.dailyFile.DatePattern='.'yyyy-MM-dd'.log'
# 每个生成的日志最大是10MB,允许生成的最多文件数量是15,达到上限后,覆盖之前的文件
log4j.appender.dailyFile.MaxFileSize=10MB
log4j.appender.dailyFile.MaxBackupIndex=10
# 输出到控制台
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%-d{yyyy-MM-dd HH\:mm\:ss} [%c]-[%p] (%F\:%L) ->%m %n
logback
推荐大家按照logback-spring.xml起名字,不要使用其他名字。因为带spring后缀的可以使用《springProfile》标签,对应application.yml配置文件。一般用在分别配置测试环境和生产环境的日志打印类别,如下图所示:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<logger name="org.springframework.web" level="INFO"/>
<logger name="org.springboot.sample" level="TRACE" />
<!-- 开发、测试环境 -->
<springProfile name="dev">
<logger name="org.springframework.web" level="INFO"/>
<logger name="org.springboot.sample" level="INFO" />
<logger name="com.taiji.sms" level="DEBUG" />
<logger name= "cn.com.qmhd" level="DEBUG" />
</springProfile>
<!-- 生产环境 -->
<springProfile name="prod">
<logger name="org.springframework.web" level="ERROR"/>
<logger name="org.springboot.sample" level="ERROR" />
<logger name="com.taiji.sms" level="ERROR" />
<logger name="cn.com.qmhd" level="ERROR" />
</springProfile>
</configuration>
常用的配置:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径 -->
<!-- 控制台输出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset class="java.nio.charset.Charset">UTF-8</charset>
</encoder>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 下面为配置只输出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.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名 -->
<fileNamePattern>/logs/safety-control-system/log_%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxHistory>14</maxHistory>
<maxFileSize>10MB</maxFileSize>
<totalSizeCap>1GB</totalSizeCap>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset class="java.nio.charset.Charset">UTF-8</charset>
</encoder>
</appender>
<!-- 日志输出级别 -->
<logger name="com.tj.scs.dao" level="DEBUG"/>
<root level="info">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
</configuration>
项目中遇到了在本地控制台可以打印出来,但是日志文件中输出不了。
解决方法:
1.先看pom的结构中有没有冲突的日志文件,因为springboot会自带日志logback,如果不排除则会起冲突 从而无法打印日志。
pom文件中排除方法如下图所示:根据你那边的具体情况排除
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.3.3.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
写这篇文章的原因是开发中遇到了日志打印不出来的问题,改了很久,后来发现是项目导包混乱的问题。觉得之前学的不细心,重新学习总结了一下。
希望我的这篇文章对你有作用,如果有什么不同的观点,欢迎留言讨论。有幸与你们相遇🤭,共同学习 共同进步,期待你的点赞哦❤