前言
注:此篇博客根据回顾来写,中途可能会有部分内容缺失,仅供参考 !
随着微服务架构的普及,服务被拆分成独立的单元,各自运行在不同的服务器或容器中。这带来了巨大的灵活性,但同时也让传统的日志排查方式变得异常痛苦。我们不再能简单地登录一台服务器,用 tail 和 grep 命令来分析问题。日志散落在各处,形成了一个个“信息孤岛”。
为了解决这个痛点,我们需要建立一套集中式的日志系统。它能够将所有微服务的日志汇集到一个地方,提供统一的存储、搜索和分析能力。本文将详细记录我如何为自己的 Spring Cloud 微服务集群,一步步搭建起业界最主流的 ELK(Elasticsearch, Logstash, Kibana)+ Filebeat 日志平台的全过程,包括所有必要的配置、代码,以及一路上踩过的坑。
第一章:基础设施先行 - Docker 部署 ELK Stack
在改造应用之前,我们首先需要搭建起接收和处理日志的后端平台。使用 Docker Compose 是在服务器上快速部署整个 ELK 套件的最简单方式。
1. 准备配置文件
在一台 Linux 服务器上,创建一个 elk 文件夹,并在其中创建四个个文件:
文件结构如下

docker-compose.yml:
version: '3.7'
services:
elasticsearch:
image: elasticsearch:8.9.2
container_name: elasticsearch
environment:
- discovery.type=single-node
- xpack.security.enabled=false
- xpack.ml.enabled=false
- ES_JAVA_OPTS=-Xms512m -Xmx512m
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- esdata:/usr/share/elasticsearch/data
ports:
- 9200:9200
logstash:
image: logstash:8.9.2
container_name: logstash
ports:
- 5044:5044
volumes:
- ./logstash/config:/usr/share/logstash/config
- ./logstash/pipeline:/usr/share/logstash/pipeline
depends_on:
- elasticsearch
kibana:
image: kibana:8.9.2
container_name: kibana
ports:
- 5601:5601
environment:
ELASTICSEARCH_HOSTS: http://elasticsearch:9200
volumes:
esdata:
logstash.yml:
http.host: "0.0.0.0"
xpack.monitoring.enabled: false
pipelines.yml:
- pipeline.id: main
path.config: "/usr/share/logstash/pipeline/logstash.conf"
logstash.conf:
input {
beats {
port => 5044
}
}
output {
stdout { codec => rubydebug }
elasticsearch {
hosts => ["http://elasticsearch:9200"]
index => "microservices-%{+YYYY.MM.dd}"
}
}
2. 启动 ELK
在 elk 文件夹下,执行命令一键启动:
docker-compose up -d
稍等片刻,您就可以通过 http://您的服务器IP:5601 访问 Kibana 界面了。
第二章:改造微服务 - 输出结构化 JSON 日志
这是整个方案的核心。我们需要让所有微服务的日志都以 ELK 友好的 JSON 格式输出。
1. 添加 Maven 依赖
在每一个微服务模块的 pom.xml 中,添加以下两个依赖:
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>7.4</version>
</dependency>
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
</dependency>
2. 创建 logback-spring.xml 配置文件
在每一个微服务的 src/main/resources 目录下,创建 logback-spring.xml 文件。这份配置的强大之处在于,它能自动识别 Windows 和 Linux 环境,输出到不同的日志路径。
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
<if condition='property("os.name").toLowerCase().contains("windows")'>
<then>
<property name="LOG_PATH" value="C:/logs"/>
</then>
<else>
<property name="LOG_PATH" value="/var/logs"/>
</else>
</if>
<appender name="CONSOLE_JSON" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
</encoder>
</appender>
<appender name="FILE_JSON" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${APP_NAME}/${APP_NAME}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${APP_NAME}/${APP_NAME}-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE_JSON"/>
<appender-ref ref="FILE_JSON"/>
</root>
</configuration>
注意:然后你就可以启动项目。到对应的目录看是否有日志文件产生,如果有的话,则设置成功
第三章:连接桥梁 - 使用 Filebeat 采集日志
现在,我们需要在应用服务器上部署“日志搬运工” Filebeat。
1. 安装 Filebeat:在每一台运行微服务的服务器上,下载并解压与您 ELK 版本相同的 Filebeat。
2. 配置 filebeat.yml:
# ================== Filebeat inputs ==================
filebeat.inputs:
- type: log
enabled: true
# 监控的日志文件路径,必须和 logback-spring.xml 中的路径匹配
# 根据您部署应用的服务器操作系统,选择路径配置
paths:
- 'C:/logs/*/*.log'
# JSON 和多行配置,用于正确解析您的日志
json.keys_under_root: true
json.add_error_key: true
json.message_key: message
multiline.type: pattern
multiline.pattern: '^{'
multiline.negate: true
multiline.match: after
# ================== Outputs ==================
output.logstash:
# 指向您 ELK 服务器的 IP 地址和 Logstash 端口
# 将下面的 IP 替换成您 Linux ELK 服务器的真实内网IP
hosts: ["your_elk_server_ip:5044"] # 指向您的Logstash服务器
3. 启动 Filebeat: ./filebeat -e -c filebeat.yml 或者 filebeat.exe -e -c filebeat.yml
第四章:收获成果 - 在 Kibana 中探索日志
所有准备工作就绪,现在是见证奇迹的时刻。
- 启动您的所有微服务。
- 访问 Kibana 界面 (
http://您的ELK服务器IP:5601)。 - 创建数据视图 (Data View):
- 进入
Stack Management->Data Views。 - 点击
Create data view。 - 索引模式(Index pattern)输入
microservices-*(根据您的logstash.conf配置)。 - 时间戳字段选择
@timestamp。 - 保存。
- 进入
- 探索日志:
- 进入 Discover 页面。
- 在右上角选择一个时间范围,例如“最近15分钟”。
- 您会看到所有服务的日志都已自动汇集于此!您可以使用强大的 KQL 语言进行搜索,例如
app_name: "gateway" and level: "ERROR"。
踩坑与总结
在这次集成过程中,我们遇到了几个关键问题,这里总结一下:
- Logback的
<if>标签不生效:这是因为 Logback 的条件判断功能需要一个额外的janino依赖,Spring Boot 默认不提供。 - Logback的
<providers>语法过时:在新版的logstash-logback-encoder(7.x+) 中,<providers>标签已被废弃,应直接在<encoder>下使用<provider>或更简洁的<pattern>。 - Logback的XML解析错误:
EmptyStackException通常由不可见的特殊字符或不匹配的 XML 标签导致,需要仔细检查或用纯净的模板替换。
结语
至此,我们的集中式日志系统就完全搭建完成了。从日志的产生、格式化、收集、处理到最终的可视化查询,形成了一个完整的闭环。这套体系将是您未来排查线上问题、进行数据分析的强大武器。

评论区