logback 集成 logstash

logback 集成 logstash

相关环境参考: Java 输出 JSON 日志

1. 添加依赖

1
2
3
4
5
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>7.2</version>
</dependency>

2. 修改logback.xml配置文件

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
<?xml version="1.0" encoding="UTF-8"?>
<!-- scan=true 支持动态更新配置文件,默认1分钟刷新一次,可以通过 scanPeriod="30 seconds" 指定刷新周期 -->
<configuration scan="true">
<!-- in the absence of the class attribute, assume ch.qos.logback.core.hook.ShutdownHook -->
<shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook">
<delay>5 seconds</delay>
</shutdownHook>

<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] - %-5level %logger:%L - %msg%n</pattern>
</encoder>
</appender>

<appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<!-- logstash tcp 服务器地址,可以配置多个地址 -->
<destination>172.30.225.232:5000</destination>
<!-- 保持连接 -->
<keepAliveDuration>5 minutes</keepAliveDuration>
<!-- 连接超时等待时间 -->
<connectionTimeout>5 seconds</connectionTimeout>
<!-- 重连延迟,默认 30s -->
<reconnectionDelay>30 second</reconnectionDelay>
<!-- 等待策略,需要测试和监控CPU找到最佳配置 -->
<!-- 文档: https://github.com/logfellow/logstash-logback-encoder#wait-strategy -->
<waitStrategyType>sleeping</waitStrategyType>
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<customFields>{"host":"${HOSTNAME}", "appname":"cloud-user"}</customFields>
</encoder>
</appender>

<root level="INFO">
<appender-ref ref="logstash"/>
<appender-ref ref="STDOUT"/>
</root>

</configuration>

3. 配置说明

如果原有配置文件中需要保留一些特殊配置时,需要理解这里的配置才能将配置应用到已有的配置中。

3.1 动态刷新

想要在应用运行时看到修改配置文件后的效果,可以在原有配置添加:

1
2
<!-- scan=true 支持动态更新配置文件,默认1分钟刷新一次,可以通过 scanPeriod="30 seconds" 指定刷新周期 -->
<configuration scan="true">

3.2 优雅关机

增加logstash配置后,为了让程序在关闭时能正确关闭相关的资源,建议配置:

1
2
3
<shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook">
<delay>5 seconds</delay>
</shutdownHook>

服务会等待5秒后执行释放资源的相关操作。

3.3 logstash appender

添加下面的配置,各部分说明看下面注释:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<!-- logstash tcp 服务器地址,可以配置多个地址 -->
<destination>IP:5000</destination>
<!-- 保持连接 -->
<keepAliveDuration>5 minutes</keepAliveDuration>
<!-- 连接超时等待时间 -->
<connectionTimeout>5 seconds</connectionTimeout>
<!-- 重连延迟,默认 30s -->
<reconnectionDelay>30 second</reconnectionDelay>
<!-- 等待策略,需要测试和监控CPU找到最佳配置 -->
<!-- 文档: https://github.com/logfellow/logstash-logback-encoder#wait-strategy -->
<waitStrategyType>sleeping</waitStrategyType>
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<customFields>{"host":"${HOSTNAME}", "appname":"cloud-user"}</customFields>
</encoder>
</appender>

这里特别说明 <customFields>{"host":"${HOSTNAME}", "appname":"cloud-user"}</customFields>

  • host 会在 json 中添加主机信息,以后有类似 POD 相关信息时,可以参考这里使用环境变量。
  • appname 定义当前的应用名,这里配置死的,后续使用容器或者POD时,也可以通过环境变量进行设置。

除此之外,还可以添加额外的自定义字段。

3.4 应用 appender

将 logstash appender 添加到某个 logger 下面,例如全局的:

1
2
3
4
<root level="INFO">
<appender-ref ref="logstash"/>
<!-- 其他 appender -->
</root>

3.5 总结

到这里可以看到,上面提供的完整配置中,没有介绍常见的 控制台输出,其他都是必要的配置。

