Logstash —— 服务端日志 ETL 与解析管道

运维监控软件手册 04-日志监控与分析 21.6 KB 原文

Logstash —— 服务端日志 ETL 与解析管道

分类:04 日志监控与分析 适用:日志集中处理层;日均 GB~TB 级、需复杂解析/富化/多路分发;Linux/容器/K8s 一句话:基于 JVM 的开源数据处理管道,用 input → filter → output 把原始日志清洗成结构化事件再送往 ES/Kafka 官方:https://www.elastic.co/logstash/ 授权:Elastic License 2.0(8.x 起;免费含全部 filter/output 插件、持久化队列与监控;部分集中管理属付费)

1. 它解决什么问题

采集器(Beats)只负责"搬运",原始日志仍是一行行文本:字段混在字符串里、格式各异、时间格式不统一、IP 无地理信息、需要按业务分流。Logstash 提供:

  • 结构化解析:Grok/Dissect/JSON/KV 把非结构化日志拆成字段(状态码、URL、耗时、客户端 IP)。
  • 清洗与富化:mutate 改名/改类型/删字段,date 统一时间,geoip 补地理位置,fingerprint 生成去重 ID。
  • 缓冲削峰:持久化队列(PQ)把在途事件落盘,下游 ES 抖动时不丢数据、不压垮上游。
  • 多路分发:一个输入按条件写多个 ES 索引 / Kafka topic,或用多 pipeline 做故障隔离。
  • 统一接入层:收 Beats(5044)、Kafka、JDBC、Syslog 等,屏蔽下游差异。

它重(JVM、数百 MB 内存),不适合部署在每台业务主机(那是 Filebeat/Fluent Bit 的活);也不做长期存储与检索(那是 ES/Loki 的活)。

2. 核心概念与架构

术语表

术语 含义
Event 事件 一条数据在管道内的表示,含 message、@timestamp、字段与 @metadata
Pipeline 管道 独立执行单元 = input + filter + output,有独立队列与 workers
Input 插件 beats / file / kafka / jdbc / syslog / stdin / pipeline
Filter 插件 grok / dissect / json / kv / mutate / date / geoip / fingerprint / drop / prune
Output 插件 elasticsearch / kafka / file / stdout(rubydebug) / pipeline
Grok 用 %{PATTERN:field:type} 正则宏把文本抽成字段
@metadata 临时字段,不写入最终输出,用于条件路由
PQ 持久化队列 事件落盘的 append-only 页文件,至少一次投递(at-least-once)
Worker 并行执行 filter/output 的线程,pipeline.workers 默认为 CPU 核数
Pipeline-to-pipeline 用 pipeline output/input 在管道间分发,配合 PQ 做输出隔离
Conditional if [field] == "x" { ... } 按条件路由

两套链路中的位置与完整数据流(ASCII)

【ELK / EFK 链路 —— Logstash 是"集中解析/缓冲层"】
  应用写日志文件 / 容器 stdout
        │ ① 采集:Filebeat / Fluentd(F) / Fluent Bit,记录 offset
        ▼
  Filebeat ──► [可选 Kafka/Redis 二级缓冲] ──► ★ Logstash ★
                                              input(beats:5044)
                                              → filter(grok/mutate/date/geoip)
                                              → output(elasticsearch / kafka)
                                              │ PQ 落盘削峰、至少一次投递
                                              ▼
                                       Elasticsearch(存储检索层) → refresh(1s) 后可检索
                                              ▼
                                       Kibana: Discover / Dashboard / Alerting

【PLG 链路 —— 不含 Logstash】
  文件 / stdout / journal ─► Alloy(推荐) / Promtail(已 EOL) ─► Loki(仅标签+压缩块) ─► Grafana(LogQL)
  对照:PLG 用 Alloy 的轻量 pipeline_stages 替代 Logstash 重解析;需要重 ETL 才前置 Logstash,属非典型。

日志从文件到可检索的完整路径(ELK):

① 文件产生 → ② Beats 采集(记录位移) → ③ 送 Logstash beats input(5044)
→ ④ 进入 PQ 落盘 → ⑤ filter 解析成结构化 JSON(@timestamp、status_code、geo…)
→ ⑥ output 批量写 ES → ⑦ ES refresh 后可被 Query DSL 检索 → ⑧ Kibana 检索/聚合/告警

