CentOS7下搭建ELK日志监控平台

  ELK是elastic公司提供的一套完整的日志收集和展示的解决方案,是取自该公司三个开源软件的字首作为缩写,分别是Elasticssearch、Logstash、Kibana。它提供中心化的日志功能,协助用户发现服务器与应用服务的问题,在一个平台上就能搜索和监控所有日志,使得日志搜索和监控变得轻而易举。

  Elasticssearch是一个开源分布式搜索引擎,提供收集、分析、存储数据三大功能。它的特点有:分布式、零配置、自动发现、索引自动分片、索引副本机制、restful风格接口、多数据源、自动搜索负载等。

  Logstash是一个日志搜集、分析、过滤的工具,支持大量的数据获取方式。一般工作方式为c/s架构,client端安装在收集日志的主机上(该部分功能被Beats替代),server端负责将收到的各节点日志进行过滤、修改等操作,再一并发往Elasticssearch上。

  Kibana为Logstash和Elasticssearch提供了分析和可视化的Web页面,可以帮助汇总、分析和搜索重要数据日志,并生成各种维度表格和图形。

  Beats是用于数据采集的工具,相较于Logstash,Beats是更轻量级的工具。Beats平台集合了多种单一用途数据采集器,这些采集器安装后可用作轻量型代理,从成百上千或成千上万的机器向Logstash或Elasticssearch发送数据。Beats平台提供了如下几种常见的具体收集日志的工具:Filebeat(收集文件数据)、Metricbeat(收集指标数据)、Packetbeat(收集网络流量数据)、Winlogbeat(收集Windows事件日志数据)、Auditbeat(收集审计数据)、Heartbeat(收集运行心跳监控数据)、Functionbeat(收集无服务器基础架构数据)。

  官网(可以调成中文模式):https://www.elastic.co/

  下载地址:https://www.elastic.co/cn/downloads/

  支持一览表:https://www.elastic.co/cn/support/matrix

  注意:安装前请先根据系统版本,在支持一览表中找到合适的软件版本。

elk-stack-elkb-diagram

(1).实验环境

  4核8G内存 CentOS7.9.2009  192.168.142.110  监控端/服务端(Logstash+Elasticssearch+Kibana)

  4核8G内存 CentOS7.9.2009  192.168.142.111  被监控端/客户端(Nginx+Filebeat)

  所有服务器均已设置阿里云yum源和epel-release源,关闭SELinubx和防火墙。

(2).110服务器安装Logstash+Elasticssearch+Kibana

  我这里的系统是CentOS7.9.2009,根据支持一览表Elasticssearch最高版本为8.19.x,Kibana最高版本为8.19.x,Logstash最高版本为8.14.x,FileBeat最高版本为8.17.x。Elasticssearch在8.x版本后所有版本均自带JDK,不再提供无JDK版本的二进制包下载,当然你还是可以使用ES_JAVA_HOME环境变量来指定JDK的版本。

  1)二进制部署Elasticssearch

