我会一步步带你完成从环境准备到最终在 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. 创建索引模式

  1. 左侧菜单 → 管理 → 索引模式 → 创建索引模式
  2. 输入索引名称:nginx-logs-* → 下一步
  3. 时间字段选择:@timestamp → 创建索引模式

3. 查看实时日志

  1. 左侧菜单 → 分析 → 发现
  2. 顶部选择刚创建的索引模式 nginx-logs-*
  3. 即可看到实时的 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 即可看到这些测试日志。

七、常见问题排查

  1. ES 启动失败:检查内存是否足够(至少 2G 可用),或修改 ES_JAVA_OPTS 减小堆内存
  2. Kibana 无法连接 ES:检查 kibana.yml 中的 ES 地址是否正确,确保 ES 已启动
  3. 日志未解析:查看 Logstash 日志 docker-compose logs -f logstash,检查 grok 解析规则是否匹配你的 Nginx 日志格式
  4. Filebeat 无权限读取日志:确保 Filebeat 容器以 root 用户运行,且日志文件权限为 777

总结

  1. 核心流程:Filebeat 采集 Nginx 日志 → Logstash 解析结构化 → ES 存储 → Kibana 可视化,通过 Docker Compose 可一键部署所有组件。
  2. 关键配置:Logstash 的 grok 规则必须匹配 Nginx 的日志格式,否则日志无法正确解析。
  3. 实用技巧:索引按天分片(nginx-logs-%{+YYYY.MM.dd})便于日志管理,Kibana 索引模式关联 @timestamp 字段实现时间筛选。

整个流程部署完成后,你可以实时监控 Nginx 的访问日志、错误日志,还能基于这些日志做性能分析、错误排查等。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