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
注意:安装前请先根据系统版本,在支持一览表中找到合适的软件版本。

(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用于配置 Elasticsearchjvm.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 是可选的,目前支持 int 和 float。例如 %{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 {
# 匹配 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))
启动后看一下网页

这里需要的令牌是由Elasticsearch产生,第一次启动会生成,只有30分钟的有效期。但我用的后台启动,所以我这边直接重新生成一个令牌:
[elk@localhost ~]$ /usr/local/elasticsearch-8.19.17/bin/elasticsearch-create-enrollment-token --scope kibana eyJ2ZXIiOiI4LjE0LjAiLCJhZHIiOlsiMTkyLjE2OC4xNDIuMTEwOjkyMDAiXSwiZmdyIjoiZmZhMDkxMWRiNTQwNTc5NDgxNDI3MTRkMGI5Y2Q2OWUzOTljOGQxZDk1NDcwOGRiZTRlMzE0YWQwZmRkMGZhMiIsImtleSI6InJEOGlHWjhCUjF3Rm5vVXM4bmtsOmt5MmN6MktDTVJ5NGx1eHF3NVlPRlEifQ==
将这串令牌复制给页面后点击“Configure Elastic”,弹出如下页面,这个验证码在我们后台启动日志“kibana-start.log”里面输出,直接输入后点击“Verify”即可。

等待一段时间后直接进入到登录页面,二进制安装的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.
之后使用账号密码登录就正常进入了。

(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索引,如下图:

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



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



参考:https://cloud.tencent.com/developer/article/2161527
https://www.omniwaresoft.com.tw/product-news/elastic-news/elk-what-is-elk-stack/

浙公网安备 33010602011771号