[root@localhost ~]# tar xvf elasticsearch-8.19.17-linux-x86_64.tar.gz -C /usr/local/
#新建elk用户
[root@localhost ~]# useradd elk
#将ES文件夹下所有文件所有者和所有者组更改为新建的elk
[root@localhost ~]# chown -R elk.elk /usr/local/elasticsearch-8.19.17/
#切换到elk用户下
[root@localhost ~]# su - elk
#-d表示后台运行
[elk@localhost ~]$ /usr/local/elasticsearch-8.19.17/bin/elasticsearch -d
#查看ES默认占用的端口9200和9300。9200用于对外提供 RESTful API 服务,支持数据的增删改查操作,以及集群本身状态的查询。9300用于 Elasticsearch 集群内部节点之间的通信。
[elk@localhost ~]$ ss -antp | grep -E  '9200|9300'
LISTEN     0      128       [::]:9200                  [::]:*                   users:(("java",pid=1534,fd=571))
LISTEN     0      128     [::ffff:127.0.0.1]:9300                  [::]:*                   users:(("java",pid=1534,fd=569))
LISTEN     0      128      [::1]:9300                  [::]:*                   users:(("java",pid=1534,fd=568))
[elk@localhost ~]$ ps -ef | grep 1534
elk        1534      1 44 23:28 pts/0    00:01:13 /usr/local/elasticsearch-8.19.17/jdk/bin/java -Des.networkaddress.cache.ttl=60
 -Des.networkaddress.cache.negative.ttl=10 -XX:+AlwaysPreTouch -Xss1m -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true
 -XX:-OmitStackTraceInFastThrow -Dio.netty.noUnsafe=true -Dio.netty.noKeySetOptimization=true -Dio.netty.recycler.maxCapacityPerThread=0
 -Dlog4j.shutdownHookEnabled=false -Dlog4j2.disable.jmx=true -Dlog4j2.formatMsgNoLookups=true -Djava.locale.providers=CLDR
 -Dorg.apache.lucene.vectorization.upperJavaFeatureVersion=26 -Des.path.home=/usr/local/elasticsearch-8.19.17 -Des.distribution.type=tar
 -Des.java.type=bundled JDK --enable-native-access=org.elasticsearch.nativeaccess,org.apache.lucene.core --enable-native-access=ALL-UNNAMED
 --illegal-native-access=deny -XX:ReplayDataFile=logs/replay_pid%p.log -XX:+EnableDynamicAgentLoading -Djdk.attach.allowAttachSelf=true
 --patch-module=java.base=/usr/local/elasticsearch-8.19.17/lib/entitlement-bridge/elasticsearch-entitlement-bridge-8.19.17.jar
 --add-exports=java.base/org.elasticsearch.entitlement.bridge=org.elasticsearch.entitlement,java.logging,java.net.http,java.naming,jdk.net,jdk.zipfs,jdk.management.agent
 -XX:+UseG1GC -Djava.io.tmpdir=/tmp/elasticsearch-10667007206045898252 --add-modules=jdk.incubator.vector -Dorg.apache.lucene.store.MMapDirectory.sharedArenaMaxPermits=1
 -XX:+HeapDumpOnOutOfMemoryError -XX:+ExitOnOutOfMemoryError -XX:ErrorFile=hs_err_pid%p.log
 -Xlog:gc*,gc+age=trace,safepoint:file=gc.log:utctime,level,pid,tags:filecount=32,filesize=64m -Xms3931m -Xmx3931m
 -XX:MaxDirectMemorySize=2061500416 -XX:G1HeapRegionSize=4m -XX:InitiatingHeapOccupancyPercent=30 -XX:G1ReservePercent=15
 --module-path /usr/local/elasticsearch-8.19.17/lib --add-modules=jdk.net --add-modules=jdk.management.agent --add-modules=ALL-MODULE-PATH
 -m org.elasticsearch.server/org.elasticsearch.bootstrap.Elasticsearch
elk        1558   1534  0 23:28 pts/0    00:00:00 /usr/local/elasticsearch-8.19.17/modules/x-pack-ml/platform/linux-x86_64/bin/controller
elk        1656   1437  0 23:31 pts/0    00:00:00 grep --color=auto 1534

    Elasticsearch 有三个配置文件,这些文件默认位于config目录中:

      • elasticsearch.yml用于配置 Elasticsearch
      • jvm.options用于配置 Elasticsearch 的 JVM 设置
      • log4j2.properties用于配置 Elasticsearch 日志记录

    elasticsearch.yml的配置格式为YAML,如果使用多种方式配置同一项设置,那么ES将会按“临时配置-->永久配置-->elasticsearch.yml配置-->默认配置”的优先级顺序应用这些配置。核心配置项如下:

1. 集群与节点设置 (Cluster & Node)
cluster.name: 集群名称。用于自动发现机制,确保节点能加入正确的集群。
node.name: 节点名称。用于标识集群中的单个节点,建议手动设置以便管理。
node.master / node.data: 节点角色配置。用于决定该节点是否有资格被选举为主节点(Master),以及是否用于存储数据(Data)。
2. 路径设置 (Paths)
path.data: 索引数据的存储路径。支持配置多个路径以分散磁盘 I/O 压力。
path.logs: 日志文件的存储路径。
3. 内存设置 (Memory)
bootstrap.memory_lock: 启动时锁定内存。建议设置为 true,以防止 JVM 发生内存交换(Swapping),从而保证 Elasticsearch 的性能。
4. 网络与端口 (Network & HTTP)
network.host: 绑定的 IP 地址。可以设置为具体的 IPv4/IPv6 地址,或特定关键字(如 _local_, _site_)。
http.port: HTTP 端口。默认通常为 9200,用于处理客户端的 REST API 请求。
5. 集群发现 (Discovery)
discovery.seed_hosts / cluster.initial_master_nodes: 节点发现与引导配置。用于在集群启动或新节点加入时,找到其他节点并防止“脑裂”(Split Brain)现象的发生。

    如果你使用的是 Elasticsearch 7.x 或 8.x 版本,默认情况下安全特性是开启的。所以我再展示一下安全认证相关的常用配置项:

