type
status
date
slug
summary
tags
category
icon
password
1、Logstash的工作原理
作为Elastic Stack的一分子,Logstash提供了一个数据采集的管道,它可以将原始数据抽取、转换并装载到Elasticsearch的索引中。无论是线上日志数据还是不断增长的数据库表数据,都可以通过Logstash快速、方便地写入Elasticsearch。Logstash拥有庞大的插件库,你可以通过添加插件的方式扩展Logstash的功能,以便它能够接入更多形式的数据。
Logstash的工作原理如图所示,数据源提供的数据进入Logstash的管道后需要经过3个阶段。
- input(输入):负责抽取数据源的数据,这个过程一般需要包含数据源的连接方式、通信协议和抽取间隔等信息,目的是将原始数据源源不断地接入数据管道。
- filter(过滤):将抽取到数据管道的数据按照业务逻辑的需要进行数据转换,例如添加或删除部分字段、修改部分字段的数据内容等。
- output(输出):将过滤后的数据写入数据的目的地,在大多数情况下,数据会被写入Elasticsearch的索引,你也可以编写配置把数据写入文件或其他地方。
当你启动一个Logstash的实例时,input部分会将数据源提供的数据抽取到内存队列中,数据管道的工作线程会从该队列中取出一批数据执行管道的过滤逻辑并将数据流输出到目的地。由于该队列默认保存在内存中,如果遇到运行故障,内存中的数据就存在丢失的风险,你可以使用配置将队列数据持久化地存储到外存上来降低数据丢失的可能性。
2、Logstash的安装和目录结构
Logstash 7.9.1的安装非常简单,以Windows平台上的安装为例,先在操作系统中安装好JDK 1.8,然后登录Elastic官方网站,进入Logstash 7.9.1的下载页面,下载ZIP格式的安装包,解压安装包并进行安装。
解压后,目录结构如下所示:
- bin目录:包含各种二进制形式的可执行脚本,例如Logstash的启动脚本、插件的安装脚本。
- config目录:包含各种Logstash的配置文件。
- data目录:是Logstash脚本执行时默认的数据目录。
- lib目录:包含Logstash运行时的库文件。
- logs目录:包含Logstash运行时产生的日志文件。
- logstash-core目录:包含Logstash的关键组件。
- logstash-core-plugin-api目录:包含Logstash的插件API。
- modules目录:包含Logstash拥有的模块文件。
- tools目录:包含Logstash运行时可用的工具组件。
- vendor目录:包含Logstash运行时依赖的Ruby环境。
- x-pack目录:包含Logstash的X-Pack插件扩展内容。要验证Logstash是否安装成功,需要从cmd进入Logstash的根目录,执行以下命令,若能看到命令行输出Logstash的版本号则说明安装成功。
要验证Logstash是否安装成功,需要从cmd进入Logstash的根目录,执行以下命令,若能看到命令行输出Logstash的版本号则说明安装成功。
3、Logstash的重要配置
在Logstash的config目录中,有几个比较重要的配置文件,正确地调整它们可以使Logstash运行在更好的状态,下面就来看看它们的含义和配置方法。
3.1 logstash.yml
该文件包含Logstash脚本执行时的重要参数,如果你在启动脚本的命令行中指定了相关配置,则会将logstash.yml中对应的配置覆盖掉,其中比较重要的配置如表10.1所示。
3.2 jvm.options
该文件主要用于调整Logstash的JVM堆内存大小,默认值为1GB。通常这个值应该配置为4GB~8GB,最好不要超过机器物理内存大小的一半。你可以动态地调整这个值并观察数据抽取的速度是否有提升。
3.3 pipelines.yml
如果想在一个Logstash进程中运行多个数据管道,则需要配置pipelines.yml文件,指明每个数据管道的配置参数。一个包含两个数据管道的配置例子如下。
这里配置了两个数据管道,一个的 id 为 nginx-log,另一个的 id 为 spring-boot-filebeat。对于没有声明的配置,会采用 logstash.yml 中的配置。
如果你想在一个Logstash节点上同时执行多个采集脚本,除了配置 pipelines.yml 文件外,还可以在命令行中指定不同的数据目录来执行脚本,例如使用下面的两条命令可以同时执行两个Logstash脚本a.conf和b.conf。
4、Logstash采集脚本
4.1 Logstash采集脚本结构
通常一个完整的采集脚本的配置中包含input、filter、output这3个部分,分别代表数据管道的输入、过滤和输出。其中输入和输出配置是必要的,过滤配置是可选的。
假如现在有一个Nginx的日志文件access.log,其中一条日志内容如下。
在Logstash的安装目录下新建一个采集脚本nginx-log.conf,脚本内容如下。
- 在input部分使用了file文件插件,它可以定期读取path路径配置的文本文件的新增内容到数据管道,从而完成对日志数据的采集。注意,即使是在Windows平台上,path的路径分隔符也要使用“/”而不是“\”。start_position设置为beginning表示第一次从头开始读取日志文件,如果不进行此设置,则默认file-input插件只读取新增的日志记录。
- 在filter部分添加了一个Grok插件,将数据流的message字段按照COMBINEDAPACHELOG的格式解析成多个结构化的字段。解析之后message字段仍然默认会存在。对于上面的日志文本,Grok插件解析后的格式数据如图所示。
- 在output部分,rubydebug编解码器可以将数据管道的每个字段输出到控制台上,方便开发人员调试和监控数据内容。另外还添加了Elasticsearch的输出目的地,表示将数据流写入索引。其中hosts用于配置Elasticsearch的地址,index用于配置数据写入的索引名称,action为“index”代表写入行为是建索引。
4.2 启动Logstash
执行下面启动命令,指定使用 nginx-log.conf 采集脚本收集数据
还有另外一种启动方式,先在 pipelines.yml 文件里面配置好数据管道
然后执行下面启动命令,不需要再手动指定采集脚本
4.3 同一个采集脚本指定多个 input/output
5、Logstash插件
所有插件参考 https://www.elastic.co/guide/en/logstash/current/filter-plugins.html。下面介绍几个常用的插件。
5.1 grok插件
5.1.1 grok 插件介绍
grok 是一种采用组合多个预定义的正则表达式,用来匹配分割文本并映射到关键字的工具。通常用来对日志数据进行预处理。logstash 的 filter 模块中 grok 插件是其实现之一。
grok 内置了许多的正则表达式库,便于我们直接使用开发。grok表达式语法:
- 模式名 - 指的就是预先定义好的正则表达式的别名,例如:IP 可以匹配ip内容。
- 自定义字段名 - 通过模式匹配到内容后,将内容保存到这个自定义的字段中
例如:
- %{IP:client} - 匹配IP内容,结果保存到client字段
- %{WORD:method} - 匹配非空字符串内容,结果保存到method字段
- %{URIPATHPARAM:request} - 匹配url路径,结果保存到request字段
- %{NUMBER:bytes} - 匹配数字,结果保存到bytes字段
logstash grok 预定义正则表达式如下,参考https://github.com/logstash-plugins/logstash-patterns-core/blob/main/patterns/legacy/grok-patterns
例如日志格式如下所示:
在 filter 里面使用 grok 插件
5.1.2 自定义grok模式
如果 grok 内置的模式无法满足需求,也可以自定义模式。模式定义语法:
- NAME - 模式名
- PATTERN - 表达式,包括正则表达式和 logstash 变量。
例如新建配置文件路径:
/opt/logstash/tizi_patterns
,文件内容如下在 filter 里面引用自定义表达式
5.1.3 在线调试grok
Kibana 支持在线调试 grok,如下所示
5.2 date插件
如果日志文件中产生了新的记录,新日志会被自动抽取到Logstash的数据管道中并写入索引。此时@timestamp字段代表的是数据经过Logstash处理的时间,你可以在 filter 部分添加一个 date 插件把日志中的timestamp字段的数据赋给@timestamp字段,把它变为日志的时间。例如:
5.3 mutate插件
mutate 插件支持增加/删除/重命名多个字段。
5.3.1 删除字段
把 message 字段解析成多个字段之后,默认仍然会保留 message 字段。另外如果使用 filebeat 采集日志信息后,这个过程中 filebeat 将自身的客户端信息也传送给了logstash,如果 logstash 不对这些字段进行过滤,导致创建索引时,产生大量没有必要的字段。
可以使用
remove_field
来移除字段,它可以接收的值是一个数组。5.3.2 正则表达式替换匹配字段
gsub
可以通过正则表达式替换字段中匹配到的值,只对字符串字段有效。5.3.3 分隔符分割字符串为数组
split
可以通过指定的分隔符分割字段中的字符串为数组5.3.4 重命名字段
5.4 multiline codec插件
Java 日志一般包含多行,这些多行应该是一个事件。这里我们要使用一个 multiline 的 codec 插件,来实现将这些多行合并到一个字段中去。
- Author:mcbilla
- URL:http://mcbilla.com/article/fe766712-a82c-4e2d-9973-279b2ceb9fb7
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!