PLG 等价路径:文件 → Alloy 解析+加标签 → Loki 按标签分块 → Grafana 用 LogQL 查询。差异:ELK 写入前做重解析并全字段索引;PLG 只加少量标签、检索时才做行过滤。

3. 安装与部署

版本差异:8.x 自带 bundled JDK、ES 8.x 默认开启安全与 TLS,因此 elasticsearch output 必须配认证(user/password)与 CA 证书,否则写入 401/SSL 失败;7.x 无此要求。TLS 参数名随 output 插件版本变化,以官方插件文档为准。具体版本号以官方最新稳定版为准。

3.1 环境准备

项 要求 / 命令
Java 8.x 自带 bundled JDK,无需单独装;自带须匹配官方 JVM 兼容表
内存 ≥4GB;堆 -Xms=-Xmx(jvm.options)常取 1–4GB,≤物理内存 50%
vm.max_map_count 与 ES 同机时设 262144(sysctl -w vm.max_map_count=262144);纯 Logstash 节点非必需
文件句柄 /etc/security/limits.conf:logstash - nofile 65535(大量 file input / PQ 页文件时)
端口 5044 Beats 输入、9600–9700 监控 API;ES 9200、Kafka 9092
磁盘 PQ 与 path.data 建议独立 SSD;queue.max_bytes 之和须 < 磁盘容量
用户 包安装自动建 logstash 用户,禁止 root 启动

3.2 多种安装方式

A. 官方 APT/YUM 仓库(生产首选)

# Debian/Ubuntu(与 ES 共用 GPG key 与 8.x 仓库)
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elastic-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/elastic-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
sudo apt update && sudo apt install -y logstash
# RHEL/Rocky:复用 ES 的 elasticsearch.repo(见 elasticsearch.md 3.2),sudo dnf install -y logstash

B. Docker / docker compose

docker run --rm -it --name ls --net elastic -p 5044:5044 -p 9600:9600 \
  -v "$PWD/pipeline:/usr/share/logstash/pipeline:ro" \
  -v "$PWD/logstash.yml:/usr/share/logstash/config/logstash.yml:ro" \
  -e LS_JAVA_OPTS="-Xms2g -Xmx2g" \
  docker.elastic.co/logstash/logstash:<版本>          # tag 以官方最新稳定版为准

C. 二进制 tar.gz + systemd

tar -xzf logstash-<版本>-linux-x86_64.tar.gz -C /opt
useradd -r logstash && chown -R logstash:logstash /opt/logstash-*
sudo -u logstash /opt/logstash-*/bin/logstash -f /opt/logstash-*/pipeline/ --config.reload.automatic
# 生产写 /etc/systemd/system/logstash.service:User=logstash、LimitNOFILE=65535、Restart=on-failure

D. K8s(Helm / Operator):官方 elastic/helm-charts 提供 logstash chart;也常以独立 Deployment + ConfigMap 挂 pipeline + PVC 承载 PQ(ECK Operator 侧重 ES/Kibana/Beats)。具体 chart 版本以官方文档为准。

3.3 首次启动与验证

sudo systemctl daemon-reload && sudo systemctl enable --now logstash
sudo /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/ --config.test_and_exit   # -t 校验配置
curl -s http://localhost:9600/?pretty ; curl -s :9600/_node/stats/pipelines?pretty | jq '.pipelines.main.events'
/usr/share/logstash/bin/logstash -e 'input { stdin {} } output { stdout { codec => rubydebug } }'   # 键入一行验证
tail -f /var/log/logstash/logstash-plain.log

4. 配置文件详解