1. 启用安全特性 (Security)
xpack.security.enabled: 核心开关,设置为 true 以启用 X-Pack 的安全特性,包括用户认证、角色授权等。
xpack.license.self_generated.type: 设置自生成的许可证类型(如 basic),用于激活基础的安全功能。
2. 传输层安全 (Transport SSL/TLS)
用于加密集群节点之间的内部通信(默认端口 9300),防止数据在节点间传输时被窃取,并防止恶意节点加入集群。
xpack.security.transport.ssl.enabled: 设置为 true 以启用节点间传输层的 SSL 加密。
xpack.security.transport.ssl.verification_mode: 设置 SSL 验证模式(如 certificate),确保客户端和服务器之间的连接安全。
xpack.security.transport.ssl.keystore.path: 指定包含身份验证公钥和私钥的密钥库文件路径(如 elastic-certificates.p12)。
xpack.security.transport.ssl.truststore.path: 指定包含用于验证服务器身份公钥的信任库文件路径。
xpack.security.transport.ssl.protocol: 强制指定 TLS 协议版本(如 TLSv1.2)。
xpack.security.transport.ssl.client_authentication: 启用客户端证书身份验证(双向 TLS),可设置为 required。
3. HTTP 层安全 (HTTP SSL/TLS)
用于加密 Elasticsearch 节点与外部客户端(如 Kibana、Logstash、应用程序)之间的通信(默认端口 9200)。
xpack.security.http.ssl.enabled: 设置为 true 以启用 HTTP 客户端通信的 SSL 加密。
xpack.security.http.ssl.keystore.path: 指定 HTTP 层使用的密钥库文件路径。
xpack.security.http.ssl.truststore.path: 指定 HTTP 层使用的信任库文件路径。
4. 身份验证与授权 (Authentication & Authorization)
xpack.security.authc.realms.file.file1.order: 配置基于文件的身份验证域的优先级顺序。
xpack.security.authc.realms.file.file1.location: 指定存储用户和角色信息的文件路径。
xpack.security.authc.realms.native.native1: 配置本地(Native)身份验证域,支持使用内置用户或本地数据库进行认证。

    更多配置请看官网的“配置Elasticsearch”:https://www.elastic.co/guide/en/elasticsearch/reference/8.19/settings.html

    a.在修改配置项network.host时遇到的常见报错

      常见报错如下:

