跳到主要内容

ELK 生态

问题

什么是 ELK Stack?Logstash、Kibana、Beats 分别起什么作用?如何构建完整的日志收集与分析系统?

答案

ELK Stack 概述

ELK 是 Elasticsearch + Logstash + Kibana 的缩写,后来加入 Beats 后又称为 Elastic Stack

组件角色功能
Beats轻量采集器在目标机器上采集数据,资源占用低
Logstash数据处理管道接收、过滤、转换、丰富数据并输出到 ES
Elasticsearch存储与搜索索引数据、全文搜索、聚合分析
Kibana可视化与管理数据探索、Dashboard、告警、APM

Logstash

Logstash 是服务端数据处理管道,使用 Input → Filter → Output 三阶段架构。

三阶段架构

# logstash.conf
input {
# 从 Beats 接收数据
beats {
port => 5044
}

# 从 Kafka 消费
kafka {
bootstrap_servers => "kafka:9092"
topics => ["app-logs"]
group_id => "logstash-consumer"
codec => json
}
}

filter {
# Grok 解析非结构化日志
grok {
match => {
"message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} %{GREEDYDATA:content}"
}
}

# 解析日期
date {
match => ["timestamp", "ISO8601"]
target => "@timestamp"
}

# GeoIP 地理信息丰富
geoip {
source => "client_ip"
}

# 移除不需要的字段
mutate {
remove_field => ["agent", "ecs", "host"]
}

# 条件过滤
if [level] == "DEBUG" {
drop {}
}
}

output {
# 输出到 Elasticsearch
elasticsearch {
hosts => ["http://es:9200"]
index => "app-logs-%{+YYYY.MM.dd}"
# 使用 ILM 策略
ilm_enabled => true
ilm_rollover_alias => "app-logs"
ilm_policy => "logs-policy"
}

# 错误日志同时发到告警
if [level] == "ERROR" {
http {
url => "https://webhook.example.com/alert"
http_method => "post"
format => "json"
}
}
}

常用 Filter 插件

插件用途示例
grok正则解析非结构化文本解析 Nginx/Apache 日志
json解析 JSON 字符串解析应用日志
date解析日期字符串统一时间戳
geoipIP → 地理位置来源地分析
mutate字段操作重命名、删除、类型转换
dissect分隔符解析(比 grok 快)固定格式日志
ruby自定义 Ruby 代码复杂逻辑处理
Logstash vs Ingest Pipeline
  • Logstash:独立进程,功能强大,适合复杂处理、多 Input/Output
  • Ingest Pipeline:ES 内置,无需额外部署,适合简单转换

简单日志场景可以用 Beats → ES(Ingest Pipeline),省去 Logstash 的资源消耗。

Beats 家族

Beats 是轻量级数据采集器,用 Go 语言编写,资源占用极低。

Beat采集对象典型场景
Filebeat日志文件应用日志、系统日志
Metricbeat系统/服务指标CPU、内存、Docker、MySQL 等
Packetbeat网络数据包HTTP、MySQL、DNS 协议分析
Heartbeat服务健康状态Uptime 监控、HTTP/TCP 探测
Auditbeat审计数据文件完整性、系统审计日志
WinlogbeatWindows 事件Windows 安全/系统日志

Filebeat 配置

# filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/app/*.log
# 多行合并(Java 异常堆栈)
multiline.pattern: '^\d{4}-\d{2}-\d{2}'
multiline.negate: true
multiline.match: after
# 添加标签
tags: ["app", "production"]
fields:
env: production
service: user-service