路径:主配置 /etc/logstash/logstash.yml;管道 /etc/logstash/conf.d/*.conf 或 /etc/logstash/pipelines.yml;JVM /etc/logstash/jvm.options;日志 /var/log/logstash/logstash-plain.log;数据/PQ /var/lib/logstash。

关键项(logstash.yml) 说明
node.name / path.data / path.logs 节点名、数据(PQ)目录、日志目录
pipeline.workers filter/output 并行线程数,默认 = CPU 核数
pipeline.batch.size / pipeline.batch.delay 每批事件数(默认 125)/ 等待毫秒(默认 50)
config.reload.automatic / config.reload.interval 自动重载 conf 变更(对 pipelines.yml 无效)
queue.type memory(默认)或 persisted(启用 PQ)
path.queue PQ 数据目录,默认 path.data/queue
queue.page_capacity 单个页文件大小,默认 64mb
queue.max_bytes 每个队列总容量,默认 1024mb(1gb),按 pipeline 分别计
queue.max_events 未读事件上限,默认 0(不限),官方不建议改动
queue.checkpoint.writes / queue.checkpoint.acks 强制 checkpoint 的写入/确认事件数,默认 1024
queue.drain true 时关闭前等待队列排空(默认 false)
xpack.monitoring.elasticsearch.* 把管道指标送到 ES 监控(也可用 9600 + exporter)

完整可运行最小示例(pipeline conf:Grok + 富化 + ES 输出):

# /etc/logstash/conf.d/nginx.conf
input { beats { port => 5044 } }                     # 接收 Filebeat;调试可临时加 stdin {}
filter {
  if "nginx" in [log][file][path] {
    grok { match => { "message" => "%{COMBINEDAPACHELOG}" } }   # 内置模式产出 clientip/timestamp/verb/request/response/bytes/agent
    # 自定义等价:match => { "message" => "%{IPORHOST:client.ip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:ts}\] \"%{WORD:verb} %{DATA:request} HTTP/%{NUMBER:httpversion}\" %{NUMBER:status:int} %{NUMBER:bytes:int}" }
    date { match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ] timezone => "Asia/Shanghai" target => "@timestamp" remove_field => ["timestamp"] }
    mutate {
      convert => { "bytes" => "integer" }
      rename  => { "clientip" => "client.ip" }
      add_field => { "[@metadata][target_index]" => "logs-nginx-%{+YYYY.MM.dd}" }
      remove_field => [ "ident", "auth", "agent", "referrer", "host" ]
    }
    geoip { source => "client.ip" target => "geo" }   # 需 GeoLite2 数据库
    if "_grokparsefailure" in [tags] { drop {} }      # 或路由到死信索引
  }
}
output {
  elasticsearch {
    hosts => ["https://<es_host>:9200"]
    user => "<es_user>"  password => "<es_password>"   # 8.x 安全集群必填
    index => "%{[@metadata][target_index]}"
    # 8.x 安全集群还需 TLS/CA 相关项,参数名随 output 插件版本变化,见官方插件文档
  }
}

多 pipeline(pipelines.yml) —— 为不同业务隔离队列与故障域:

# /etc/logstash/pipelines.yml
- pipeline.id: main
  path.config: "/etc/logstash/conf.d/*.conf"
  pipeline.workers: 4
  queue.type: persisted
  queue.max_bytes: 8gb
- pipeline.id: nginx
  path.config: "/etc/logstash/nginx.d/*.conf"
  pipeline.workers: 2
  queue.type: persisted
  queue.max_bytes: 4gb
- pipeline.id: audit
  config.string: "input { pipeline { address => audit } } output { elasticsearch { hosts => [\"https://<es_host>:9200\"] index => \"audit-%{+YYYY.MM.dd}\" } }"

5. 核心使用方法(CLI / 过滤插件 / 多 pipeline / 监控 API)

A. CLI 与插件管理

bin/logstash -e 'input { stdin {} } output { stdout { codec => rubydebug } }'   # 内联最小管道
bin/logstash -f /etc/logstash/conf.d/ --config.test_and_exit                    # -t 校验语法
bin/logstash -f /etc/logstash/conf.d/ --config.reload.automatic                  # 自动重载
bin/logstash -f /etc/logstash/conf.d/ --path.settings /etc/logstash --verbose    # 指定配置目录
bin/logstash --version ; systemctl start|stop|restart|status logstash ; bin/logstash-plugin list ; bin/logstash-plugin list --group filter
bin/logstash-plugin install logstash-filter-dissect ; bin/logstash-plugin update logstash-filter-grok ; bin/logstash-plugin remove logstash-output-email

B. Grok 模式(解析核心)

# 常用内置:%{IPORHOST} %{WORD} %{NUMBER} %{INT} %{DATA} %{GREEDYDATA} %{HTTPDATE} %{TIMESTAMP_ISO8601} %{LOGLEVEL};组合:%{COMBINEDAPACHELOG} %{SYSLOGLINE};语法 %{PATTERN:字段名:类型}
grok {
  match => { "message" => "%{TIMESTAMP_ISO8601:log_time} %{LOGLEVEL:log.level} \[%{DATA:trace_id}\] %{GREEDYDATA:msg}" }
  # 自定义命名捕获:match => { "message" => "code=(?<code>\d+) cost=(?<cost_ms>\d+)" };patterns_dir 放自定义模式文件
  # break_on_match => true ; tag_on_failure => ["_grokparsefailure"]
}
dissect { mapping => { "message" => "%{ts} %{+ts} %{level} %{msg}" } }   # 分隔符固定时比 Grok 更快

C. mutate / date / geoip / 其它过滤器

mutate {
  rename => { "host" => "host.name" }
  convert => { "status" => "integer"; "cost_ms" => "float" }
  add_field => { "env" => "prod"; "[@metadata][idx]" => "app-%{+YYYY.MM.dd}" }
  remove_field => [ "agent", "ecs", "input", "log", "@version" ]
  gsub => [ "request", "\?.*$", "" ] ; split => { "tags" => "," } ; lowercase => [ "log.level" ]
}
date { match => [ "log_time", "ISO8601", "yyyy-MM-dd HH:mm:ss.SSS" ] timezone => "Asia/Shanghai" target => "@timestamp" }
geoip { source => "client.ip" target => "geo" }                       # 输出 geo.country_name / geo.location
fingerprint { source => ["host.name","trace_id","@timestamp"] method => "SHA1" target => "[@metadata][fp]" }
json { source => "message" target => "json" }                         # 应用输出 JSON 日志时先解析
kv { source => "msg" field_split => " " value_split => "=" }           # key=value 串
prune { whitelist_names => ["@timestamp","message","status","trace_id"] }   # 精简字段防映射爆炸
if [log.level] == "DEBUG" { drop {} }

D. 多 pipeline 与管道间分发

# 分发器:按类型把事件送到不同下游管道,各管道有独立 PQ(官方 output isolator 模式)
input { beats { port => 5044 } }
output {
  if [event][module] == "nginx" { pipeline { send_to => [nginx_pipe] } }
  else { pipeline { send_to => [app_pipe] } }
}
# 下游:input { pipeline { address => nginx_pipe } }
curl -s :9600/_node/pipelines?pretty | jq 'keys'                      # 列出 pipeline.id
curl -s :9600/_node/stats/pipelines?pretty | jq '.pipelines|to_entries[]|{id:.key,in:.value.events.in,out:.value.events.out,q:.value.queue}'

E. 监控 API / 排查

curl -s :9600/?pretty ; curl -s :9600/_node?pretty                    # 节点与版本、OS/JVM
curl -s :9600/_node/stats?pretty                                      # events in/out/filtered、JVM、PQ
curl -s :9600/_node/hot_threads?pretty                                 # 卡住的线程
# 关注:events.in 与 events.out 差值(积压)、queue 使用率、reloads.failures、_grokparsefailure 计数

上述 CLI、插件名、queue.* 与 filter 选项均为官方稳定用法;pipeline input/output 为默认自带插件。

6. 告警与通知

Logstash 自身不产生告警,它暴露 9600 指标与管道事件,由外部告警:

层 做法
Elastic 侧 ES/Kibana Alerting 规则对 _grokparsefailure、events.out 骤降、5xx 数量告警;Watcher 付费
监控侧 Prometheus logstash_exporter(抓 9600)+ Alertmanager;或 Metricbeat logstash 模块 + Stack Monitoring
PLG 侧(对照) Loki Ruler 定义 LogQL 告警规则 → Alertmanager;Grafana 统一告警面板
Grafana 告警 Grafana Alerting 对 ES/Loki 数据源直接建规则,通知走 Contact Point

告警条件示例:events.out 5 分钟环比降 > 80%(管道卡死)、PQ 使用率 > 80% 持续 10 分钟(积压)、ES 中 tags:_grokparsefailure 5 分钟 > 100(格式变更)。

通知渠道:Grafana Contact Point 支持 Email / Webhook / 钉钉 / 企业微信(机器人)/ Slack;企微/钉钉把 {"msgtype":"text","text":{"content":"告警内容"}} 发到 <机器人 webhook>。Elastic 侧用 Kibana Connector(Email/SMTP、Webhook、Slack、Teams、PagerDuty),企微/钉钉经 Webhook Connector 转发。

7. 实战场景

7.1 Nginx/应用日志接入并做状态码统计

目标:Nginx access log → Filebeat → Logstash Grok 结构化 → ES → 按状态码统计。

步骤 + 命令/配置:

# ① Filebeat 送 Logstash(/etc/filebeat/filebeat.yml)
# filebeat.inputs: - type: filestream  id: nginx  paths: [/var/log/nginx/access.log]
# output.logstash: hosts: ["<logstash>:5044"]
# ② Logstash 用第 4 章 nginx.conf(grok COMBINEDAPACHELOG + date + mutate)
bin/logstash -f /etc/logstash/conf.d/ --config.test_and_exit && systemctl restart logstash
# ③ 端到端写入验证
echo '127.0.0.1 - - [05/Nov/2026:10:00:00 +0800] "GET /api HTTP/1.1" 500 123 "-" "curl"' >> /var/log/nginx/access.log
curl -s -u elastic:<密码> --cacert <http_ca.crt> "https://<es>:9200/logs-nginx-*/_search?pretty"