[2026-06-28T11:18:31,367][ERROR][o.e.b.Elasticsearch      ] [localhost.localdomain] node validation exception
[2] bootstrap checks failed. You must address the points described in the following [2] lines before starting Elasticsearch. For more information see
 [https://www.elastic.co/guide/en/elasticsearch/reference/8.19/bootstrap-checks.html]
bootstrap check failure [1] of [2]: max file descriptors [4096] for elasticsearch process is too low, increase to at least [65535]; for more information
 see [https://www.elastic.co/guide/en/elasticsearch/reference/8.19/bootstrap-checks-file-descriptor.html]
bootstrap check failure [2] of [2]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]; for more information
、 see [https://www.elastic.co/guide/en/elasticsearch/reference/8.19/bootstrap-checks-max-map-count.html]

      核心原因当你将 network.host 设置为非回环地址时,Elasticsearch 会自动进入生产模式(Production Mode)。在生产模式下,为了保证系统的稳定性和性能,Elasticsearch 会强制执行一系列严格的检查。这个错误并非由 IP 设置直接引起,而是因为系统当前的配置不满足生产环境的要求:1、文件描述符限制过低(File Descriptor Check),当前值:4096,要求值:至少 65535。Elasticsearch 是一个高并发应用,需要同时处理大量文件和网络连接,默认的文件描述符限制(4096)太低,容易导致“Too Many Open Files”错误;2、最大虚拟内存区域数过低(Max Map Count Check),当前值:65530,要求值:至少262144。Elasticsearch 大量使用内存映射文件(mmap)来提高文件访问速度。vm.max_map_count 参数限制了单个进程可以拥有的内存映射区域数量。当前的值(65530)不足以支持 Elasticsearch 的正常运行。

      解决办法

#解决文件描述符限制问题
#新增针对elk用户的设置,文件最大打开数量,需要重新登录该用户或重启系统才能生效
[root@localhost ~]# vim /etc/security/limits.conf
elk soft nofile 65535
elk hard nofile 65535

#解决最大虚拟内存区域数问题
#新增或修改mmap 最大区域数,推荐值为 1048576,最低要求 262144
[root@localhost ~]# vim /etc/sysctl.conf
vm.max_map_count=262144
#使配置立即生效
[root@localhost ~]# sysctl -p
vm.max_map_count = 262144

#验证
[root@localhost ~]# su - elk
Last login: Sun Jun 28 11:19:29 CST 2026 on pts/0
[elk@localhost ~]$ /usr/local/elasticsearch-8.19.17/bin/elasticsearch -d
[elk@localhost ~]$ ss -antup | grep -E '9200|9300'
tcp    LISTEN     0      128    [::]:9200               [::]:*                   users:(("java",pid=12336,fd=570))
tcp    LISTEN     0      128      [::ffff:192.168.142.0]:9300               [::]:*                   users:(("java",pid=12336,fd=568))

  2)二进制部署Logstash

 

#退出elk用户,回到root用户下
[elk@localhost ~]$ exit
logout
[root@localhost ~]# tar xvf logstash-8.14.3-linux-x86_64.tar.gz -C /usr/local/
#将logstash文件夹下所有文件所有者和所有者组改为新建的elk
[root@localhost ~]# chown -R elk.elk /usr/local/logstash-8.14.3/
#切换到elk用户下
[root@localhost ~]# su - elk
Last login: Sun Jun 28 18:40:15 CST 2026 on pts/0

#使用grok过滤插件解析日志,使用grok自定义模式针对Nginx日志进行解析
[elk@localhost ~]$ vim /usr/local/logstash-8.14.3/grok-patterns
#Nginx Access Log
NGINXACCESS %{IPORHOST:remote_addr} - %{DATA:remote_user} \[%{HTTPDATE:time_local}\] "%{WORD:request_method} %{DATA:request_uri} HTTP/%{NUMBER:http_version}" %{NUMBER:status:int} %{NUMBER:body_bytes_sent:int} "%{DATA:http_referer}" "%{DATA:http_user_agent}" "%{DATA:http_x_forwarded_for}"

#Nginx Error Log
NGINXERRORLOGTIME %{YEAR}[/-]%{MONTHNUM}[/-]%{MONTHDAY} %{TIME}
NGINXERROR %{NGINXERRORLOGTIME:time_local} \[%{LOGLEVEL:log_level}\] %{NUMBER:pid}#%{NUMBER:tid}: \*%{NUMBER:connection_id} %{GREEDYDATA:error_message}

#创建Logstash配置文件
[elk@localhost ~]$ vim /usr/local/logstash-8.14.3/config/logstash.conf
#定义输入插件及配置
input{
    beats{
        port => "5044"
    }
}

#定义过滤插件及配置
filter{
    # 这里的tags是由Filebeat传过来的,所以值需要匹配上才能过滤
    if "nginx_access" in [tags] {
        # 使用自定义的grok模式解析日志
        grok{
            # 指定自定义模式文件所在位置
            patterns_dir => ["/usr/local/logstash-8.14.3/grok-patterns"]
            # 调用自定义的 NGINXACCESS 模式
            match => {"message" => "%{NGINXACCESS}"}
            # 当grok正则表达式无法成功匹配原始日志时,自动给该条日志添加一个自定义标签(Tag)
            tag_on_failure => ["_grokparsefailure_access"]
        }

        # 添加geoip地理位置解析
        geoip{
            # 指定要解析的IP字段,对应grok提取出的remote_addr字段
            source => "remote_addr"
            # 可选,指定解析结果存放的字段名(默认也是geoip)
            target => "geoip"
        }

        # 时间转换
        date {
            match => [ "time_local", "dd/MMM/yyyy:HH:mm:ss Z" ]
            # 把解析结果存放到"@timestamp"字段
            target => "@timestamp"
            # 移除"time_local"字段
            remove_field => [ "time_local" ]
        }
    }
    else if "nginx_error" in [tags] {
        grok{
            patterns_dir => ["/usr/local/logstash-8.14.3/grok-patterns"]
            match => {"message" => "%{NGINXERROR}"}
            tag_on_failure => ["_grokparsefailure_error"]
        }
        date {
            match => [ "time_local", "yyyy/MMM/dd HH:mm:ss" ]
            target => "@timestamp"
            remove_field => [ "time_local" ]
        }
    }
}

#定义输出插件及配置
output{
    if "nginx_access" in [tags] {
        elasticsearch{
            # 输出到本机9200端口
            hosts => ["https://127.0.0.1:9200"]
            # 每天自动创建一个独立的ES索引
            index => "nginx-access-%{+YYYY.MM.dd}"
            # 跳过证书验证(测试环境)
            ssl_certificate_verification => false
            # 指定 Elasticsearch 的 CA 证书(生产环境)
            # ssl_certificate_authorities => ["/path/to/http_ca.crt.pem"]
            # 可选,指定用户认证,密码是我后期直接重置的
            user => "elastic"
            password => "123456"
        }
    }
    else if "nginx_error" in [tags] {
        elasticsearch{
            hosts => ["https://127.0.0.1:9200"]
            index => "nginx-error-%{+YYYY.MM.dd}"
            ssl_certificate_verification => false
            user => "elastic"
            password => "123456"
        }
    }
    # 冗余策略
    else {
        elasticsearch{
            hosts => ["https://127.0.0.1:9200"]
            index => "unknown-%{+YYYY.MM.dd}"
            ssl_certificate_verification => false
            user => "elastic"
            password => "123456"
        }
    }
}
#后台启动
[elk@localhost ~]$ nohup /usr/local/logstash-8.14.3/bin/logstash -f /usr/local/logstash-8.14.3/config/logstash.conf >logstash-start.log 2>&1 &
[1] 12593
[elk@localhost ~]$ ss -antup | grep 5044
tcp    LISTEN     0      128    [::]:5044               [::]:*                   users:(("java",pid=12593,fd=111))

 

 

 

 

     a.grok语法

      Grok 最基本的语法格式为 %{SYNTAX:SEMANTIC}

      • SYNTAX(匹配类型):代表要匹配的数据类型,例如使用 NUMBER 匹配数字,使用 IP 匹配 IP 地址。
      • SEMANTIC(字段名称):代表存储匹配值的自定义变量名(字段名),该字段会被存入 Elasticsearch 中方便后续查询。例如 %{IP:client_ip_address} 会将匹配到的 IP 存入 client_ip_address 字段。

      在 Grok 语法中,SYNTAX(匹配类型)主要来源于 Logstash 预定义的正则表达式库(即 logstash-patterns-core 包)。官方提供了超过 120 种内置模式,涵盖了从简单的字符串到复杂的复合日志格式。最常见和常用的 SYNTAX 匹配类型如下:

1、基础数据类型
NUMBER:匹配任何数字(包括整数和小数)。例如 3.44、5000。
INT:匹配整数。
BASE10NUM:匹配十进制数字。
BASE16NUM:匹配十六进制数字。
WORD:匹配单个单词(通常由字母、数字或下划线组成)。
DATA:相当于正则表达式中的 .*?,匹配除换行符以外的任何字符,采用懒惰模式(匹配到第一个符合条件的即结束)。
2、网络与地址类型 IP:匹配标准的 IPv4 或 IPv6 地址。例如 192.168.21.2、55.3.244.1。 HOSTNAME:匹配主机名。 EMAILADDRESS:匹配完整的电子邮件地址,例如 fy123@mail.com。 EMAILLOCALPART:仅匹配电子邮件地址中 @ 符号前面的用户名部分。
3、用户与权限类型 USERNAME / USER:匹配用户名,通常由字母、数字及特殊字符(如 ._-)组成。
4、URI 与路径类型 URIPATHPARAM:匹配 URI 路径及其附带的参数。例如 /index.html。
5、复合/复合日志格式类型 HTTPDATE:匹配标准的 Web 服务器日志时间戳格式。 COMBINEDAPACHELOG:一个强大的复合模式,用于一次性解析整个 Apache 访问日志行。

      注意:由于内置模式非常丰富,建议您在实际使用时,直接查阅 Logstash 官方维护的 Grok 模式库源码(如 GitHub 上的 logstash-patterns-core 仓库),以获取最完整、最准确的 SYNTAX 列表。如果内置类型无法满足需求,您也可以使用 Oniguruma 正则语法自行定义匹配规则。

      Grok 进阶语法(带类型转换)格式为%{SYNTAX:SEMANTIC:TYPE}TYPE 是可选的,目前支持 intfloat。例如 %{NUMBER:duration:float} 会将匹配到的数字直接转换为浮点数类型。

      当 Logstash 内置的近 200 种模式无法满足需求时,可以使用自定义语法

方式一:使用 Oniguruma 正则语法
直接在表达式中使用 (?<field_name>the pattern here) 来匹配并命名。例如,匹配一个长度为 10 或 11 的十六进制队列 ID:
(?<queue_id>[0-9A-F]{10,11})
方式二:创建自定义 Pattern 文件 创建一个文件夹(如 ./patterns),在其中新建文件(如 postfix),写入自定义规则: POSTFIX_QUEUEID [0-9A-F]{10,11} 然后在 Logstash 中通过 patterns_dir 引入该文件夹,并在 match 中直接调用 %{POSTFIX_QUEUEID:queue_id}。

      实战演示1:假设有一条 Web 服务器日志:55.3.244.1 GET /index.html 15824 0.043,可以使用如下 Grok 模式进行解析:
%{IP:client_id_address} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:http_response_time}
。在 Logstash 配置文件中的写法如下:

