前言

最近做项目的时候遇到一个问题,那就是程序运行的时候,怎么拿到控制台刚刚打印的日志,来做一些需求。甚至跨服务如何获取别的服务控制台打印的日志。这次我来分享一个非常简单的方法,使用目前最为常用的logback。2分钟即可搞定~

导入依赖

依赖只需要导入2个logback的依赖就可以

1
2
3
4
5
6
7
8
9
10
11
<!--在logback-core基础上扩展的版本-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>

<!--logback基础模块-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>

自定义Appender

我们要收集控制台的日志,可以自定义一个Appender来实现。继承AppenderBase,AppenderBase是Appender接口的抽象类。重写append方法。参数ILoggingEvent就是我们想要的东西。有的时候我们可能只需要获取项目中的某一个类中的某一个方法的某一行日志。这些我们都可以自定义,通过包名、日志等级、甚至可以用日志开头信息来进行更细致化的筛选我们想要收集的日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class LogAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {

private static final Logger logger = LoggerFactory.getLogger(LogAppender.class);

@Override
protected void append(ILoggingEvent event) {
// 获取包名
String loggerName = event.getLoggerName();
// 获取日志等级
Level level = event.getLevel();
// 获取日志信息
String message = event.getMessage();

if ("ERROR".equals(level.toString())) {
logger.info("追踪到日志:");
logger.info("包名:" + loggerName);
logger.info("日志等级:" + level);
logger.info("日志信息:" + message);
}

}
}

logback配置

最后一步,我们需要加载我们刚刚写的Appender。在logback中引入我们刚刚自定义Appender,在root中引用就可以。那么我们如何跨服务收集控制台日志呢?同理,在对应服务的logback配置中也加载我们自定义的Appender就可以了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<?xml version="1.0" encoding="UTF-8"?>
<configuration>

<contextName>logback</contextName>

<!-- 日志的输出目录 -->
<property name="log.path" value="D:/logback" />

<!--控制台日志格式:彩色日志-->
<property name="CONSOLE_LOG_PATTERN"
value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) %highlight([%-5level]) %green(%logger) %msg%n"/>

<!--文件日志格式-->
<property name="FILE_LOG_PATTERN"
value="%date{yyyy-MM-dd HH:mm:ss} [%-5level] %thread %file:%line %logger %msg%n" />

<!--编码-->
<property name="ENCODING"
value="UTF-8" />


<!-- 控制台日志 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
</appender>

<!-- 文件日志 -->
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${log.path}/log.log</file>
<append>true</append>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
</appender>

<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">

<!-- 要区别于其他的appender中的文件名字 -->
<file>${log.path}/log-rolling.log</file>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>


<!-- 设置滚动日志记录的滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志归档路径以及格式 -->
<fileNamePattern>${log.path}/info/log-rolling-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--归档日志文件保留的最大数量-->
<maxHistory>15</maxHistory>

<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>1KB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>

</appender>

<!--自定义Appender 追踪控制台日志-->
<appender name="getConsoleLog" class="com.sora.logback.appender.LogAppender"></appender>

<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
<appender-ref ref="getConsoleLog" />
</root>
</configuration>

结果

这里我设置了项目启动后打印2条日志,分别是WARN级别和ERROR级别的

1
2
3
4
5
6
7
8
9
10
11
@Component
public class PrintLog implements ApplicationRunner {

private static final Logger logger = LoggerFactory.getLogger(PrintLog.class);

@Override
public void run(ApplicationArguments args) throws Exception {
logger.warn("启动后打印INFO日志!");
logger.error("启动后打印ERROR日志!");
}
}

可以看到我们的2条日志正常打印,然后自定义的Appender经过过滤,只获取ERROR的日志。需求实现~

image-20221022160030909

收集控制台日志就是这么简单,下次见😎