Java应用运行过程中会产生大量业务日志和异常日志,分散在各个服务器节点上,排查问题时需要逐个登录服务器查看,效率很低。将Java生成的日志统一发送到ELK栈,就能实现日志的集中管理、快速检索和可视化分析,大幅降低运维和排查成本。

环境准备
首先需要准备好基础的ELK环境,确保Elasticsearch、Logstash、Kibana都处于正常运行状态,同时确认Java应用的运行环境为JDK8及以上版本。如果是本地测试,可以用Docker快速拉取ELK相关镜像启动服务,生产环境建议单独部署各个组件并做好高可用配置。
添加项目依赖
Java项目通常使用Logback作为日志框架,需要添加对应的Logstash适配依赖,让日志可以直接输出到Logstash。如果是Maven项目,在pom.xml中添加以下依赖:
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>7.4</version>
</dependency>配置Logback输出到Logstash
在项目的resources目录下创建或修改logback.xml配置文件,添加Logstash的appender,配置日志的输出格式和Logstash的接收地址。示例配置如下:
<configuration>
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<!-- Logstash的TCP接收地址,根据实际部署的地址修改 -->
<destination>127.0.0.1:5044</destination>
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<!-- 自定义字段,方便后续检索 -->
<customFields>{"app_name":"java-demo","env":"test"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="LOGSTASH" />
<appender-ref ref="CONSOLE" />
</root>
</configuration>配置Logstash接收日志
在Logstash的配置目录下创建新的配置文件,比如java-log.conf,设置输入为TCP端口,过滤日志字段,输出到Elasticsearch。配置示例如下:
input {
tcp {
port => 5044
codec => json_lines
}
}
filter {
# 可以添加字段过滤、格式转换等处理逻辑
if [level] == "ERROR" {
mutate {
add_tag => ["error_log"]
}
}
}
output {
elasticsearch {
hosts => ["127.0.0.1:9200"]
index => "java-log-%{+YYYY.MM.dd}"
}
}验证日志收集效果
启动Logstash加载新配置,然后启动Java项目,在代码中打印几条测试日志:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogTest {
private static final Logger logger = LoggerFactory.getLogger(LogTest.class);
public static void main(String[] args) {
logger.info("这是一条测试info日志");
logger.error("这是一条测试error日志,用于验证错误日志收集");
}
}日志打印后,打开Kibana,在索引管理页面创建匹配java-log-*的索引模式,之后就能在Discover页面看到刚才打印的日志,还可以根据app_name、level等字段进行检索和过滤。
常见问题处理
- 如果日志没有出现在Kibana中,先检查Logstash的端口是否和Logback配置的destination一致,防火墙是否开放了对应端口
- 日志字段缺失的话,检查Logstash的filter配置是否正确,或者Logback的customFields是否配置有误
- 大量日志发送失败的话,可以考虑给Logstash添加队列配置,避免日志丢失