filter {
  grok {
    match => { "message" => "%{IP:client_id_address} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:http_response_time}" }
  }
}

      实战演示2:假设有一条日志:System Status: [Service Unavailable] Error Code: 503,内置的 WORD 模式只能匹配单个单词(遇到空格就会停止)。如果您需要提取一个包含空格的完整句子或状态描述,可以使用如下Grok表达式:System Status: \[(?<system_status>[^\]]+)\] Error Code: (?<error_code>\d+)。在 Logstash 配置文件中的写法如下:

filter {
  grok {
    match => { "message" => "System Status: \[(?<system_status>[^\]]+)\] Error Code: (?<error_code>\d+)" }
  }
}

      注意:Grok 是 CPU 消耗大户,尽量使用预定义模式(如 %{IP}),少用极其复杂的自定义正则。

    b.Logstash配置文件

      Logstash 的配置文件主要用于定义数据处理管道,其核心结构由三个部分组成:input(输入)、filter(过滤,可选)和 output(输出)。配置文件使用大括号 {} 来定义区段,区段内部可以引入各种插件,插件的配置通过键值对的形式进行设置。

      一个标准的 Logstash 配置文件结构如下:

input {
  # 定义输入插件及配置
}

filter {
  # 定义过滤插件及配置(可选)
}