状态码统计(ES 侧聚合 → Kibana 可视化):

curl -s -u elastic:<密码> --cacert <ca> -X POST "https://<es>:9200/logs-nginx-*/_search?size=0&pretty" \
  -H 'Content-Type: application/json' \
  -d '{"query":{"range":{"@timestamp":{"gte":"now-24h"}}},"aggs":{"by_status":{"terms":{"field":"status","size":10}},"trend":{"date_histogram":{"field":"@timestamp","fixed_interval":"1h"}}}}'

验证::9600/_node/stats/pipelines 的 events.out 递增;ES _search 有 status 字段;Kibana 可过滤 status:500。 回滚:停 Logstash 前把 Filebeat output.logstash 指回备用管道或改 output.elasticsearch;删索引 DELETE /logs-nginx-* 前先快照 ⚠️。

7.2 日志暴增导致磁盘打满的处置

目标:PQ/输出磁盘被打满 → 止血 → 恢复 → 根治。

# ① 定位 PQ 使用率、事件积压、磁盘
curl -s :9600/_node/stats/pipelines?pretty | jq '.pipelines.main.queue' ; df -h /var/lib/logstash ; du -sh /var/lib/logstash/queue/*
# ② 止血:临时丢弃低价值日志 filter { if [log.level]=="DEBUG" { drop {} } };③ 给 ES 索引降副本腾空间
curl -s -u elastic:<密码> --cacert <ca> -X PUT "https://<es>:9200/logs-2025-*/_settings" -d '{"index.number_of_replicas":0}'
# ④ PQ 自身撑满:停机 → 扩容 → 调大 queue.max_bytes(<磁盘容量) → 启动排空(queue.drain: true);⑤ 根治:采集端限速、ILM 缩短留存

