Spring Boot 接入 ELK 时,先验证应用到 Logstash,再接 Elasticsearch 和 Kibana。这样在 Kibana 查不到日志时,就能分清是没收到事件、没写进索引,还是查询条件选错了。
Spring Boot 输出 JSON 日志
引入 net.logstash.logback:logstash-logback-encoder,版本按项目的 Java、Logback 和 Jackson 选择。原笔记的 Spring Boot 2.5.15 与 encoder 7.3 属于当时的环境记录,新项目按兼容表选版本。
<!-- logback-spring.xml -->
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<springProperty name="logstashDestination" source="app.logstash.destination"
defaultValue="127.0.0.1:5044"/>
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>${logstashDestination}</destination>
<encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="LOGSTASH"/>
</root>
</configuration>
如果应用和 Logstash 在同一 Compose 网络,设置 APP_LOGSTASH_DESTINATION=logstash:5044。容器里的 127.0.0.1 指向自身。保留控制台输出,Logstash 不可达时还可以从应用容器里看日志。
先让 Logstash 打印收到的事件
input {
tcp {
port => 5044
codec => json_lines
}
}
output {
stdout { codec => rubydebug }
}
启动后在应用里打一条 log.info("elk-smoke-check");,再运行 docker compose logs --tail=100 logstash。如果事件里能看到 message、level 和时间字段,就确认了输入和 JSON 解码。json_lines 用来处理 TCP 流里的换行分隔 JSON。
接入 Elasticsearch 和 Kibana
接下来配置 Elasticsearch output。启用安全机制的 Elasticsearch 需要认证和受信任的 CA,凭据可放在环境变量或 Logstash keystore。日志入口和数据库端口放在私有网络。
写入后,在 Kibana Discover 选择与实际索引相符的 Data View,例如 application-logs-*,时间字段选 @timestamp,再搜索测试日志。Logstash 有事件但索引没有写入时,优先查 output 的认证、证书和索引权限。索引已有数据但 Discover 空白,就检查 Data View 与时间范围。
Logstash Logback Encoder 兼容说明 · JSON Lines Codec · Elasticsearch Output