output {
  # 定义输出插件及配置
}

      在插件配置中,使用 => 符号进行变量赋值。Logstash 支持以下几种基本数据类型(注意:是=>符号后面的部分):

字符串 (String):host => "hostname"
数值 (Number):port => 5044
布尔值 (Boolean):debug => true
数组 (Array):match => ["datetime", "UNIX", "ISO8601"]
哈希 (Hash):options => { key1 => "value1", key2 => "value2" }

      字段引用:使用 [] 中括号来引用字段值。对于嵌套字段(如 JSON 或 Hash 结构),可以使用多重 [] 获取,例如 [options][key1]。

      内插变量:支持在字符串中动态引用字段值,格式为 %{[字段名]}。例如,根据日志类型动态生成 Elasticsearch 索引名称:index => "easymonitor-%{[fields][log_type]}-%{+yyyy.MM.dd}"

      Logstash 支持 if、else if 和 else 语句来实现条件路由。需要注意的是,Logstash 不支持 && 和 ||,必须使用英文单词 and 和 or支持的判断表达式包括:

比较大小:==, !=, <, >, <=, >=
正则匹配:=~ (匹配), !~ (不匹配)
包含关系:in, not in
布尔逻辑:and, or, nand, xor
取反操作:! (例如 !() 对复合表达式取反)

    c.Logstash 常用插件的配置示例速查表(AI生成)

      1. 常用 Filter(过滤器)插件速查

          Grok(文本解析),用于将非结构化日志转换为结构化数据。
grok {
  # 匹配 Nginx/Apache 组合日志格式
  match => { "message" => "%{COMBINEDAPACHELOG}" }
  
  # 自定义正则解析(命名捕获组)
  # match => { "message" => "%{IP:client_ip} - %{WORD:method} %{URIPATH:request}" }
  
  # 如果解析失败,不打标签(可选)
  # tag_on_failure => [] 
}

        Date(时间戳解析),极其重要:将日志中的字符串时间转换为 Logstash 的 @timestamp 字段。

date {
  match => [ "log_time", "yyyy-MM-dd HH:mm:ss", "ISO8601", "UNIX_MS" ]
  target => "@timestamp"
  timezone => "Asia/Shanghai"
}

        Mutate(字段操作),用于重命名、删除、替换或转换字段。