验证:df -h 回落;events.in ≈ events.out;ES _cluster/health 回 green。 回滚:恢复 drop 规则与副本数 PUT /logs-*/_settings {"index.number_of_replicas":1};⚠️ 已删索引只能从快照恢复。

7.3 多 pipeline 隔离 + 输出到 Kafka 削峰

目标:关键业务与普通日志隔离队列;下游 ES 维护时先写 Kafka 不丢数据。

# pipelines.yml:nginx 与 audit 各自 persisted 队列,互不影响(同上第 4 章结构)
- pipeline.id: nginx
  path.config: "/etc/logstash/nginx.d/*.conf"
  queue.type: persisted
  queue.max_bytes: 8gb
  pipeline.workers: 4
# nginx.d/90-output.conf:主写 ES,同时镜像一份到 Kafka 便于重放
output {
  elasticsearch { hosts => ["https://<es>:9200"] user => "<u>" password => "<p>" index => "logs-nginx-%{+YYYY.MM.dd}" }
  kafka { topic_id => "logs-raw" bootstrap_servers => "<kafka>:9092" codec => json }
}

验证::9600/_node/pipelines 存在 nginx/audit 两个 id;停 audit 的 ES 输出后 nginx 的 events.out 不受影响。 回滚:pipelines.yml 改回单管道(或注释 kafka output)并 restart;⚠️ 重启前确认 PQ 已排空,避免重复投递。

8. 日常运维与故障排查

项 命令 / 路径
服务管理 systemctl start|stop|restart|status logstash;改 conf 需 restart(或开自动重载)
日志路径 /var/log/logstash/logstash-plain.log
健康检查 curl :9600/?pretty、curl :9600/_node/stats?pretty
配置校验 bin/logstash -f <dir> --config.test_and_exit(上线前必做)
管道 / PQ 状态 :9600/_node/pipelines、_node/hot_threads、_node/stats/pipelines 的 queue 节点

故障「现象 → 原因 → 处置」表

