ELK(Elasticsearch + Logstash + Kibana + Filebeat)采集方案

一、准备条件

  • 已安装:Docker ≥ 20.x、Docker Compose 插件docker compose 命令)

  • 本机一个日志目录(示例:/abs/path/to/logs)。里边有你的 Logback JSON 文件,如:
    logback-demo.json.log(行级 JSON,包含 message/level/timestamp/traceId/... 字段)

如果你用的是我上一条给的 Spring Boot + Logback 配置,只要确定它的 JSON 日志落在这个目录即可。

二、目录结构(复制即可)

在任意空文件夹(例如 elk-stack/)里创建如下结构与文件:

elk-stack/

├─ docker-compose.yml

├─ .env

├─ logstash/

│ └─ pipeline/

│ └─ logstash.conf

└─ filebeat/

└─ filebeat.yml

三、.env(版本与路径)

HOST_LOG_DIR 改成你 日志目录的绝对路径(很重要)

复制代码
# Elasticsearch / Kibana / Logstash 统一版本
STACK_VERSION=8.12.2

# ES 堆大小(本机内存够可以调大)
ES_JAVA_OPTS=-Xms1g -Xmx1g

# Kibana 映射的端口
KIBANA_PORT=5601

# Logstash 映射的端口(Beats 输入)
LOGSTASH_BEATS_PORT=5044

# 你的日志目录(绝对路径)
HOST_LOG_DIR=/abs/path/to/logs

四、docker-compose.yml(核心编排,一键启动)

复制代码
version: "3.9"

services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
    container_name: es
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false   # 本地演示禁用安全,生产请开启
      - ES_JAVA_OPTS=${ES_JAVA_OPTS}
    ulimits:
      memlock:
        soft: -1
        hard: -1
    ports:
      - "9200:9200"
    volumes:
      - esdata:/usr/share/elasticsearch/data

  kibana:
    image: docker.elastic.co/kibana/kibana:${STACK_VERSION}
    container_name: kibana
    depends_on:
      - elasticsearch
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
      - XPACK_SECURITY_ENABLED=false
    ports:
      - "${KIBANA_PORT}:5601"

  logstash:
    image: docker.elastic.co/logstash/logstash:${STACK_VERSION}
    container_name: logstash
    depends_on:
      - elasticsearch
    ports:
      - "${LOGSTASH_BEATS_PORT}:5044"
    volumes:
      - ./logstash/pipeline:/usr/share/logstash/pipeline:ro

  filebeat:
    image: docker.elastic.co/beats/filebeat:${STACK_VERSION}
    container_name: filebeat
    user: root
    depends_on:
      - logstash
    volumes:
      # 你的日志目录挂载到容器内 /logs
      - ${HOST_LOG_DIR}:/logs:ro
      # Filebeat 配置
      - ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
      # 容器读取宿主机文件需要访问 docker 的 meta(可选)
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
    command: ["--strict.perms=false"]

volumes:
  esdata:

五、Logstash Pipeline(解析 JSON 并写 ES)

html 复制代码
input {
  beats {
    port => 5044
    codec => "json"   # Filebeat 已经传 JSON,这里再保险
  }
}

filter {
  # 如果你的 JSON 在 message 字段里而不是最外层,请用 json 过滤器解开:
  # json { source => "message" }

  # 规范化时间戳(如果有 @timestamp 就跳过)
  if !("@timestamp" in [@metadata]) and [timestamp] {
    date {
      match => ["timestamp", "ISO8601", "yyyy-MM-dd HH:mm:ss,SSS", "UNIX_MS"]
      target => "@timestamp"
      remove_field => ["timestamp"]
    }
  }

  # 统一字段名与类型(可按你的日志做适配)
  mutate {
    rename => { "level" => "log.level" }
    rename => { "logger" => "log.logger" }
    rename => { "thread" => "process.thread.name" }
    # 保留示例字段:traceId/spanId/app/env/message
  }

  # 简单去除无用字段示例
  mutate {
    remove_field => ["host", "agent", "ecs", "log.flags"]
  }
}

output {
  elasticsearch {
    hosts => ["http://elasticsearch:9200"]
    index => "app-logs-%{+YYYY.MM.dd}"
    # 模板/ILM 可后续加,这里先简单跑通
  }
  # 便于调试
  stdout { codec => rubydebug }
}

六、Filebeat(采集你的 JSON 文件并输送到 Logstash)