- type: container
paths:
- /var/lib/docker/containers/*/*.log
processors:
- add_kubernetes_metadata: ~

# 输出到 Logstash
output.logstash:
hosts: ["logstash:5044"]

# 或直接输出到 ES(简单场景)
# output.elasticsearch:
# hosts: ["es:9200"]
# pipeline: "app-log-pipeline" # 使用 Ingest Pipeline

Filebeat 工作原理

  • Harvester:每个文件一个 goroutine,逐行读取
  • Registry:记录每个文件的读取偏移量,重启后从上次位置继续
  • 背压处理:当 Output 目标不可用时,自动减慢读取速度

Kibana

Kibana 是 ES 的可视化前端,提供数据探索、Dashboard、告警等功能。

核心功能

功能说明
Discover日志搜索、过滤、时间范围选择
Dashboard可视化看板,组合多个图表
Lens拖拽式可视化创建
Canvas像素级自定义 Dashboard
Alerting基于条件的告警规则
APM应用性能监控
Maps地理信息可视化
Dev ToolsES Query Console
Stack MonitoringES 集群监控
Index Management索引生命周期管理

KQL(Kibana Query Language)

# 基本搜索
level: "ERROR"

# AND 组合
level: "ERROR" and service: "order-service"

# OR 组合
level: "ERROR" or level: "WARN"

# 通配符
message: *timeout*

# 范围
response_time > 1000

# NOT
not level: "DEBUG"

# 嵌套字段
request.method: "POST" and response.status >= 500

索引生命周期管理(ILM)

ILM 自动管理索引的创建、优化和删除。

// 创建 ILM 策略
PUT _ilm/policy/logs-policy
{
"policy": {
"phases": {
"hot": {
"actions": {
"rollover": {
"max_size": "50gb",
"max_age": "1d"
}
}
},
"warm": {
"min_age": "7d",
"actions": {
"forcemerge": { "max_num_segments": 1 },
"shrink": { "number_of_shards": 1 }
}
},
"cold": {
"min_age": "30d",
"actions": {
"freeze": {}
}
},
"delete": {
"min_age": "90d",
"actions": {
"delete": {}
}
}
}
}
}

完整日志系统架构

为什么加 Kafka 缓冲层?

直接推送经过 Kafka
架构简单削峰填谷,应对日志突增
Logstash 挂了日志丢失Kafka 持久化,不丢数据
无法重放支持消费重放
单一消费多消费者(ES + Flink 等)

ES vs 同类方案对比

对比项ElasticsearchSplunkLoki
开源✅(BSL 许可)❌ 商业✅ Apache 2.0
全文索引✅ 倒排索引✅ 倒排索引❌ 仅标签索引
存储成本中等低(不索引日志内容)
查询能力强(Query DSL)强(SPL)中(LogQL)
适合场景通用搜索与分析企业安全分析云原生日志
与 K8s 集成一般一般优秀(和 Grafana 一体)
Loki 的设计理念

Grafana Loki 不对日志内容建索引,只索引标签(label)。查询时通过标签过滤 + grep 搜索内容。存储成本只有 ES 的 1/10,但搜索大量日志时性能较差。

选型建议

  • 需要复杂搜索和分析 → ES/ELK
  • 云原生 + 已用 Grafana + 成本敏感 → Loki
  • 企业级安全合规 → Splunk

常见面试问题

Q1: ELK 各组件的作用?

答案

  • Elasticsearch:分布式搜索与分析引擎,负责存储、索引和搜索日志数据
  • Logstash:服务端数据处理管道,负责数据接收(Input)、转换过滤(Filter)、输出(Output)
  • Kibana:可视化界面,提供数据搜索、Dashboard、告警等功能
  • Beats:轻量级数据采集器,部署在目标机器上收集各类数据(Filebeat 收集日志、Metricbeat 收集指标等)

Q2: 为什么日志系统中通常在 Beats 和 Logstash 之间加 Kafka?

答案

  1. 削峰填谷:日志量有波峰波谷,Kafka 作为缓冲层吸收峰值流量
  2. 解耦:采集端和处理端解耦,Logstash 挂了不影响日志采集
  3. 持久化:Kafka 持久化消息,不会因为 Logstash 重启而丢失日志
  4. 重放能力:可以重新消费历史日志(如修改处理逻辑后重新入 ES)
  5. 多消费者:日志可以同时给 ES、Flink、数据仓库等多个系统消费

Q3: Filebeat 如何保证日志不丢失和不重复?

答案

  • 不丢失:Filebeat 使用 Registry 文件记录每个日志文件的读取偏移量(offset),重启后从上次位置继续读取。同时支持背压(backpressure),当下游不可用时减慢读取速度
  • 不重复:正常情况不会重复。但如果 Filebeat 在发送确认前崩溃,重启后会从上次记录的 offset 重新发送,可能产生少量重复(at-least-once 语义)。需要在 ES 端通过文档 ID 去重实现幂等写入

Q4: 如何管理 ES 中的日志索引?

答案

使用 ILM(Index Lifecycle Management) 自动管理:

  1. Hot Phase:写入新数据,使用高性能 SSD,按大小或时间自动 rollover
  2. Warm Phase:不再写入,force merge 减少 Segment,迁移到普通磁盘
  3. Cold Phase:低频查询,冻结索引减少内存
  4. Delete Phase:过期自动删除

配合 Index TemplateRollover Alias 实现全自动化管理。

Q5: ES + Loki + Splunk 如何选型?

答案

场景推荐方案
全文搜索需求强Elasticsearch
已有 Grafana 生态Loki
成本敏感Loki(不索引内容,存储成本低)
企业安全合规Splunk
少量日志 + 简单查询Loki
大规模日志 + 复杂分析Elasticsearch
APM + 日志一体Elastic APM

相关链接