配置正常后,就可以将日志以 JSON 形式输出到 logstash 中了,logstash 可以参考下面的配置,提供 tcp 端口的服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
input {
tcp {
port => 5000
codec => json_lines
}
}

output {
elasticsearch {
hosts => ["elasticsearch:9200"]
index => "app-%{[appname]}-%{+YYYY.MM.dd}"
}
stdout {
}
}

elasticsearch 插件文档:https://www.elastic.co/guide/en/logstash/8.5/plugins-outputs-elasticsearch.html

上面的配置会为每个 appname 创建对应的索引,在 Kibana 中的 DavaView 可以配置 app* 索引来查看所有应用的日志。

4. 代码中使用

默认情况下,代码中仍然通过 logger.info(...) 方式输出日志即可,日志的内容会作为 message 字段存储。

如果想要额外记录其他信息,全局的信息可以通过 slf4j 的 MDC 机制记录,如下:

1
2
3
4
5
//记住用slf4j,不要依赖具体的实现
//import org.slf4j.MDC;
MDC.put("xxx", "xxx");
logger.info(....);
MDC.remove("XXX");

MDC信息和线程绑定,处理不好可能会乱,logstash-logback-encoder 提供了 StructuredArguments,参考文档:

https://github.com/logfellow/logstash-logback-encoder#event-specific-custom-fields

由于这种方式依赖了具体的日志实现,需要做一层封装才适合使用。

5. Kibana 效果

5.1 索引

5.2 Data Views

5.3 Discover

对应的 JSON:

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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
{
"_index": "app-cloud-user-2022.11.26",
"_id": "qbYdsoQBuYtdaHhXAY0t",
"_version": 1,
"_score": 0,
"_source": {
"message": "hello indexStr=201, 2022-11-26T04:05:55.852Z",
"@version": "1",
"appname": "cloud-user",
"host": "liuzh-pc",
"level_value": 20000,
"config": {
"date": "2022-11-26 12:05:55",
"uuid": "dd0cedcc-82e4-4783-8bcc-09c32b2fd051"
},
"thread_name": "Thread-9",
"level": "INFO",
"dateStr": "2022-11-26T04:05:55.852Z",
"logger_name": "com.example.springbootjsonlog.SpringBootJsonLogApplication",
"@timestamp": "2022-11-26T04:05:55.852Z",
"HOSTNAME": "liuzh-pc",
"indexStr": "201"
},
"fields": {
"config.date": [
"2022-11-26 12:05:55"
],
"indexStr": [
"201"
],
"appname.keyword": [
"cloud-user"
],
"config.date.keyword": [
"2022-11-26 12:05:55"
],
"appname": [
"cloud-user"
],
"host": [
"liuzh-pc"
],
"@version": [
"1"
],
"logger_name": [
"com.example.springbootjsonlog.SpringBootJsonLogApplication"
],
"host.keyword": [
"liuzh-pc"
],
"logger_name.keyword": [
"com.example.springbootjsonlog.SpringBootJsonLogApplication"
],
"config.uuid.keyword": [
"dd0cedcc-82e4-4783-8bcc-09c32b2fd051"
],
"thread_name.keyword": [
"Thread-9"
],
"dateStr": [
"2022-11-26T04:05:55.852Z"
],
"level": [
"INFO"
],
"HOSTNAME.keyword": [
"liuzh-pc"
],
"@version.keyword": [
"1"
],
"message": [
"hello indexStr=201, 2022-11-26T04:05:55.852Z"
],
"@timestamp": [
"2022-11-26T04:05:55.852Z"
],
"HOSTNAME": [
"liuzh-pc"
],
"level.keyword": [
"INFO"
],
"level_value": [
20000
],
"thread_name": [
"Thread-9"
],
"message.keyword": [
"hello indexStr=201, 2022-11-26T04:05:55.852Z"
],
"indexStr.keyword": [
"201"
],
"config.uuid": [
"dd0cedcc-82e4-4783-8bcc-09c32b2fd051"
]
}
}

logback 集成 logstash
https://blog.mybatis.io/post/b6d231b0.html
作者
Liuzh
发布于
2022年11月26日
许可协议