html 复制代码
filebeat.inputs:
  - type: filestream
    id: app-json-logs
    enabled: true
    paths:
      - /logs/*.json.log
      - /logs/**/*.json.log
    parsers:
      - ndjson:
          # 如果你的日志每行就是 JSON(logback JSON Encoder),开启 ndjson
          overwrite_keys: true
          add_error_key: true
          # 如果你的 JSON 行里 time 字段叫 "timestamp",这里可以映射到 @timestamp
          # 但我们在 Logstash 里做了统一处理,这里可以不配
    ignore_older: 72h
    close_inactive: 5m

output.logstash:
  hosts: ["logstash:5044"]

# 关闭 elastic-agent 管理
features:
  # 禁用云、k8s自动发现等高级特性(本地演示用)
  monitoring.enabled: false

说明

  • 如果你的日志不是每行一个 JSON(比如普通文本),也能采,不过建议把 Logback 输出改为 JSON,更利于结构化检索。

  • 如果你已有 Filebeat 生产配置,可直接把 output 指到本 Logstash。

七、启动(一步到位)

复制代码
cd elk-stack
docker compose pull
docker compose up -d
健康检查:
html 复制代码
# ES
curl http://localhost:9200
# Kibana(浏览器打开)
# http://localhost:5601

确认 Filebeat、Logstash 日志:

复制代码
docker logs -f filebeat
docker logs -f logstash
看到 Filebeat 发现文件、Logstash 输出“elasticsearch output succeeded”之类即 OK。

八、产生日志(两种方式)

  1. 你的应用 :确保它把 JSON 日志写到 .env 里的 HOST_LOG_DIR 目录。

    例如 Spring Boot 示例,执行后访问接口触发日志:

复制代码
curl "http://localhost:8080/api/hello?name=Alice"
curl "http://localhost:8080/api/hello?name=oops"

2.快速模拟器(可选):临时生成一些 JSON 行用来验证采集。

在 HOST_LOG_DIR 下生成文件并持续写入

html 复制代码
mkdir -p /abs/path/to/logs
bash -c 'while true; do \
  echo "{\"level\":\"INFO\",\"logger\":\"demo.producer\",\"thread\":\"main\",\"message\":\"hello\",\"app\":\"demo\",\"traceId\":\""$(uuidgen | tr -d - | cut -c1-16)"\",\"env\":\"dev\",\"timestamp\":\""$(date -u +"%Y-%m-%dT%H:%M:%S.%3NZ")"\"}"; \
  sleep 1; \
done >> /abs/path/to/logs/demo.json.log'

九、在 Kibana 里看日志

  1. 打开浏览器:http://localhost:5601

  2. 左侧 Discover → 创建 Data View

    • Nameapp-logs

    • Index patternapp-logs-*

    • Timestamp field :选择 @timestamp

  3. 保存后即可看到实时入库的日志。

  4. 常用查询(KQL)示例:

    • log.level: "ERROR"

    • app: "logback-demo"

    • traceId: "abcd1234*"

十、常见问题排查

  • Kibana 看不到索引 :确认 Logstash 是否在往 app-logs-* 写入(看容器日志 / curl 索引)

    curl "http://localhost:9200/_cat/indices?v"

  • Filebeat 无法读取 :确认本机日志目录是绝对路径 并已挂载到容器 /logs,文件权限可读。

  • 时间乱序 :确保你的 JSON 带有正确的 UTC 时间,或让 Logstash date 过滤器按格式解析。

复制代码
相关推荐
864记忆3 小时前
项目名称:烟酒进销存管理系统
java
纪莫3 小时前
技术面:SpringBoot(启动流程、如何优雅停机)
java·spring·java面试⑧股
吃饭最爱3 小时前
redis的基础知识
1024程序员节
数据智能老司机3 小时前
OpenSearch 权威指南——OpenSearch 概览
elasticsearch·搜索引擎·aws
weixiao04303 小时前
Linux网络 NAT、代理服务、内⽹穿透
1024程序员节
Merrick3 小时前
亲手操作Java抽象语法树
java·后端
初级程序员Kyle4 小时前
开始改变第三天 Java并发(1)
java·后端
B站_计算机毕业设计之家4 小时前
基于大数据的游戏数据可视化分析与推荐系统 Steam游戏 电子游戏 娱乐数据 Flask框架 selenium爬虫 协同过滤推荐算法 python✅
大数据·python·深度学习·游戏·信息可视化·1024程序员节·steam