ELK + Filebeat (compose)部署:采集并可视化 Nginx 日志
·
我会一步步带你完成从环境准备到最终在 Kibana 查看实时 Nginx 日志的完整流程,全程采用 Docker Compose 部署(最便捷的方式),适合新手快速上手。
一、整体架构说明
plaintext
Nginx 日志文件 → Filebeat(采集) → Logstash(过滤/处理) → Elasticsearch(存储) → Kibana(可视化)
- Filebeat:轻量级日志采集器,部署在 Nginx 服务器上(必须跟NGINX一台服务器),负责读取日志并发送给 Logstash
- Logstash:日志处理中间件,负责解析 Nginx 日志格式、过滤无用数据
- Elasticsearch:分布式搜索引擎,存储结构化后的日志数据
- Kibana:可视化工具,提供日志检索、实时查看、图表分析功能
二、环境准备
1. 前置条件
- 服务器安装 Docker 和 Docker Compose(建议 Linux 系统,内存 ≥ 4G,ES 对内存要求较高)
- 服务器已安装 Nginx(或用 Docker 部署 Nginx,下文提供示例)
- 确保 9200、9300(ES)、5601(Kibana)、5044(Logstash)端口未被占用
2. 目录结构(统一规划)
先创建基础目录,方便管理配置和数据:
bash
运行
# 创建主目录
mkdir -p /elk/{filebeat,logstash,elasticsearch,kibana,nginx/logs}
cd /elk
# 赋予权限(避免容器权限问题)
chmod -R 777 /elk
三、编写配置文件
1. Filebeat 配置(filebeat.yml)
路径:/elk/filebeat/filebeat.yml
yaml
filebeat.inputs:
- type: filestream
enabled: true
# Nginx 日志路径(根据你的实际路径修改,支持通配符)
paths:
- /elk/nginx/logs/access.log
- /elk/nginx/logs/error.log
# 自定义标签,方便后续筛选
tags: ["nginx-logs"]
# 输出到 Logstash(而非直接输出到 ES)
# 192.168.235.134替换自己Logstash部署服务器的IP
output.logstash:
hosts: ["localhost:5044"]
# 关闭 Filebeat 内置的模板管理(交给 Logstash/ES 处理)
setup.template.enabled: false
setup.ilm.enabled: false
# 日志级别(调试用 debug,生产用 info)
logging.level: info
logging.to_files: false
2. Logstash 配置
(1)主配置文件(logstash.yml)
路径:/elk/logstash/logstash.yml
yaml
http.host: "0.0.0.0"
xpack.monitoring.elasticsearch.hosts: ["http://localhost:9200"]
# 避免重复日志
pipeline.batch.size: 125
pipeline.batch.delay: 50
(2)Nginx 日志解析配置(nginx.conf)
路径:/elk/logstash/pipeline/nginx.conf
ruby
# 输入:接收 Filebeat 的数据
input {
beats {
port => 5044
codec => "json"
}
}
# 过滤:解析 Nginx 日志(核心)
filter {
# 只处理 Nginx 日志(通过 Filebeat 的 tags 筛选)
if "nginx-logs" in [tags] {
# 解析 access.log(Nginx 组合日志格式)
if [log][file][path] =~ "access.log" {
grok {
match => { "message" => '%{IPORHOST:remote_addr} - %{USERNAME:remote_user} \[%{HTTPDATE:time_local}\] "%{WORD:method} %{URIPATH:request} %{URIPROTO:http_version}" %{NUMBER:status:int} %{NUMBER:body_bytes_sent:int} "%{DATA:http_referer}" "%{DATA:http_user_agent}" "%{DATA:http_x_forwarded_for}"' }
remove_field => ["message"] # 解析后删除原始 message 字段
}
# 转换时间格式(适配 ES)
date {
match => [ "time_local", "dd/MMM/yyyy:HH:mm:ss Z" ]
target => "@timestamp"
}
}
# 解析 error.log(简单处理,保留原始信息)
if [log][file][path] =~ "error.log" {
mutate {
add_field => { "log_type" => "nginx_error" }
}
}
# 添加自定义字段(方便后续筛选)
mutate {
add_field => { "service" => "nginx" }
convert => { "status" => "integer" } # 确保状态码是数字类型
}
}
}
# 输出:发送到 Elasticsearch
output {
elasticsearch {
hosts => ["localhost:9200"]
# 索引名称(按天分片,方便管理)
index => "nginx-logs-%{+YYYY.MM.dd}"
user => "elastic"
password => "elastic"
# 自动创建索引模板(确保字段类型正确)
template_overwrite => true
}
# 可选:控制台输出(调试用,生产可注释)
# stdout { codec => rubydebug }
}
3. Elasticsearch 配置(elasticsearch.yml)
路径:/elk/elasticsearch/elasticsearch.yml
yaml
cluster.name: elk-cluster
node.name: es-node-1
network.host: 0.0.0.0
http.port: 9200
# 单节点模式(新手推荐)
discovery.type: single-node
# 关闭内存交换(提升性能)
bootstrap.memory_lock: true
# JVM 堆内存(根据服务器配置调整,建议物理内存的 50%,最大不超过 31G)
ES_JAVA_OPTS: "-Xms1g -Xmx1g"
# 开启跨域(适配 Kibana)
http.cors.enabled: true
http.cors.allow-origin: "*"
4. Kibana 配置(kibana.yml)
路径:/elk/kibana/kibana.yml
yaml
server.port: 5601
server.host: "0.0.0.0"
# 连接 ES
elasticsearch.hosts: ["http://localhost:9200"]
# 中文界面(可选)
i18n.locale: "zh-CN"
# 自动创建索引模式(简化配置)
xpack.indexPatterns.defaultIndex: "nginx-logs-*"
5. Nginx 配置(可选:如果用 Docker 部署 Nginx)
路径:/elk/nginx/nginx.conf
nginx
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
# 标准组合日志格式(和 Logstash 解析规则对应)
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}
四、编写 Docker Compose 文件
路径:/elk/docker-compose.yml
yaml
version: '3.8'
services:
# 1. Elasticsearch
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.14.0
container_name: elk-es
restart: always
volumes:
- ./elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
- es-data:/usr/share/elasticsearch/data
environment:
- "ES_JAVA_OPTS=-Xms1g -Xmx1g"
- "ELASTIC_PASSWORD=elastic123" # 设置 ES 密码(可选)
- "xpack.security.enabled=false" # 新手先关闭安全认证(简化配置)
ulimits:
memlock:
soft: -1
hard: -1
ports:
- "9200:9200"
- "9300:9300"
networks:
- elk-network
# 2. Logstash
logstash:
image: docker.elastic.co/logstash/logstash:8.14.0
container_name: elk-logstash
restart: always
volumes:
- ./logstash/logstash.yml:/usr/share/logstash/config/logstash.yml
- ./logstash/pipeline:/usr/share/logstash/pipeline
ports:
- "5044:5044"
depends_on:
- elasticsearch
networks:
- elk-network
# 3. Kibana
kibana:
image: docker.elastic.co/kibana/kibana:8.14.0
container_name: elk-kibana
restart: always
volumes:
- ./kibana/kibana.yml:/usr/share/kibana/config/kibana.yml
ports:
- "5601:5601"
depends_on:
- elasticsearch
networks:
- elk-network
# 4. Filebeat
filebeat:
image: docker.elastic.co/beats/filebeat:8.14.0
container_name: elk-filebeat
restart: always
volumes:
- ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml
- ./nginx/logs:/elk/nginx/logs # 挂载 Nginx 日志目录
- /var/lib/docker/containers:/var/lib/docker/containers:ro # 如果采集容器日志需要
- /var/run/docker.sock:/var/run/docker.sock:ro
user: root # 必须用 root 权限读取宿主机日志
depends_on:
- logstash
networks:
- elk-network
# 5. Nginx(可选:如果没有现成的 Nginx)
nginx:
image: nginx:latest
container_name: elk-nginx
restart: always
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/logs:/var/log/nginx # 日志目录挂载到宿主机
ports:
- "8080:80"
networks:
- elk-network
volumes:
es-data: # ES 数据持久化卷
networks:
elk-network:
driver: bridge
五、启动服务
bash
运行
# 进入 /elk 目录
cd /elk
# 启动所有服务(后台运行)
docker-compose up -d
# 查看服务状态(确保所有容器都是 Up 状态)
docker-compose ps
# 查看日志(排查启动错误)
docker-compose logs -f elasticsearch
docker-compose logs -f logstash
六、Kibana 配置与查看实时日志
1. 访问 Kibana
浏览器打开:http://你的服务器IP:5601(首次加载可能需要 1-2 分钟)
2. 创建索引模式
- 左侧菜单 → 管理 → 索引模式 → 创建索引模式
- 输入索引名称:
nginx-logs-*→ 下一步 - 时间字段选择:
@timestamp→ 创建索引模式
3. 查看实时日志
- 左侧菜单 → 分析 → 发现
- 顶部选择刚创建的索引模式
nginx-logs-* - 即可看到实时的 Nginx 日志:
- 可以通过字段筛选(如
status:404查看 404 错误) - 可以通过时间范围筛选(如最近 1 小时、最近 5 分钟)
- 可以搜索关键词(如在搜索框输入
request:/api查看 /api 路径的请求)
- 可以通过字段筛选(如
4. 生成测试日志(验证流程)
如果没有真实的 Nginx 访问日志,可以手动触发:
bash
运行
# 访问 Nginx 生成 access.log
curl http://你的服务器IP:8080
# 故意访问不存在的路径生成 404 日志
curl http://你的服务器IP:8080/xxx
刷新 Kibana 即可看到这些测试日志。
七、常见问题排查
- ES 启动失败:检查内存是否足够(至少 2G 可用),或修改
ES_JAVA_OPTS减小堆内存 - Kibana 无法连接 ES:检查
kibana.yml中的 ES 地址是否正确,确保 ES 已启动 - 日志未解析:查看 Logstash 日志
docker-compose logs -f logstash,检查 grok 解析规则是否匹配你的 Nginx 日志格式 - Filebeat 无权限读取日志:确保 Filebeat 容器以 root 用户运行,且日志文件权限为 777
总结
- 核心流程:Filebeat 采集 Nginx 日志 → Logstash 解析结构化 → ES 存储 → Kibana 可视化,通过 Docker Compose 可一键部署所有组件。
- 关键配置:Logstash 的 grok 规则必须匹配 Nginx 的日志格式,否则日志无法正确解析。
- 实用技巧:索引按天分片(
nginx-logs-%{+YYYY.MM.dd})便于日志管理,Kibana 索引模式关联@timestamp字段实现时间筛选。
整个流程部署完成后,你可以实时监控 Nginx 的访问日志、错误日志,还能基于这些日志做性能分析、错误排查等。
更多推荐
所有评论(0)