ELK 日志收集方案
概述
ELK Stack 是 Elasticsearch、Logstash、Kibana 三个开源工具的缩写,用于实现集中式日志管理。
| 组件 | 作用 |
|---|---|
| Elasticsearch | 分布式搜索和分析引擎,存储日志数据 |
| Logstash | 数据处理管道,采集、转换、发送日志 |
| Kibana | 可视化平台,探索和展示 Elasticsearch 数据 |
架构演进
经典 ELK 架构
App → Logfile → Logstash → Elasticsearch → Kibana
引入 Filebeat 的轻量级架构
App → Logfile → Filebeat → Logstash → Elasticsearch → Kibana
↓
(可选 Kafka 缓冲)
生产架构
App → Filebeat → Kafka → Logstash → Elasticsearch → Kibana
↓
ILM 索引生命周期管理
Elasticsearch
核心概念
| 概念 | 说明 |
|---|---|
| Index | 类似数据库中的表,存储相关文档 |
| Document | 一条记录,JSON 格式 |
| Shard | 分片,将索引水平分割 |
| Replica | 副本分片,提供高可用 |
部署配置
# docker-compose.yml
services:
elasticsearch:
image: elasticsearch:8.12
environment:
- discovery.type=single-node
- xpack.security.enabled=false
- ES_JAVA_OPTS=-Xms2g -Xmx2g
ports:
- "9200:9200"
volumes:
- es_data:/usr/share/elasticsearch/data
索引生命周期管理 (ILM)
PUT _ilm/policy/logs_policy
{
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": {
"max_size": "50GB",
"max_age": "1d"
}
}
},
"warm": {
"min_age": "7d",
"actions": {
"shrink": { "number_of_shards": 1 }
}
},
"cold": {
"min_age": "30d",
"actions": {
"freeze": {}
}
},
"delete": {
"min_age": "90d",
"actions": {
"delete": {}
}
}
}
}
}
Logstash
配置文件结构
# logstash.conf
input {
beats {
port => 5044
}
}
filter {
# 解析 Nginx 访问日志
if [fields][type] == "nginx_access" {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
date {
match => ["timestamp", "dd/MMM/yyyy:HH:mm:ss Z"]
}
geoip {
source => "clientip"
}
}
# 解析 JSON 日志
if [fields][type] == "app_json" {
json {
source => "message"
}
}
# 添加字段
mutate {
add_field => { "environment" => "%{[fields][env]}" }
remove_field => ["message", "original"]
}
}
output {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
index => "logs-%{[fields][type]}-%{+YYYY.MM.dd}"
}
}
性能优化
# 使用多 pipeline
# pipelines.yml
- pipeline.id: nginx_logs
path.config: "/usr/share/logstash/pipeline/nginx.conf"
pipeline.workers: 4
- pipeline.id: app_logs
path.config: "/usr/share/logstash/pipeline/app.conf"
pipeline.workers: 2
# 批量处理优化
output {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
flush_size => 500
idle_flush_time => 5
}
}
Filebeat
配置
# filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
fields:
type: nginx_access
env: production
multiline:
pattern: '^\d{4}-\d{2}-\d{2}'
negate: true
match: after
- type: container
paths:
- /var/lib/docker/containers/*/*.log
output.logstash:
hosts: ["logstash:5044"]
ssl.enabled: false
# 同时输出到 Elasticsearch(直接模式)
# output.elasticsearch:
# hosts: ["http://elasticsearch:9200"]
Kibana
数据探索
Kibana 提供三种主要的数据探索方式:
- Discover:全文搜索和过滤日志
- Dashboard:组合多个可视化面板
- Canvas:自定义数据展示
常用可视化
可视化类型:
时间序列: Timelion / TSVB
统计: 饼图、数据表、指标
地理: 坐标地图、区域地图
日志: 日志视图(Logs UI)
常用查询
# Lucene 语法
status: 500 AND response_time: > 1000
# KQL (Kibana Query Language)
status: 500 and response_time > 1000
# 范围查询
@timestamp >= "2024-01-01" and @timestamp <= "2024-01-31"
# 通配符
message: "error*" or message: "exception*"
# 字段存在性
_exists_: error.stack_trace
生产最佳实践
索引模板
PUT _index_template/logs_template
{
"index_patterns": ["logs-*"],
"template": {
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1,
"refresh_interval": "30s"
},
"mappings": {
"dynamic_templates": [
{
"strings_as_keyword": {
"match_mapping_type": "string",
"mapping": {
"type": "text",
"fields": {
"keyword": { "type": "keyword" }
}
}
}
}
]
}
}
}
性能优化
Elasticsearch
- 合理设置分片大小(20-50GB)
- 使用 SSD 存储
- 启用节点角色分离(hot/warm/cold)
Logstash
- 使用 Kafka 缓冲削峰填谷
- 多 pipeline 分离处理
- 避免复杂 grok 模式
Filebeat
- 合理设置
harvester_buffer_size - 使用
registry确保断点续传 - 启用
ssl安全传输
- 合理设置
总结
ELK Stack 提供了从日志采集到可视化的完整解决方案。生产环境中推荐使用 Filebeat + Kafka + Logstash 的架构,配合 Elasticsearch 的 ILM 实现自动化的索引管理,最后通过 Kibana 实现日志的探索和可视化。合理规划索引模板和分片策略,可以有效控制存储成本并保证查询性能。