现象 原因 处置
启动即退出、报 Configuration ERROR conf 语法错/插件参数错 --config.test_and_exit 定位;看 logstash-plain.log
大量 _grokparsefailure 日志格式变了 / 模式不匹配 用 Grok Debugger 调模式;加 tag_on_failure 并路由死信
events.in 涨但 events.out 为 0 下游 ES 401/SSL/不可达 查 output 日志;8.x 补认证/CA;curl 测 9200
PQ 使用率 100%、上游被背压 下游写入慢/宕机、队列容量小 恢复下游、扩 queue.max_bytes、加 worker、临时 drop 低价值日志
CPU 100%、吞吐上不去 Grok 复杂 / workers 过多 换 dissect、减 GREEDYDATA、workers 调回核数附近、调 batch.size
时间差 8 小时 date 未设 timezone 或日志无时区 timezone => "Asia/Shanghai",采集端写带 +08:00 时间
多行堆栈被拆成多条 未配 multiline 在 Filebeat parsers.multiline 合并后再送 Logstash
geoip 无输出 数据库缺失/过期、source 非公网 IP 确认 GeoLite2 路径与授权、检查 client.ip

9. 性能、容量与高可用

容量估算公式(官方 PQ 公式):

Bytes/s = EPS × 单事件字节 ; Bytes/h = Bytes/s × 3600
所需 PQ 容量 = Bytes/h × 可容忍下游不可用小时数 × 放大系数(起始 1.10),例:1000 EPS × 1KB ≈ 3.5GB/h,容忍 12h → ≈ 47GB
约束:所有 pipeline 的 queue.max_bytes 之和 < 磁盘容量;queue.max_bytes ≥ queue.page_capacity(64mb)

Logstash 自身无分片/副本概念:分片与副本在下游 ES 规划(单分片 30–50GB、1 主 1 副、ILM rollover,见 elasticsearch.md);Logstash 侧对应 PQ 容量 + workers + 多实例 HA。

维度 建议
JVM 堆 -Xms=-Xmx 1–4GB 起步,≤内存 50%;GC 默认 G1;堆过大反而拖慢
并行度 pipeline.workers ≈ CPU 核数;batch.size 125 可试 500–1000,配合 batch.delay
队列 关键管道一律 queue.type: persisted;queue.checkpoint.writes: 1 最耐久但严重损性能,默认 1024 即可
冷热分层 由 ES ILM 负责;output 用日期索引名配合模板,勿按小时切索引
集群/HA 多实例 + Filebeat loadbalance: true 多 hosts + 前置 LB;各实例独立 PQ,无单点
削峰 上游加 Kafka;或 pipeline-to-pipeline output isolator 让单 output 卡顿不阻塞全局
自监控 9600 指标经 logstash_exporter/Metricbeat 采集;盯 in/out 差值、queue 使用率、reloads.failures、heap

10. 安全加固、备份与升级

认证鉴权 / TLS / 最小权限

# ES output 用最小权限专用用户(见 elasticsearch.md 10 建 logs_writer 角色),勿用 elastic 超管
elasticsearch { hosts => ["https://<es>:9200"] user => "logstash_svc" password => "${ES_PWD}" index => "logs-%{+YYYY.MM.dd}" }
# TLS/CA 配置项名称随插件版本变化,按官方 output-elasticsearch 插件文档设置
# beats input 启用 TLS 的参数名以官方 input-beats 插件文档为准
  • 密码勿写明文:用 keystore(bin/logstash-keystore create / add ES_PWD,配置里用 ${ES_PWD})。
  • 最小权限:仅 create_index + write + view_index_metadata;禁用不必要插件;9600 仅内网可达。

备份:Logstash 无状态(除 PQ 在途数据),备份对象是配置与 keystore:/etc/logstash/、pipelines.yml、conf.d/、keystore;数据最终在 ES,用 SLM 快照备份恢复(PUT /_slm/policy/... + _restore,见 elasticsearch.md 10),⚠️ 恢复前先 _close 目标索引。

滚动升级顺序与回滚:① 备份配置与 keystore → ② 逐台停(先确认 PQ 排空或 queue.drain: true)→ ③ 升级包/镜像 → ④ logstash -t 校验 → ⑤ 启动看 9600 与 events.out 恢复 → ⑥ 下一台。回滚:降回旧版本包并恢复备份配置(PQ 页文件跨版本可能不兼容,回滚前另存/清空 path.queue ⚠️);下游 ES 升级另按其滚动顺序。