mutate {
  # 删除不需要的字段
  remove_field => [ "message", "host", "agent" ]
  
  # 重命名字段
  rename => { "old_name" => "new_name" }
  
  # 字段类型转换
  convert => { "response_code" => "integer" }
  
  # 字符串替换
  gsub => [ "request", "/\?.*/, "" ]
}

        JSON(JSON 解析),当你的日志本身就是 JSON 格式时使用。

json {
  source => "message"
  target => "parsed_json" # 解析后放入新字段,不写则覆盖原字段
}

      2. 常用 Input(输入)插件速查

        File(文件读取)

input {
  file {
    path => ["/var/log/nginx/access.log", "/var/log/nginx/error.log"]
    type => "nginx"
    start_position => "beginning" # 首次读取从头开始(之后依赖 sincedb 记录偏移量)
    sincedb_path => "/dev/null"   # 每次重启都从头读取(仅测试时使用!)
  }
}

        Beats(接收 Filebeat 等数据)

input {
  beats {
    port => 5044
    # 如果开启了 SSL
    # ssl => true
    # ssl_certificate => "/path/to/cert.pem"
    # ssl_key => "/path/to/key.pem"
  }
}

      3. 常用 Output(输出)插件速查

        Elasticsearch(写入 ES)

output {
  elasticsearch {
    hosts => ["http://es-node1:9200", "http://es-node2:9200"]
    
    # 动态索引名称(按天滚动)
    index => "logs-%{[type]}-%{+YYYY.MM.dd}"
    
    # 认证信息
    user => "elastic"
    password => "your_password"
    
    # 批量写入优化参数
    flush_size => 1000
    idle_flush_time => 5
  }
}

        Stdout(控制台输出),用于调试,查看数据流转情况。

output {
  stdout {
    codec => rubydebug  # 格式化输出,便于阅读
    # codec => json     # 以纯 JSON 格式输出
  }
}

  3)二进制部署Kibana

#退出elk用户,回到root用户下
[elk@localhost ~]$ exit
logout
[root@localhost ~]# tar xvf kibana-8.19.17-linux-x86_64.tar.gz -C /usr/local/
#将logstash文件夹下所有文件所有者和所有者组改为新建的elk
[root@localhost ~]# chown -R elk.elk /usr/local/kibana-8.19.17/
#切换到elk用户下
[root@localhost ~]# su - elk
Last login: Sun Jun 28 20:50:55 CST 2026 on pts/0
#备份配置文件
[elk@localhost ~]$ cp /usr/local/kibana-8.19.17/config/kibana.yml{,.bak}
#将server.host配置项由localhost改为192.168.142.110,允许浏览器通过该IP访问Kibana服务
[elk@localhost ~]$ vim /usr/local/kibana-8.19.17/config/kibana.yml
server.host: "192.168.142.110"
[elk@localhost ~]$ nohup /usr/local/kibana-8.19.17/bin/kibana > kibana-start.log 2>&1 &
[2] 12770
[elk@localhost ~]$ ss -antup | grep 5601
tcp    LISTEN     0      128    192.168.142.110:5601                  *:*                   users:(("node",pid=12770,fd=19))

    启动后看一下网页

image

     这里需要的令牌是由Elasticsearch产生,第一次启动会生成,只有30分钟的有效期。但我用的后台启动,所以我这边直接重新生成一个令牌:

[elk@localhost ~]$ /usr/local/elasticsearch-8.19.17/bin/elasticsearch-create-enrollment-token --scope kibana
eyJ2ZXIiOiI4LjE0LjAiLCJhZHIiOlsiMTkyLjE2OC4xNDIuMTEwOjkyMDAiXSwiZmdyIjoiZmZhMDkxMWRiNTQwNTc5NDgxNDI3MTRkMGI5Y2Q2OWUzOTljOGQxZDk1NDcwOGRiZTRlMzE0YWQwZmRkMGZhMiIsImtleSI6InJEOGlHWjhCUjF3Rm5vVXM4bmtsOmt5MmN6MktDTVJ5NGx1eHF3NVlPRlEifQ==

    将这串令牌复制给页面后点击“Configure Elastic”,弹出如下页面,这个验证码在我们后台启动日志“kibana-start.log”里面输出,直接输入后点击“Verify”即可。

image

     等待一段时间后直接进入到登录页面,二进制安装的Elasticsearch,默认账号为elastic,密码在首次启动 Elasticsearch 时,由系统自动生成并打印在控制台终端里的。但一样的原因,我并不知道登录密码,所以直接重置:

#使用-i选项是自己设置密码,不加则会随机生成。我这里设置的密码是“123456”
[elk@localhost logs]$ /usr/local/elasticsearch-8.19.17/bin/elasticsearch-reset-password -u elastic -i This tool will reset the password of the [elastic] user. You will be prompted to enter the password. Please confirm that you would like to continue [y/N]y Enter password for [elastic]: Re-enter password for [elastic]: Password for the [elastic] user successfully reset.

    之后使用账号密码登录就正常进入了。

