侧边栏壁纸
  • 累计撰写 38 篇文章
  • 累计创建 8 个标签
  • 累计收到 3 条评论

目 录CONTENT

文章目录

微服务可观测性实战:从零搭建 ELK + Filebeat 集中式日志平台,告别 grep 时代

Administrator
2025-07-22 / 0 评论 / 0 点赞 / 248 阅读 / 0 字
温馨提示:
本文最后更新于2026-04-28,若内容或图片失效,请留言反馈。 部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

前言

注:此篇博客根据回顾来写,中途可能会有部分内容缺失,仅供参考 !
随着微服务架构的普及,服务被拆分成独立的单元,各自运行在不同的服务器或容器中。这带来了巨大的灵活性,但同时也让传统的日志排查方式变得异常痛苦。我们不再能简单地登录一台服务器,用 tailgrep 命令来分析问题。日志散落在各处,形成了一个个“信息孤岛”。

为了解决这个痛点,我们需要建立一套集中式的日志系统。它能够将所有微服务的日志汇集到一个地方,提供统一的存储、搜索和分析能力。本文将详细记录我如何为自己的 Spring Cloud 微服务集群,一步步搭建起业界最主流的 ELK(Elasticsearch, Logstash, Kibana)+ Filebeat 日志平台的全过程,包括所有必要的配置、代码,以及一路上踩过的坑。


第一章:基础设施先行 - Docker 部署 ELK Stack

在改造应用之前,我们首先需要搭建起接收和处理日志的后端平台。使用 Docker Compose 是在服务器上快速部署整个 ELK 套件的最简单方式。

1. 准备配置文件

在一台 Linux 服务器上,创建一个 elk 文件夹,并在其中创建四个个文件:
文件结构如下
image

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 中探索日志

所有准备工作就绪,现在是见证奇迹的时刻。

  1. 启动您的所有微服务。
  2. 访问 Kibana 界面 (http://您的ELK服务器IP:5601)。
  3. 创建数据视图 (Data View)
    • 进入 Stack Management -> Data Views
    • 点击 Create data view
    • 索引模式(Index pattern)输入 microservices-* (根据您的 logstash.conf 配置)。
    • 时间戳字段选择 @timestamp
    • 保存。
  4. 探索日志
    • 进入 Discover 页面。
    • 在右上角选择一个时间范围,例如“最近15分钟”。
    • 您会看到所有服务的日志都已自动汇集于此!您可以使用强大的 KQL 语言进行搜索,例如 app_name: "gateway" and level: "ERROR"

image-1753162386468

踩坑与总结

在这次集成过程中,我们遇到了几个关键问题,这里总结一下:

  • Logback的<if>标签不生效:这是因为 Logback 的条件判断功能需要一个额外的 janino 依赖,Spring Boot 默认不提供。
  • Logback的<providers>语法过时:在新版的 logstash-logback-encoder (7.x+) 中,<providers> 标签已被废弃,应直接在 <encoder> 下使用 <provider> 或更简洁的 <pattern>
  • Logback的XML解析错误EmptyStackException 通常由不可见的特殊字符或不匹配的 XML 标签导致,需要仔细检查或用纯净的模板替换。

结语

至此,我们的集中式日志系统就完全搭建完成了。从日志的产生、格式化、收集、处理到最终的可视化查询,形成了一个完整的闭环。这套体系将是您未来排查线上问题、进行数据分析的强大武器。

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区