logstash教程

Logstash 从入门到实战教程

目录

  1. [Logstash 简介](#Logstash 简介 "#1-logstash-%E7%AE%80%E4%BB%8B")
  1. [Logstash 核心架构](#Logstash 核心架构 "#2-logstash-%E6%A0%B8%E5%BF%83%E6%9E%B6%E6%9E%84")
  1. 环境准备与安装
    • 3.1 系统要求
    • 3.2 安装步骤(Linux/Windows)
    • 3.3 验证安装
  1. [Logstash 基础配置(核心)](#Logstash 基础配置(核心) "#4-logstash-%E5%9F%BA%E7%A1%80%E9%85%8D%E7%BD%AE%E6%A0%B8%E5%BF%83")
    • 4.1 配置文件结构(Input → Filter → Output)
    • 4.2 第一个 Demo:标准输入 → 标准输出
    • 4.3 常用 Input 插件配置
    • 4.4 常用 Filter 插件配置(Grok 解析日志)
    • 4.5 常用 Output 插件配置(Elasticsearch)
  1. 实战案例
    • 5.1 案例 1:采集本地日志文件到 Elasticsearch
    • 5.2 案例 2:接收 Filebeat 采集的分布式日志
  1. [Logstash 运维与优化](#Logstash 运维与优化 "#6-Logstash-%E8%BF%90%E7%BB%B4%E4%B8%8E%E4%BC%98%E5%8C%96")
    • 6.1 查看 Logstash 日志
    • 6.2 性能优化(线程、内存配置)
    • 6.3 常见问题排查
  1. 附录:常用插件参考

1. Logstash 简介

Logstash 是 Elastic Stack(ELK Stack:Elasticsearch、Logstash、Kibana)的核心组件之一,定位为 开源日志采集与数据处理引擎,主要功能:

  • 数据采集:从文件、数据库、消息队列、网络端口等多种来源获取数据;
  • 数据处理:对原始数据进行过滤、清洗、转换(如日志解析、字段提取、格式统一);
  • 数据输出:将处理后的数据发送到 Elasticsearch、Kafka、文件等目标存储。

适用场景:日志集中管理、数据格式标准化、多源数据聚合(如将应用日志、服务器日志、数据库日志统一导入 Elasticsearch 分析)。

2. Logstash 核心架构

Logstash 基于 管道(Pipeline) 工作,每个管道由三部分组成,流程为:Input → Filter → Output,且三部分均通过插件扩展功能。

组件 作用 常用插件示例
Input 采集数据,从外部数据源读取原始数据到 Logstash 管道 file(文件)、beats(接收 Filebeat)、stdin(标准输入)、kafka(消息队列)
Filter 处理数据,对 Input 采集的原始数据进行清洗、转换、提取字段(可选环节) grok(日志解析)、mutate(字段修改)、date(时间格式化)、json(JSON 解析)
Output 输出数据,将 Filter 处理后的结构化数据发送到目标存储 elasticsearch(Elasticsearch)、stdout(标准输出)、file(本地文件)、kafka

注意:Filter 是可选的(若无需处理数据,可直接 Input → Output);一个 Logstash 实例可配置多个 Pipeline(多管道并行工作)。

3. 环境准备与安装

3.1 系统要求

  • 操作系统:Linux(推荐 CentOS/Ubuntu)、Windows、macOS;
  • Java 环境:Logstash 依赖 JDK,需安装 JDK 11+(与 Elasticsearch 版本兼容,建议统一使用 Elastic 官方 JDK);
  • 资源配置:最低 2C 4G(生产环境建议 4C 8G 以上,根据日志量调整)。

3.2 安装步骤(以 Linux 为例,CentOS 7)

步骤 1:安装 JDK(若未安装)
bash 复制代码
# 1. 下载 Elastic 官方 JDK(以 JDK 17 为例)
wget https://artifacts.elastic.co/downloads/jdk/corretto-17.0.9-linux-x64.tar.gz
# 2. 解压到 /usr/local
tar -zxf corretto-17.0.9-linux-x64.tar.gz -C /usr/local
# 3. 配置环境变量
echo 'export JAVA_HOME=/usr/local/amazon-corretto-17.0.9.8.1-linux-x64' >> /etc/profile
echo 'export PATH=$JAVA_HOME/bin:$PATH' >> /etc/profile
source /etc/profile
# 4. 验证 Java 安装
java -version  # 输出 java version "17.0.9" 表示成功
步骤 2:安装 Logstash(以 8.10.0 版本为例)
bash 复制代码
# 1. 下载 Logstash 安装包(Elastic 官方源)
wget https://artifacts.elastic.co/downloads/logstash/logstash-8.10.0-linux-x86_64.tar.gz
# 2. 解压到 /usr/local
tar -zxf logstash-8.10.0-linux-x86_64.tar.gz -C /usr/local
cd /usr/local && ln -s logstash-8.10.0 logstash  # 创建软链接,方便操作
# 3. (可选)配置 Logstash 环境变量
echo 'export LOGSTASH_HOME=/usr/local/logstash' >> /etc/profile
echo 'export PATH=$LOGSTASH_HOME/bin:$PATH' >> /etc/profile
source /etc/profile
3.2.2 Windows 安装步骤
  1. 下载 Logstash 压缩包(网下载地址);
  1. 解压到本地目录(如 D:\logstash-8.10.0);
  1. 配置 JAVA_HOME 环境变量(指向 JDK 11+ 目录);
  1. 打开命令提示符(CMD),进入 D:\logstash-8.10.0\bin 目录,执行后续命令。

3.3 验证安装

通过 标准输入 → 标准输出 的简单命令验证 Logstash 是否正常运行:

bash 复制代码
# Linux/macOS 执行(直接在终端输入,无需配置文件)
logstash -e 'input { stdin {} } output { stdout {} }'
# Windows 执行(在 Logstash 的 bin 目录下)
logstash.bat -e "input { stdin {} } output { stdout {} }"
  • -e:表示 "临时配置",直接在命令行写简单的 Pipeline 配置,无需单独创建配置文件;
  • 执行后,终端会提示 Successfully started Logstash API endpoint,此时输入任意内容(如 hello logstash),Logstash 会将输入内容以结构化格式输出(默认 JSON 格式),示例:
ini 复制代码
{
  "@timestamp" => 2025-09-17T08:30:00.123Z,
  "message" => "hello logstash",
  "@version" => "1",
  "host" => "localhost"  # 主机名,根据实际环境显示
}
  • 按 Ctrl + C 退出验证。

4. Logstash 基础配置(核心)

Logstash 生产环境中需通过 配置文件 定义 Pipeline(而非 -e 临时配置),配置文件为 UTF-8 编码的文本文件,语法遵循 Ruby 风格(键值对用 => 分隔,字符串用单引号 / 双引号)。

4.1 配置文件结构

一个完整的 Pipeline 配置文件包含 Input、Filter(可选)、Output 三部分,示例框架:

ini 复制代码
# 示例:配置文件框架(文件名可自定义,如 logstash-demo.conf)
input {
  # 输入源配置(可配置多个 Input 插件,用逗号分隔)
  stdin {}  # 标准输入
  file {    # 本地文件输入(示例)
    path => "/var/log/nginx/access.log"  # 日志文件路径
    start_position => "beginning"        # 从文件开头读取(默认从末尾)
  }
}
filter {
  # 数据处理配置(可选,可配置多个 Filter 插件)
  grok {
    match => { "message" => "%{COMBINEDAPACHELOG}" }  # 用预定义模式解析 Apache/Nginx 日志
  }
  date {
    match => { "timestamp" => "dd/MMM/yyyy:HH:mm:ss Z" }  # 格式化时间字段
    target => "@timestamp"  # 将解析后的时间赋值给 @timestamp 字段(Logstash 默认时间字段)
  }
}
output {
  # 数据输出配置(可配置多个 Output 插件,数据会发送到所有 Output)
  stdout {
    codec => rubydebug  # 输出格式为"易读的 Ruby 调试格式"(默认 JSON)
  }
  elasticsearch {
    hosts => ["http://es-node1:9200", "http://es-node2:9200"]  # ES 集群地址
    index => "logstash-demo-%{+YYYY.MM.dd}"  # 索引名(按日期分片,如 logstash-demo-2025.09.17)
    user => "elastic"  # ES 用户名(若启用安全认证)
    password => "your-es-password"  # ES 密码
  }
}

4.2 第一个 Demo:标准输入 → 标准输出(配置文件版)

步骤 1:创建配置文件

在 Logstash 的 config 目录下创建 logstash-stdin.conf 文件:

ini 复制代码
# logstash-stdin.conf
input {
  stdin {
    add_field => { "source_type" => "manual_input" }  # 新增字段,标记数据来源
  }
}
output {
  stdout {
    codec => rubydebug  # 输出易读格式,方便调试
  }
}
步骤 2:启动 Logstash 并加载配置文件
lua 复制代码
# Linux/macOS 执行(-f 表示"加载指定配置文件")
logstash -f /usr/local/logstash/config/logstash-stdin.conf
# Windows 执行(在 bin 目录下)
logstash.bat -f ..\config\logstash-stdin.conf
  • 启动成功后,输入任意内容(如 test config file),Logstash 会输出包含 source_type: manual_input 字段的结构化数据,说明配置生效。

4.3 常用 Input 插件配置

4.3.1 File 插件(采集本地文件日志)

用于采集服务器本地日志文件(如 Nginx 访问日志、应用程序日志),核心参数:

ini 复制代码
input {
  file {
    path => ["/var/log/nginx/access.log", "/var/log/app/*.log"]  # 日志文件路径(支持通配符)
    start_position => "beginning"  # 读取位置:beginning(开头)、end(末尾,默认)
    sincedb_path => "/usr/local/logstash/data/sincedb"  # 记录文件读取进度的文件(避免重复读取)
    ignore_older => 86400  # 忽略 24 小时前的旧文件(单位:秒)
    discover_interval => 15  # 每隔 15 秒检查一次新文件(单位:秒)
    add_field => { "log_type" => "nginx_access" }  # 新增字段,标记日志类型
  }
}
  • 关键说明:sincedb_path 用于记录每个文件的读取进度(如已读取到第几行),Logstash 重启后会从上次中断的位置继续读取,避免重复采集;若需重新读取所有文件,可删除 sincedb 文件后重启。
4.3.2 Beats 插件(接收 Filebeat 采集的日志)

当日志分布在多台服务器时,通常用 Filebeat(轻量级采集器)在每台服务器采集日志,再发送到 Logstash 处理(Filebeat 资源占用远低于 Logstash,适合分布式场景)。Logstash 配置 Beats 插件接收数据:

ini 复制代码
input {
  beats {
    port => 5044  # 监听 5044 端口(Filebeat 需配置此端口发送数据)
    host => "0.0.0.0"  # 允许所有地址访问(生产环境建议指定内网地址)
    ssl => false  # 是否启用 SSL 加密(生产环境建议开启,需配置证书)
  }
}
  • 对应 Filebeat 配置(参考):
yaml 复制代码
# Filebeat 配置文件(filebeat.yml)
filebeat.inputs:
  - type: filestream
    paths:
      - /var/log/app/*.log  # Filebeat 采集的日志路径
output.logstash:
  hosts: ["logstash-server:5044"]  # Logstash 服务器地址和端口

4.4 常用 Filter 插件配置(核心:Grok 解析日志)

Filter 是 Logstash 数据处理的核心,其中 Grok 插件 用于解析非结构化日志(如 Nginx 日志、Tomcat 日志),将其转换为结构化字段(便于后续在 Kibana 中筛选、聚合)。

4.4.1 Grok 基础:预定义模式与自定义模式

Grok 通过 "模式匹配" 提取日志中的字段,Elastic 提供了大量 预定义模式 (如 %{IP} 匹配 IP 地址、%{NUMBER} 匹配数字、%{COMBINEDAPACHELOG} 匹配 Apache/Nginx 访问日志),完整预定义模式可参考 Grok 模式库

示例 1:解析 Nginx 访问日志

Nginx 访问日志默认格式(在 nginx.conf 中定义):

dart 复制代码
log_format combined '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"';

对应的 Grok 配置(用预定义模式 %{COMBINEDAPACHELOG} 直接匹配):

ini 复制代码
filter {
  grok {
    match => { "message" => "%{COMBINEDAPACHELOG}" }  # 匹配 Nginx/Apache 组合日志格式
    # 若匹配失败,将错误信息写入 tags 字段(便于排查)
    tag_on_failure => ["grok_parse_failed"]
  }
  # (可选)删除原始 message 字段(解析后已提取结构化字段,原始字段可删除节省空间)
  mutate {
    remove_field => ["message"]
  }
}
  • 解析后生成的结构化字段:remote_addr(客户端 IP)、remote_user(远程用户)、request(请求内容,如 GET /index.html HTTP/1.1)、status(HTTP 状态码)、body_bytes_sent(发送字节数)等。

示例 2:自定义 Grok 模式(解析自定义日志)

若日志格式为自定义(如 2025-09-17 10:30:00 [INFO] user=zhangsan action=login),需自定义 Grok 模式:

ini 复制代码
filter {
  grok {
    # 自定义模式:%{YEAR}-%{MONTHNUM2}-%{MONTHDAY} %{TIME} 匹配时间;%{WORD} 匹配单词(如 INFO、login)
    match => { "message" => "%{YEAR}-%{MONTHNUM2}-%{MONTHDAY} %{TIME} [%{WORD:log_level}] user=%{WORD:username} action=%{WORD:action}" }
    # 给字段添加自定义名称:log_level(日志级别)、username(用户名)、action(操作)
    tag_on_failure => ["grok_parse_failed"]
  }
  # 格式化时间字段(将日志中的时间赋值给 @timestamp)
  date {
    match => { "timestamp" => "yyyy-MM-dd HH:mm:ss" }  # 日志中的时间格式
    target => "@timestamp"
    remove_field => ["timestamp"]  # 删除原始时间字段
  }
}

4.4.2 常用 Filter 插件:Mutate(完整示例)

Mutate 插件是 Logstash 最灵活的 Filter 之一,支持对字段进行多种修改操作,以下是常见用法的综合示例:

dart 复制代码
filter {
  mutate {
    # 1. 重命名字段(如将 "remote_addr" 改为 "client_ip",避免字段名歧义)
    rename => { "remote_addr" => "client_ip" }
    
    # 2. 类型转换(如将 "status" 从字符串转为整数,便于后续在 Kibana 中聚合计算)
    convert => { "status" => "integer" "body_bytes_sent" => "integer" }
    
    # 3. 添加字段(手动添加固定值字段,标记日志来源服务器)
    add_field => { "server_ip" => "192.168.1.100" "log_source" => "nginx_server" }
    
    # 4. 删除无用字段(如删除 Logstash 自动生成的 "host" 字段,保留自定义的 "server_ip")
    remove_field => { "host" "message" }
    
    # 5. 字段值替换(如将 "log_level" 中的 "WARN" 替换为 "WARNING",统一格式)
    gsub => [ "log_level", "WARN", "WARNING" ]
    
    # 6. 截取字段(如截取 "request" 字段的前 100 个字符,避免字段过长)
    substring => { "request" => 0 => 100 }
  }
}

关键说明:Mutate 插件的操作按配置顺序执行,建议先做 "类型转换" 和 "重命名",再做 "添加 / 删除字段",避免后续操作依赖的字段不存在。

4.4.3 常用 Filter 插件:JSON(解析 JSON 格式日志)

若日志本身是 JSON 格式(如应用程序输出的结构化日志),无需用 Grok 手动解析,直接用 JSON 插件即可自动提取字段,示例:

dart 复制代码
# 假设原始日志格式:{"user_id": "123", "action": "purchase", "amount": 99.9, "timestamp": "2025-09-17 14:30:00"}
filter {
  json {
    source => "message"  # 指定从 "message" 字段中解析 JSON 数据
    target => "json_data"  # (可选)将解析后的 JSON 字段放入 "json_data" 嵌套字段中
    # 若不指定 target,解析后的字段会直接平铺到顶层(如 "user_id"、"action" 直接作为顶层字段)
    remove_field => "message"  # 解析完成后删除原始 "message" 字段
  }
  
  # 配合 date 插件格式化时间(使用 JSON 中的 "timestamp" 字段)
  date {
    match => { "timestamp" => "yyyy-MM-dd HH:mm:ss" }
    target => "@timestamp"
    remove_field => "timestamp"
  }
}

优势:相比 Grok,JSON 插件解析效率更高,且无需编写复杂的匹配模式,适合结构化日志场景。

4.5 常用 Output 插件配置

Output 插件决定 Logstash 处理后的数据流向,以下是生产环境中最常用的 2 种 Output 配置:

4.5.1 Elasticsearch 插件(核心输出目标)

将结构化数据写入 Elasticsearch,是 ELK Stack 的标准流程,支持集群、认证、按日期分片索引等功能,完整配置:

ini 复制代码
output {
  elasticsearch {
    # 1. ES 集群地址(多个节点用逗号分隔,Logstash 会自动负载均衡)
    hosts => ["http://es-node1:9200", "http://es-node2:9200", "http://es-node3:9200"]
    
    # 2. 索引名配置(按日期分片,如 "nginx-access-2025.09.17",便于日志按天管理)
    index => "nginx-access-%{+YYYY.MM.dd}"  # %{+YYYY.MM.dd} 是 Logstash 时间格式化语法
    
    # 3. 安全认证(若 ES 启用了 xpack.security,必须配置)
    user => "elastic"  # ES 用户名(建议使用有索引写入权限的专用用户,如 "logstash_writer")
    password => "YourESPassword123!"  # 对应密码
    
    # 4. 索引模板(可选,提前定义索引的映射结构,避免字段类型自动识别错误)
    template => "/usr/local/logstash/config/templates/nginx-template.json"  # 模板文件路径
    template_name => "nginx-template"  # 模板名称
    template_overwrite => true  # 允许覆盖已存在的模板
    
    # 5. 批量写入优化(提升写入性能,生产环境建议配置)
    flush_size => 500  # 累计 500 条数据批量写入一次
    idle_flush_time => 10  # 若 10 秒内未达到 flush_size,也触发批量写入
  }
}

索引模板示例(nginx-template.json):

提前定义字段类型(如 client_ip 为 IP 类型、status 为整数类型),避免 ES 自动识别错误:

perl 复制代码
{
  "template": "nginx-access-*",  # 匹配所有以 "nginx-access-" 开头的索引
  "mappings": {
    "properties": {
      "client_ip": { "type": "ip" },
      "status": { "type": "integer" },
      "body_bytes_sent": { "type": "integer" },
      "request": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } },
      "@timestamp": { "type": "date" }
    }
  }
}
4.5.2 File 插件(输出到本地文件)

适合无需实时分析、仅需本地备份日志的场景(如非核心日志的归档),配置示例:

ini 复制代码
output {
  file {
    path => "/data/logstash/output/nginx-access-%{+YYYY.MM.dd}.log"  # 输出文件路径(按日期分片)
    codec => line {  # 输出格式:每行一条 JSON 数据(便于后续读取解析)
      format => "%{[@timestamp]} %{client_ip} %{status} %{request}"  # 自定义输出格式(可选)
      # 若不自定义 format,默认输出完整 JSON 结构
    }
    flush_interval => 5  # 每隔 5 秒刷新一次缓冲区到文件(默认 2 秒)
    gzip => true  # 启用 GZIP 压缩,减少磁盘占用(可选)
  }
}

5. 实战案例(生产环境常用场景)

5.1 案例 1:采集本地 Nginx 日志到 Elasticsearch

场景描述

某服务器上运行 Nginx,需将 Nginx 访问日志(非结构化)通过 Logstash 解析为结构化数据,最终写入 Elasticsearch,便于在 Kibana 中查看访问量、错误率等指标。

步骤 1:确认 Nginx 日志格式

Nginx 配置文件(nginx.conf)中定义的访问日志格式(默认 combined 格式):

dart 复制代码
http {
  log_format combined '$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 combined;  # 日志路径和格式
}
步骤 2:编写 Logstash 配置文件(nginx-access.conf)
ini 复制代码
input {
  # 采集本地 Nginx 访问日志文件
  file {
    path => "/var/log/nginx/access.log"
    start_position => "end"  # 从文件末尾开始读取(避免重复采集历史日志)
    sincedb_path => "/usr/local/logstash/data/sincedb_nginx"  # 记录读取进度
    discover_interval => 10  # 每 10 秒检查一次日志文件是否有新增
    add_field => { "log_type" => "nginx_access" }  # 标记日志类型
  }
}
filter {
  # 1. 用 Grok 解析 Nginx combined 格式日志
  grok {
    match => { "message" => "%{COMBINEDAPACHELOG}" }
    tag_on_failure => ["grok_parse_failed"]  # 解析失败的日志会添加此标签
  }
  
  # 2. 用 Mutate 优化字段
  mutate {
    rename => { "remote_addr" => "client_ip" "http_x_forwarded_for" => "proxy_ip" }
    convert => { "status" => "integer" "body_bytes_sent" => "integer" }
    remove_field => ["message", "host", "http_referer", "http_user_agent"]  # 删除无用字段
  }
  
  # 3. 用 Date 格式化时间(使用日志中的 "time_local" 字段)
  date {
    match => { "time_local" => "dd/MMM/yyyy:HH:mm:ss Z" }  # Nginx 时间格式:17/Sep/2025:15:30:00 +0800
    target => "@timestamp"
    remove_field => "time_local"
  }
}
output {
  # 1. 输出到 Elasticsearch(按日期分片索引)
  elasticsearch {
    hosts => ["http://es-node1:9200", "http://es-node2:9200"]
    index => "nginx-access-%{+YYYY.MM.dd}"
    user => "elastic"
    password => "YourESPassword123!"
    template => "/usr/local/logstash/config/templates/nginx-template.json"
    template_overwrite => true
  }
  
  # 2. (可选)输出到标准输出,方便调试(生产环境可注释)
  stdout {
    codec => rubydebug
  }
}
步骤 3:启动 Logstash 并验证
bash 复制代码
# 1. 启动 Logstash(指定配置文件,后台运行)
nohup logstash -f /usr/local/logstash/config/nginx-access.conf > /var/log/logstash/nginx-access.log 2>&1 &
# 2. 验证 Elasticsearch 索引是否生成
curl -u elastic:YourESPassword123! http://es-node1:9200/_cat/indices?v
# 若看到 "nginx-access-2025.09.17" 索引,说明数据已成功写入
# 3. 在 Kibana 中创建索引模式(Management → Index Patterns → Create index pattern)
# 输入 "nginx-access-*",选择时间字段 "@timestamp",即可在 Discover 中查看解析后的日志

5.2 案例 2:接收 Filebeat 采集的分布式应用日志

场景描述

多台应用服务器(如 Tomcat 服务器)输出 JSON 格式的应用日志,需用 Filebeat 在每台服务器采集日志,发送到 Logstash 处理后写入 Elasticsearch,实现分布式日志集中管理。

步骤 1:配置 Filebeat(每台应用服务器)

Filebeat 配置文件(filebeat.yml),负责采集本地日志并发送到 Logstash:

yaml 复制代码
filebeat.inputs:
  - type: filestream  # 采集文件流(Filebeat 7.17+ 推荐使用,替代旧的 "file" 类型)
    paths:
      - /var/log/tomcat/app.log  # 应用日志路径(JSON 格式)
    fields:
      log_type: "tomcat_app"  # 自定义字段,标记日志类型
    fields_under_root: true  # 将自定义字段放入顶层(而非嵌套在 "fields" 下)
# 输出到 Logstash(而非直接输出到 Elasticsearch)
output.logstash:
  hosts: ["logstash-server:5044"]  # Logstash 服务器地址和端口(Beats 插件默认监听 5044)
  ssl.enabled: false  # 生产环境建议开启 SSL,需配置证书(此处为简化关闭)
# (可选)开启 Filebeat 日志,便于排查问题
logging.level: info
logging.to_files: true
logging.files:
  path: /var/log/filebeat
  name: filebeat.log
  keepfiles: 7
  permissions: 0644
步骤 2:编写 Logstash 配置文件(tomcat-app.conf)

Logstash 接收 Filebeat 数据,解析 JSON 日志并写入 Elasticsearch:

ini 复制代码
input {
  # 启用 Beats 插件,监听 5044 端口接收 Filebeat 数据
  beats {
    port => 5044
    host => "0.0.0.0"  # 允许所有应用服务器访问
    ssl => false
  }
}
filter {
  # 解析 Filebeat 发送的 JSON 格式日志
  json {
    source => "message"  # 从 "message" 字段提取 JSON 数据
    remove_field => "message"  # 解析完成后删除原始字段
  }
  
  # 类型转换(如将 "response_time" 从字符串转为浮点数,用于计算平均响应时间)
  mutate {
    convert => { "response_time" => "float" "user_id" => "integer" }
    remove_field => ["agent", "input", "ecs"]  # 删除 Filebeat 自动添加的无用字段
  }
  
  # 格式化时间(使用应用日志中的 "log_time" 字段)
  date {
    match => { "log_time" => "yyyy-MM-dd HH:mm:ss.SSS" }  # 应用日志时间格式:2025-09-17 16:45:30.123
    target => "@timestamp"
    remove_field => "log_time"
  }
}
output {
  elasticsearch {
    hosts => ["http://es-node1:9200", "http://es-node2:9200"]
    index => "tomcat-app-%{+YYYY.MM.dd}"  # 按日期分片索引
    user => "elastic"
    password => "YourESPassword123!"
  }
  
  # 调试用:输出到标准输出
  stdout {
    codec => rubydebug
  }
}
步骤 3:启动服务并验证
bash 复制代码
# 1. 启动 Logstash(后台运行)
nohup logstash -f /usr/local/logstash/config/tomcat-app.conf > /var/log/logstash/tomcat-app.log 2>&1 &
# 2. 在每台应用服务器启动 Filebeat(后台运行)
nohup filebeat -e -c /etc/filebeat/filebeat.yml > /var/log/filebeat/start.log 2>&1 &
# 3. 验证:在 Elasticsearch 中查看索引数据
curl -u elastic:YourESPassword123! http://es-node1:9200/tomcat-app-2025.09.17/_search?q=*&pretty
# 若返回解析后的结构化数据(如 "user_id"、"response_time" 字段),说明配置成功

6. Logstash 运维与优化

6.1 查看 Logstash 日志(排查问题核心)

Logstash 日志默认存储在 $LOGSTASH_HOME/logs 目录下,关键日志文件:

  • logstash-plain.log:主日志文件,包含启动信息、错误信息、Pipeline 运行状态(最常用);
  • logstash-slowlog-plain.log:慢日志文件,记录处理耗时超过阈值的事件(默认关闭,需手动开启)。
常用日志查看命令
perl 复制代码
# 1. 实时查看主日志(排查启动失败或运行中报错)
tail -f /usr/local/logstash/logs/logstash-plain.log
# 2. 搜索包含 "error" 的日志(定位错误原因)
grep -i "error" /usr/local/logstash/logs/logstash-plain.log
# 3. 查看 Pipeline 启动状态(确认配置是否加载成功)
grep -i "pipeline started" /usr/local/logstash/logs/logstash-plain.log
开启慢日志(优化性能瓶颈)

在 Logstash 主配置文件($LOGSTASH_HOME/config/logstash.yml)中添加以下配置,开启慢日志:

yaml 复制代码
slowlog.threshold.warn: 10s    # 处理耗时超过 10 秒的事件,记录 WARN 级慢日志
slowlog.threshold.info: 5s     # 处理耗时超过 5 秒的事件,记录 INFO 级慢日志
slowlog.threshold.debug: 2s    # 处理耗时超过 2 秒的事件,记录 DEBUG 级慢日志
slowlog.threshold.trace: 1s    # 处理耗时超过 1 秒的事件,记录 TRACE 级慢日志
slowlog.path: logs/logstash-slowlog-plain.log  # 慢日志存储路径(默认已配置)

使用场景:当 Logstash 处理延迟过高时,通过慢日志定位耗时环节(如 Grok 解析复杂日志、Elasticsearch 写入超时),针对性优化。

6.2 性能优化(生产环境必看)

Logstash 性能瓶颈多集中在 Filter 解析Output 写入 环节,需从资源配置、插件参数、架构设计三方面优化:

6.2.1 资源配置优化(JVM 与进程)
  1. JVM 内存配置(核心)

Logstash 基于 JVM 运行,内存不足会导致频繁 GC,严重影响性能。修改 $LOGSTASH_HOME/config/jvm.options:

ruby 复制代码
# 初始堆内存与最大堆内存保持一致(避免频繁扩容,推荐设置为物理内存的 1/2 ~ 2/3)
-Xms4g  # 初始堆内存(如 4G,根据服务器内存调整)
-Xmx4g  # 最大堆内存(与 -Xms 相同)
# 禁用 UseConcMarkSweepGC(CMS 垃圾收集器,JDK 9+ 已废弃),改用 G1GC
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200  # G1GC 最大暂停时间(默认 200ms,避免长暂停)

注意:32G 内存服务器建议设置 -Xms16g -Xmx16g,不要超过 31G(JVM 对 32G 以上内存管理效率下降)。

  1. Worker 线程配置

Logstash 用 "Worker 线程" 并行处理事件,修改 logstash.yml 调整线程数:

yaml 复制代码
pipeline.workers: 4  # Worker 线程数(推荐设置为 CPU 核心数的 1~2 倍,如 4 核 CPU 设为 4)
pipeline.batch.size: 125  # 每个 Worker 单次处理的事件数(默认 125,可根据内存调整)
pipeline.batch.delay: 5  # 批次延迟时间(毫秒,默认 5,平衡吞吐量与延迟)

原理:pipeline.workers × pipeline.batch.size 决定 Logstash 单次并行处理的最大事件数,需避免过大导致内存溢出。

6.2.2 插件级优化(针对性提升效率)
  1. Filter 优化(减少解析耗时)
    • 优先用 JSON 插件替代 Grok:JSON 解析效率是 Grok 的 3~5 倍,若应用能输出 JSON 日志,尽量避免用 Grok;
    • Grok 模式优化:避免使用复杂正则(如 .* 贪婪匹配),优先用预定义模式(如 %{IP} 替代自定义 IP 正则);
    • 添加条件过滤:用 if 语句跳过无需处理的日志(如仅处理 ERROR 级日志),减少无效计算:
ini 复制代码
filter {
  if [log_level] != "ERROR" {
    drop {}  # 丢弃非 ERROR 级日志,不进入后续处理
  }
  grok {
    match => { "message" => "%{COMBINEDAPACHELOG}" }
  }
}
  1. Output 优化(提升写入吞吐量)
    • Elasticsearch 批量写入:在 elasticsearch 插件中配置 flush_size 和 idle_flush_time(参考 4.5.1 配置),避免单条写入;
    • 禁用 Output 重试:生产环境建议关闭 retry_on_conflict(默认 1),减少重试开销,若需保证数据不丢失,可配合 dead_letter_queue(死信队列):
ini 复制代码
output {
  elasticsearch {
    hosts => ["http://es-node1:9200"]
    retry_on_conflict => 0  # 禁用重试
  }
  # 配置死信队列:将写入失败的日志存储到本地,后续手动处理
  dead_letter_queue {
    path => "/data/logstash/dead_letter_queue"
    max_bytes => "10gb"  # 死信队列最大容量
  }
}
6.2.3 架构优化(分布式场景)

当日志量超过单台 Logstash 处理能力时,需通过 "多实例 + 负载均衡" 扩展:

  1. 部署多 Logstash 实例:在多台服务器部署 Logstash,均配置相同的 Pipeline(如接收 Filebeat 数据);
  1. Filebeat 负载均衡:修改 Filebeat 配置,将日志分发到多台 Logstash:
yaml 复制代码
output.logstash:
  hosts: ["logstash-1:5044", "logstash-2:5044"]  # 多 Logstash 地址
  loadbalance: true  # 启用负载均衡(默认 false)
  worker: 2  # Filebeat 并发发送线程数(推荐 2~4)
  1. 避免单点故障:多 Logstash 实例接入同一 ES 集群,任一 Logstash 宕机不影响整体流程。

6.3 常见问题排查(实战经验)

问题现象 可能原因 解决方案
Logstash 启动失败,日志报 Address already in use 5044 端口被占用(Beats 插件默认端口) 1. 用 `netstat -tuln
Grok 解析失败,日志报 grok_parse_failed 1. 日志格式与 Grok 模式不匹配;2. 日志包含特殊字符(如中文) 1. 用 GrokDebugger 验证模式(输入日志和模式,查看匹配结果);2. 确保日志编码为 UTF-8,在 Filebeat 中配置 encoding: utf-8
Elasticsearch 写入失败,日志报 401 Unauthorized 1. ES 用户名 / 密码错误;2. 用户无索引写入权限 1. 验证 ES 账号密码(用 curl -u 用户名:密码 http://es-node1:9200 测试);2. 给用户添加写入权限(如通过 Kibana 角色管理,或执行 ES API:PUT /_security/role/logstash_writer { "indices": [{"names": ["*"], "privileges": ["create", "write"]}] })
Logstash 处理延迟高,慢日志显示 Filter 耗时久 1. Grok 模式复杂;2. Worker 线程数不足 1. 简化 Grok 模式,或改用 JSON 解析;2. 增加 pipeline.workers 线程数(不超过 CPU 核心数的 2 倍)

7. 附录:常用插件参考

7.1 Input 插件速查

插件名称 用途 核心参数 适用场景
stdin 标准输入 调试、测试
file 本地文件采集 path(文件路径)、sincedb_path(进度记录) 单服务器日志采集(如 Nginx 日志)
beats 接收 Filebeat 数据 port(监听端口)、ssl(是否启用 SSL) 分布式日志采集(多服务器 → Logstash)
kafka 从 Kafka 消费数据 bootstrap_servers(Kafka 地址)、topics(消费主题) 高吞吐场景(如实时日志流)

7.2 Filter 插件速查

插件名称 用途 核心参数 示例
grok 非结构化日志解析 match(字段与模式映射)、tag_on_failure(失败标签) match => { "message" => "%{COMBINEDAPACHELOG}" }
mutate 字段修改 rename(重命名)、convert(类型转换)、remove_field(删除字段) convert => { "status" => "integer" }
json JSON 日志解析 source(JSON 来源字段)、target(嵌套目标字段) source => "message"
date 时间格式化 match(原始时间格式)、target(目标时间字段) match => { "log_time" => "yyyy-MM-dd HH:mm:ss" }
drop 丢弃日志 if [log_level] == "INFO" { drop {} }

7.3 Output 插件速查

插件名称 用途 核心参数 适用场景
stdout 标准输出 codec(输出格式,如 rubydebug) 调试、测试
elasticsearch 写入 ES hosts(ES 地址)、index(索引名)、user/password(认证) ELK Stack 标准流程
file 写入本地文件 path(文件路径)、gzip(是否压缩) 日志本地归档
kafka 写入 Kafka bootstrap_servers(Kafka 地址)、topic(写入主题) 日志转发到 Kafka 供其他系统消费
dead_letter_queue 死信队列 path(存储路径)、max_bytes(最大容量) 存储处理失败的日志,避免数据丢失

8. 总结

Logstash 作为 Elastic Stack 的 "数据处理中枢",核心价值在于将多源非结构化数据转为结构化数据,并灵活分发到目标存储。学习 Logstash 的关键是:

  1. 掌握 Pipeline 核心流程:Input(采集)→ Filter(处理)→ Output(输出),理解各环节插件的作用;
  1. 重点突破 Filter 解析:Grok(非结构化)和 JSON(结构化)是最常用的解析插件,需熟练使用;
  1. 重视运维优化:生产环境需通过 JVM 配置、线程调整、架构扩展提升性能,避免因配置不当导致瓶颈;
  1. 结合实战练习:通过 "采集 Nginx 日志""接收 Filebeat 数据" 等案例,加深对配置的理解。

建议后续结合 Kibana 学习(如用 Kibana 查看 Logstash 写入 ES 的日志,制作可视化图表),完整掌握 ELK Stack 的应用流程。

相关推荐
chen9452 小时前
k8s集群部署vector日志采集器
运维
chen9452 小时前
aws ec2部署harbor,使用s3存储
运维
東雪蓮☆7 小时前
深入理解 LVS-DR 模式与 Keepalived 高可用集群
linux·运维·服务器·lvs
qq_264220897 小时前
LVS负载均衡群集和LVS+Keepalived群集
运维·负载均衡·lvs
乌萨奇也要立志学C++8 小时前
【Linux】进程概念(二):进程查看与 fork 初探
linux·运维·服务器
雨落Liy8 小时前
Nginx 从入门到进阶:反向代理、负载均衡与高性能实战指南
运维·nginx·负载均衡
Yyyy4828 小时前
Nginx负载均衡集群实验步骤
运维·nginx·负载均衡
獭.獭.10 小时前
Linux -- 信号【上】
linux·运维·服务器
hashiqimiya10 小时前
centos配置环境变量jdk
linux·运维·centos