image

 (3).111服务器安装Nginx+Filebeat

  1)源码部署nginx

[root@localhost ~]# yum -y install gcc gcc-c++ autoconf automake  zlib zlib-devel openssl openssl-devel pcre pcre-devel
[root@localhost ~]# tar xvf nginx-1.28.1.tar.gz 
[root@localhost ~]# useradd -s /sbin/nologin -M nginx
[root@localhost ~]# cd nginx-1.28.1
[root@localhost nginx-1.28.1]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_gzip_static_module --with-pcre
[root@localhost nginx-1.28.1]# echo $?
0
[root@localhost nginx-1.28.1]# make -j 4 && make install
[root@localhost nginx-1.28.1]# echo $?
0
[root@localhost nginx-1.28.1]# /usr/local/nginx/sbin/nginx

 

  2)二进制部署Filebeat

[root@localhost nginx-1.28.1]# cd .. 
[root@localhost ~]# tar xvf filebeat-8.17.10-linux-x86_64.tar.gz -C /usr/local/
[root@localhost ~]# cp /usr/local/filebeat-8.17.10-linux-x86_64/filebeat.yml{,.bak}
#对配置文件的inputs和output部分进行修改
[root@localhost ~]# vim /usr/local/filebeat-8.17.10-linux-x86_64/filebeat.yml
# ============================== Filebeat inputs ===============================

filebeat.inputs:

# 每一个 - 代表一个单独的输入(input)配置。大多数选项都可以在输入级别进行设置,因此你>可以为不同的采集需求配置不通的输入。
# 下面是针对特定输入类型的配置项。

# filestream 是一种用于从文件中采集日志消息的输入类型(input)。替代了 log 类型。
- type: filestream
  # 此 filestream 输入的唯一标识符(ID)。每个 filestream 输入都必须拥有一个唯一的ID。
  # 注意:id仅用于Filebeat内部状态跟踪
  id: nginx_access
  # 是否启用该输入配置
  enabled: true
  # 需要被扫描和抓取的文件路径。支持基于通配符(Glob)的路径。
  paths:
    - /usr/local/nginx/logs/access.log
  # 设置标签
  tags: ["nginx-access"]
  # 设置自定义字段
  fields:
    log_name: "nginx_access"

- type: filestream
  id: nginx-error
  enabled: true
  paths:
    - /usr/local/nginx/logs/error.log
  tags: ["nginx_error"]
  fields:
    log_name: "nginx_error"

······

# ================================== Outputs ===================================
#将输出到 Elasticsearch 的配置注释掉,打开输出到 Logstash 的配置
# ---------------------------- Elasticsearch Output ----------------------------
#output.elasticsearch:
  #hosts: ["localhost:9200"]
  #preset: balanced
# ------------------------------ Logstash Output -------------------------------
output.logstash:
  hosts: ["192.168.142.110:5044"]
[root@localhost ~]# nohup /usr/local/filebeat-8.17.10-linux-x86_64/filebeat -e -c /usr/local/filebeat-8.17.10-linux-x86_64/filebeat.yml > filebeat-start.log 2>&1 &
[1] 17496

  注意:标签和自定义字段在用于Logstash判断时,只要二选一即可。自定义字段在Logstash中判断的写法为if [fields][log_name] == "nginx_access",标签在Logstash中判断的写法为if "nginx_access" in [tags]。

  官方filebeat参考手册:https://www.elastic.co/guide/en/beats/filebeat/index.html

(4).测试

  浏览器打开192.168.142.111和192.168.142.111/error,使得nginx产生access.log日志和error.log日志。

  接着到ELK服务器上使用命令curl -k -u elastic -XGET "https://localhost:9200/_cat/indices?v"查看所有ES索引中,或者使用命令curl -k -u elastic -XGET "https://localhost:9200/<索引名称>/_settings?pretty"查看指定的ES索引,如下图:

 

image

  然后用浏览器登录到Kibana(192.168.142.110:5601),左上角菜单-->Management下的Stack Management-->Kibana下的Data View-->Create Data View-->填写相关信息(如果不填写Name,将会自动同步Index pattern的值)-->Save data view to Kibana。

image

image

image

  左上角菜单-->Analytics下的Discover,后续就是正常使用了。

 

 

image

image

image

 

 

 

 

参考:https://cloud.tencent.com/developer/article/2161527

   https://www.omniwaresoft.com.tw/product-news/elastic-news/elk-what-is-elk-stack/

posted @ 2026-07-03 15:26  苦逼运维  阅读(7)  评论(0)    收藏  举报