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 的应用流程。

相关推荐
我爱钱因此会努力3 小时前
ansible自动化运维入门篇
linux·运维·服务器·centos·自动化·ansible
CIb0la3 小时前
能保持精神专注的爱好能给生活带来种种积极的转变
运维·学习·生活
梁萌5 小时前
Linux安装mysql8.4.6
linux·运维·mysql安装·8.4.6
FreeBuf_5 小时前
Ubuntu内核曝严重UAF漏洞,可致攻击者获取Root权限
linux·运维·ubuntu
初学者_xuan7 小时前
零基础新手小白快速了解掌握服务集群与自动化运维(十六)集群部署模块——Keepalived双机热备
运维·自动化·github
行思理7 小时前
Dockerfile 各指令说明
运维·macos·docker·容器·php
半梦半醒*8 小时前
k8s——资源管理
linux·运维·docker·容器·kubernetes·自动化
gfdgd xi8 小时前
GXDE For deepin 25:deepin25 能用上 GXDE 了!
linux·运维·python·ubuntu·架构·bug·deepin
落世繁华9 小时前
Docker快速部署--Mysql一键初始化
运维·mysql·docker·容器·一键部署
叫我詹躲躲10 小时前
救命!MySQL 误删数据找不回?老运维私藏的备份技巧,免费给
运维·数据库