11. 常见坑

现象 原因 解决 / 备注
⚠️ 下游 ES 分片过多、集群变慢 output 索引按小时切、无 rollover 日期索引 + ES data stream/ILM max_primary_shard_size=50gb
⚠️ 映射爆炸 total fields [1000] Grok 抽太多字段 / 动态映射 mutate.prune 白名单、模板 dynamic: strict、@metadata 不落盘
⚠️ 时区差 8 小时 date 未设 timezone、日志无时区 timezone => "Asia/Shanghai",采集端时间带 +08:00
⚠️ 日志重复 PQ at-least-once 重投、Beats 重传、无幂等 fingerprint 生成 _id 写 ES;保留 registry;避免反复重放同一批
_grokparsefailure 暴涨 日志格式变更 版本化模式、加死信索引而非静默丢弃、上线前用样本回归
PQ 把磁盘打满、上游停摆 queue.max_bytes 超磁盘 / 下游长期不可用 容量按公式留余量、80% 告警、临时 drop 低价值日志
改了 conf 不生效 用 pipelines.yml 时 config.reload.automatic 不作用于它 pipelines.yml 变更需重启;单 conf 才支持自动重载
8.x 写入 401 / SSL 失败 ES 安全默认开启未配认证 output 补 user/password 与 CA(参数名以插件文档为准)

12. 速查表

项 值 / 命令
默认端口 5044(Beats input)、9600(监控 API)
主配置 /etc/logstash/logstash.yml
管道配置 /etc/logstash/conf.d/*.conf、/etc/logstash/pipelines.yml
JVM / 日志 / 数据 /etc/logstash/jvm.options、/var/log/logstash/logstash-plain.log、/var/lib/logstash
配置校验 bin/logstash -f <dir> --config.test_and_exit(-t)
自动重载 --config.reload.automatic
最小管道 bin/logstash -e 'input{stdin{}} output{stdout{codec=>rubydebug}}'
插件管理 bin/logstash-plugin list|install|update|remove
密钥库 / 版本 bin/logstash-keystore create|add|list、bin/logstash --version
管道指标 GET :9600/_node/stats/pipelines?pretty
管道列表 / 热线程 GET :9600/_node/pipelines?pretty、GET :9600/_node/hot_threads?pretty
启用 PQ queue.type: persisted、queue.max_bytes: 8gb
Grok 语法 %{PATTERN:field:type}、%{COMBINEDAPACHELOG}、(?<f>regex)
常用 filter grok / dissect / mutate / date / geoip / json / kv / fingerprint / prune / drop
常用 input/output beats / pipeline / kafka;elasticsearch / kafka / stdout / pipeline
关键标签 _grokparsefailure、@metadata(默认不输出)
服务管理 systemctl start|stop|restart|status logstash

13. 选型建议与同类对比

维度 ELK(含 Logstash) PLG(Loki+Alloy+Grafana) Graylog Fluent Bit / Vector
解析能力 ★★★ 最强(Grok/富化/路由) ★★ Alloy stage 够用 ★★ ★ 轻量
资源开销 高(JVM 数百 MB~GB) 低 中 极低(C/Rust,MB 级)
缓冲削峰 ★★★ PQ + Kafka 中(客户端缓冲) 中 中
全文检索 / 部署 ★★★ ES / 集中层 ★ 标签+行过滤 / 每主机 Agent ★★ ES(旧) / 集中 无 / 每主机 Agent
授权 Elastic License 2.0 Apache 2.0 部分 GPL/企业 Apache/MIT

何时选 Logstash:异构日志格式多、需要 Grok/富化/条件路由/至少一次投递缓冲、已有 ES 且能承担 JVM 运维。何时不选:只需"采集+轻量解析"→ Filebeat/Fluent Bit/Alloy 直接入 ES/Loki,省掉一层;成本敏感且已用 Grafana → PLG;想要单机轻量替代 → Vector。边界:Logstash 在 ELK/EFK 是解析/缓冲层,PLG 链路默认不含 Logstash(由 Alloy 承担解析),二者不是串联关系。

14. 参考链接

8.x 起 ES 安全/TLS 默认开启,Logstash output 需认证;PQ 的 queue.compression(9.2+)、queue.checkpoint.interval(9.1+ 弃用) 随版本变化。具体版本与参数以官方最新稳定版文档为准。

Logstash —— 服务端日志 ETL 与解析管道 - 知识库 - 起航社区