系列文章目录
Elastic Stack之日志收集Logstash
Elastic Stock之日志收集:优化篇
Elastic Stack之应用系统日志结构化
前言
Logstash日志采集流程大致分为: 输入、过滤器和输出;三个步骤。我的架构方案是:
logback通过rabbitmq将日志传递到Logstash通过插件来实时过滤和结构化,
另外一种方案是在应用系统内使用logstash-logback-encoder来转码日志,效果如https://blog.csdn.net/wangxudongx/article/details/103743963。
这里我们介绍通过插件过滤的方案。
Logstash 能够动态地采集、转换和传输数据,不受格式或复杂度的影响。利用 Grok 从非结构化数据中派生出结构,从 IP 地址解码出地理坐标,匿名化或排除敏感字段,并简化整体处理过程。
筛选
实时解析和转换数据
数据从源传输到存储库的过程中,Logstash 过滤器能够解析各个事件,识别已命名的字段以构建结构,并将它们转换成通用格式,以便进行更强大的分析和实现商业价值。
Logstash 能够动态地转换和解析数据,不受格式或复杂度的影响:
利用 Grok 从非结构化数据中派生出结构
从 IP 地址破译出地理坐标
将 PII 数据匿名化,完全排除敏感字段
简化整体处理,不受数据源、格式或架构的影响
使用我们丰富的过滤器库和功能多样的 Elastic Common Schema,您可以实现无限丰富的可能。
想要将应用系统日志转成结构化数据放入ES我们需要做一些操作,当前有两个方案;一是在应用端使用logstash-logback-encoder库,另一个是使用Logstash提供的filter插件来做,这里我们使用filter插件,有关logstash-logback-encoder的使用请看博主的同系列文章。
提示:以下是本篇文章正文内容,下面案例可供参考
环境
组件 | 版本 |
---|---|
CentOS | 7 |
Docker | 20.10.7 |
elasticsearch | 7.6.2 |
logstash | 7.6.2 |
kibana | 7.6.2 |
rabbitmq | 3.8.9-management |
Logstash filter(筛选)
实时解析和转换数据
数据从源传输到存储库的过程中,Logstash 过滤器能够解析各个事件,识别已命名的字段以构建结构,并将它们转换成通用格式,以便进行更强大的分析和实现商业价值。
Logstash 能够动态地转换和解析数据,不受格式或复杂度的影响: 利用 Grok 从非结构化数据中派生出结构 从 IP 地址破译出地理坐标 将 PII 数据匿名化,完全排除敏感字段 简化整体处理,不受数据源、格式或架构的影响 使用丰富的过滤器库和功能多样的 Elastic Common Schema,您可以实现无限丰富的可能。
Grok 过滤器插件
Grok是Logstash众多过滤器插件当中的一个,是将非结构化日志数据解析为结构化和可查询的东西的好方法。原理是使用正则表达式。
这里我们使用的插件版本:v4.2.0
默认情况下,Logstash 附带大约 120 种模式。你可以在这里找到它们:https://github.com/logstash-plugins/logstash-patterns-core/tree/master/patterns
你可以简单地添加你自己的。(见patterns_dir设置)
Grok 还是 Dissect?或两者?
该dissect过滤器插件是另一种方式,以提取非结构化事件数据到使用定界符字段。
Dissect 与 Grok 的不同之处在于它不使用正则表达式并且速度更快。当数据可靠地重复时,解剖效果很好。当您的文本结构因行而异时,Grok 是更好的选择。
您可以将 Dissect 和 Grok 用于混合用例,当线路的一部分可靠地重复,但整条线路不是。Dissect 过滤器可以解构重复的线段。Grok 过滤器可以处理具有更多正则表达式可预测性的剩余字段值。
这里我不对DIssect进行介绍了,有兴趣可以自行去看文档。
grok官方文档
https://www.elastic.co/guide/en/logstash/current/plugins-filters-grok.html
Grok 基础知识
Grok用的正则表达式库是 Oniguruma
Grok 的工作原理是将文本模式组合成与您的日志相匹配的内容。
grok 模式的语法是 %{SYNTAX:SEMANTIC:TYPE}
SYNTAX是,将匹配文本模式的名称。直白来说就是一段Logstash或者你自定义的正则表达式的名字。
比如说MINUTE (?:[0-5][0-9])
MINUTE就是(?:[0-5][0-9])`这段表达式的名字,可以在pipeline的grok段使用。
该SEMANTIC是你给一段文字的标识相匹配之后所生成的字段名称。例如,35可能是事件的持续时间,因此您可以简单地将其称为minute。
对于上面的示例,您的 grok 过滤器将如下所示:
%{ MINUTE:持续时间}
您还可以选择向您的 grok 模式添加数据类型转换。默认情况下,所有语义都保存为字符串。如果您希望转换语义的数据类型,例如将字符串更改为整数,然后使用目标数据类型作为后缀。例如%{NUMBER:num:int},将num语义从字符串转换为整数。目前唯一支持的转换是int和float。
自带的grok 方法
cat /usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-patterns-core-4.1.2/patterns/grok-patterns
https://github.com/logstash-plugins/logstash-patterns-core/tree/master/patterns
配置pipeline
pipeline 配置
如果在Logstash默认提供的匹配模式中没有找到适合的,我们也可以用正则表达式自定义模式。
如下面的配置项patterns_dir
就是指定自定义配置模式的文件。
配置文件内容示例:
USERNAME [a-zA-Z0-9._-]+
USER %{USERNAME}
input {
rabbitmq {
host => "3.8.23.16"
port => 5672
user => admin
password => "blke134343"
durable => true
queue => "q_logstash"
codec => plain
}
}
filter{
grok{
patterns_dir => "/usr/share/logstash/my-grok-pattern"
match => { "message" => "%{DATESTAMP:logTime} %{THREAD:thread} %{LOGLEVEL:logLevel} %{GREEDYDATA:logContent}"
}
remove_field => ["message"]
}
}
output {
stdout { codec => rubydebug }
elasticsearch { hosts => "172.17.0.3:9200" }
}
原本的日志
2021-07-20 10:26:24.952 [http-nio-6002-exec-9] DEBUG c.rocky.chats.mapper.ChatsUserinfoMapper.selectOne.? ? - ==> Preparing: SELECT create_by,create_time,update_by,update_time,id,nickname,sex,short_id,level,mobile,email,channel,deleted,headimg,pwd,birthday FROM chats_userinfo WHERE email = ? AND pwd = ? \n
{
"@version" => "1",
"@timestamp" => 2021-07-20T10:26:24.994Z,
"message" => "2021-07-20 10:26:24.952 [http-nio-6002-exec-9] DEBUG c.rocky.chats.mapper.ChatsUserinfoMapper.selectOne.? ? - ==> Preparing: SELECT create_by,create_time,update_by,update_time,id,nickname,sex,short_id,level,mobile,email,channel,deleted,headimg,pwd,birthday FROM chats_userinfo WHERE email = ? AND pwd = ? \n"
}
grok转换后的日志
{
"@version" => "1",
"@timestamp" => 2021-07-20T10:24:33.307Z,
"logTime" => "21-07-20 10:24:33.251",
"logContent" => "c.rocky.chats.mapper.ChatsUserinfoMapper.selectOne.? ? - ==> Preparing: SELECT create_by,create_time,update_by,update_time,id,nickname,sex,short_id,level,mobile,email,channel,deleted,headimg,pwd,birthday FROM chats_userinfo WHERE email = ? AND pwd = ? \n",
"thread" => "[http-nio-6002-exec-4]",
"logLevel" => "DEBUG"
}
在Kibana里面debug grok语句
如果你需要自定义匹配模式或者是构造一般的Grok语句,那么语法debugger工具会对你很有用。
菜单:Management -> Dev Tools -> Grok Debugger
另一个调试Grok Pattern的地方
https://grokdebug.herokuapp.com/
个人觉得没有Kibana好看。
在Kibana里面管理应用系统日志
需要先创建Kibana的Index Patterns
在Discover里面看日志
创建图表
保存查询
创建一个dashboard
总结
当前扁平化的日志基本就只够给开发、运维人员分析问题用了,想通过日志发掘出更多有用的信息我们就需要将日志当作数据入库再通过其它工具分析,而入库就肯定要结构化了,所以这是日志结构的应用场景。
当然想让日志变得更有用也要开发人员将日志输出尽量简要,形成规划的日志输出,这样更利于日志的后续利用。