Logstash:使用自定义正则表达式模式

news2025/1/15 21:22:40

有时 Logstash Grok 没有我们需要的模式。 幸运的是我们有正则表达式库:Oniguruma。在很多时候,如果 Logstash 所提供的正则表达不能满足我们的需求,我们选用定制自己的表达式。

定义

  • Logstash 是一种服务器端数据处理管道,可同时从多个来源获取数据,对其进行转换,然后将其发送到 “存储”(如 Elasticsearch)。
  • Grok 是 Logstash 中的过滤器,用于将非结构化数据解析为结构化和可查询的内容。
  • Regular expression 是定义搜索模式的字符序列。

如果你已经在运行 Logstash,则无需安装额外的正则表达式库,因为 Grok 位于正则表达式之上,因此任何正则表达式在 grok 中也有效 —— Elastic 文档。

语法

Grok

Grok 语法如下:

%{SYNTAX:SEMANTIC}
  • SYNTAX 是默认的 grok 模式
  • SEMANTIC 是 key

Oniguruma

oniguruma 语法如下:

(?<field_name>the pattern here)

Grok + Oniguruma

你可以像下面这样组合 Grok 和 Oniguruma:

%{SYNTAX:SEMANTIC} (?<field_name>the pattern here)

让我们开始吧

样本数据

为了演示我们如何将 Oniguruma 与 Grok 结合使用,我们将在示例中使用下面的日志数据。

production GET /v2/blacklist/ 200 24ms 5ba9e948801d34906b96e0c20 Panya/1.6.3 (com.sn.panya.host; build:1; iOS 10.3.3) Alamofire/4.66.0 {\"user_id\":\"5bd4c2f4569f470016bd8d55\",\"reason\":\"SPAMMER\"}

日志数据结构:

production == environment
GET == method
/v2/blacklist == url
200 == response_status
24ms == response_time
5bc6e716b5d6cb35fc9687c0 == user_id
Panya/1.6.3 (com.sn.panya.host; build:1; iOS 10.3.3) Alamofire/4.66.0 == user_agent
{\"user_id\":\"5bd4c2f4569f470016bd8d55\",\"reason\":\"SPAMMER\"} == req.body

目的:

目标是找到一种模式来构造非结构化日志数据。为此,我们将使用 Kibana 里的 Grok Debugger 来进行测试:

其中,我们的 Grok pattern 定义如下:

%{WORD:environment} %{WORD:method} %{URIPATH:url} %{NUMBER:response_status} %{WORD:response_time} %{USERNAME:user_id}

如上所示,上面的 Grok pattern 产生如下的结果:

{
  "environment": "production",
  "method": "GET",
  "response_status": "200",
  "user_id": "5ba9e948801d34906b96e0c20",
  "response_time": "24ms",
  "url": "/v2/blacklist/"
}

这是一个不错的开始,但还不完整。 没有 user_agent 和 req.body 的映射。要提取 user_agent 和 req.body,我们需要仔细检查其结构。

空格分隔符

值 production GET /v2/blacklist/ 200 24ms 5ba9e948801d34906b96e0c20 由空格分隔,这很容易使用。

但是,对于 user_agent,可以有动态数量的空格,具体取决于发送请求的硬件类型。

Panya/1.6.3 (com.sn.panya.host; build:1; iOS 10.3.3) Alamofire/4.66.0 

我们如何解释这种持续变化?

提示:看一下 req.body 的结构。

{\”user_id\”:\”5bd4c2f4569f470016bd8d55\”,\”reason\”:\”SPAMMER\”}

我们可以看到 req.body 是由花括号 {} 组成的。

利用这些知识,我们可以构建一个自定义正则表达式模式来查找第一个左括号之前的所有内容,然后获取之后的所有内容。

 在上面,我们使用 Grok pattern:

(?<user_agent>[^{]*) %{GREEDYDATA:body}

你可在这个链接中找到 “regex match everything until character”。

把所有的都放在一起

将其应用于 grok 调试器中的自定义正则表达式模式,我们得到了我们想要的结果:

我们的 Grok pattern 为:

%{WORD:environment} %{WORD:method} %{URIPATH:url} %{NUMBER:response_status} %{WORD:response_time} %{USERNAME:user_id} (?<user_agent>[^{]*) %{GREEDYDATA:body}

 

创建 logstash.conf

为了能够测试我们的 Grok pattern 是否正确,我们创建如下的一个 logstash.conf 文件。我们可以参考之前的文章 “Logstash:在实施之前测试 Logstash 管道/过滤器”。

logstash.conf

input {
  generator {
    message => 'production GET /v2/blacklist/ 200 24ms 5ba9e948801d34906b96e0c20 Panya/1.6.3 (com.sn.panya.host; build:1; iOS 10.3.3) Alamofire/4.66.0 {"user_id":"5bd4c2f4569f470016bd8d55","reason":"SPAMMER"}'
    count => 1
  }
}
 
filter {
  grok {
    match => { "message" => "%{WORD:environment} %{WORD:method} %{URIPATH:url} %{NUMBER:response_status} %{WORD:response_time} %{USERNAME:user_id1} (?<user_agent>[^{]*) %{GREEDYDATA:body}"}
  }

  mutate {
    remove_field => ["message", "event", "host", "@version"]
  } 
} 
 
output {
  stdout {
    codec => rubydebug
  }
}

我们使用如下的命令来启动 Logstash pipeline:

./bin/logstash -f logstash.conf

从上面的输出中,我们可以看出来原始的数据已经变为结构化的数据了。我们可以看到美中不足的是 body 这个数据是一个 JSON 格式的数据,还没有被结构化。我们进一步修改我们的 logstash.conf 配置文件:

logstash.conf

input {
  generator {
    message => 'production GET /v2/blacklist/ 200 24ms 5ba9e948801d34906b96e0c20 Panya/1.6.3 (com.sn.panya.host; build:1; iOS 10.3.3) Alamofire/4.66.0 {"user_id":"5bd4c2f4569f470016bd8d55","reason":"SPAMMER"}'
    count => 1
  }
}
 
filter {
  grok {
    match => { "message" => "%{WORD:environment} %{WORD:method} %{URIPATH:url} %{NUMBER:response_status} %{WORD:response_time} %{USERNAME:user_id1} (?<user_agent>[^{]*) %{GREEDYDATA:body}"}
  }

  json {
    source => "body"
  }

  mutate {
    remove_field => ["message", "event", "host", "@version", "body"]
  }

} 
 
output {
  stdout {
    codec => rubydebug
  }
}

在上面,我们添加了 json 过滤器来处理 body,从而更进一步结构化数据。我们再次运行 Logstash。我们可以看到如下的结果:

 

从上面,我们可以看到 body 也被结果化了。我们可以看到 user_id 及 reason 两个字段。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/415744.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

zabbix客户端配置

一、zabbix客户端配置 1.实验环境&#xff1a;关闭防火墙和安全模块 systemctl disable --now firewalld setenforce 0 2.服务端和客户端都要时间同步 yum install -y ntpdate #注意安装需要用网络源安装&#xff0c;不能用本地源 ntpda…

电子器件系列34:tvs二极管(2)

一、基本原理&#xff1a; 二、重要产数&#xff1a; 不同的资料对于相同的参数可能有不同的命名&#xff0c;要根据实际情况来确定参数的意义 这里以上图表格里的参数名称进行解析&#xff0c;以其他资料作为参考。 结合图表和伏安特性曲线&#xff0c;再结合下面的图我是…

你认为的.NET数据库连接池,真的是全部吗?

一般我们的项目中会使用1到2个数据库连接配置&#xff0c;同程艺龙的数据库连接被收拢到配置中心&#xff0c;由DBA统一配置和维护&#xff0c;业务方通过某个字符串配置拿到的是开箱即用的Connection对象。 DBA能在对业务方无侵入的情况下&#xff0c;让大规模微服务实例切换…

第二周P9-P22

文章目录第三章 系统总线3.1、总线的基本概念一、为什么要用总线二、什么是总线三、总线上信息的传送四、总线结构的计算机举例1、单总线结构框图2、面向CPU的双总线结构框图3、以存储器为中心的双总线结构图3.2、总线的分类1、片内总线2、系统总线3、通信走线3.3、总线特性及性…

基于多目标粒子群优化算法的计及光伏波动性的主动配电网有功无功协调优化(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Vivado中ILA(集成逻辑分析仪)的使用

Vivado中ILA&#xff08;集成逻辑分析仪&#xff09;的使用一、写在前面二、ILA(Integrated Logic Analyzer)的使用2.1 ILA查找2.2 ILA配置2.2.1 General Options2.2.2 Probe Ports三、ILA调用四、ILA联调4.1 信号窗口4.2 波形窗口4.3 状态窗口4.4 设置窗口4.5 触发条件设置窗口…

Segment Anything论文详解(SAM)

论文名称&#xff1a;Segment Anything 论文地址&#xff1a;https://arxiv.org/abs/2304.02643 开源地址&#xff1a;https://github.com/facebookresearch/segment-anything demo地址&#xff1a;Segment Anything | Meta AI 主要贡献&#xff1a;开发一个可提示的图像分…

6.Java数组

数组 一、数组概述 1、什么是数组&#xff1f; 数组是相同类型数据的有序集合。数组描述的是相同类型的若干个数据&#xff0c;按照一定的先后次序排列组合而成。其中&#xff0c;每一个数据称作一个元素&#xff0c;每个元素可以通过一个索引(下标)来访问它们。 2、数组的…

哈夫曼树和最小生成树

哈夫曼树 首先给我们一串权值&#xff0c;然后我们需要让这串权值组成一个树&#xff0c;然后当他的wpl最小 我们可以发现当他的小权值离根节点越远&#xff0c;大权值离根节点越近的时候&#xff0c;我们这个时候构建出来的树就是wpl最小的树&#xff0c;也就是我们说的哈夫曼…

c++之 类和对象

目录 1.类和对象的基本概念 1.c语言与c中的结构体 2.类的封装性 3.定义类 4.构造与析构 构造与析构的概念&#xff1a; 构造函数 析构函数 拷贝构造函数 c默认增加的函数 1.类和对象的基本概念 1.c语言与c中的结构体 我们知道在c语言里&#xff0c;我们是无法在结构体…

进程的开销比线程大在了哪里?

进程内部都有哪些数据&#xff1f; 为什么创建进程的成本很高&#xff1f; 这样的问题确实不好回答&#xff0c;除非你真正理解了进程和线程的原理&#xff0c;否则很容易掉入面试大坑。探究问题背后的原理&#xff0c;围绕面试题展开理论与实践知识的学习。真正理解进程和线…

centos7虚拟机下hbase的使用案例讲解

系列文章目录 centos7虚拟机在集群zookeeper上面配置hbase的具体操作步骤 centos7虚拟机配置集群时间同步的操作步骤_centos虚拟机时间同步 centos7配置zookeeper本地模式与集群模式的详细教程 卸载centos7自带的jdk的操作步骤_centos7 卸载java 虚拟机centos7配置Hadoop单…

如何用 Vitis HLS 实现 OpenCV 仿真

这篇文章的基础是《Windows上快速部署Vitis HLS OpenCV仿真库》&#xff0c;我们使用的版本是Vitis HLS 2022.2&#xff0c;其他版本BUG不清楚&#xff0c;目前已知2021版本有BUG&#xff0c;只能使用其他方式&#xff0c;本文不适合。 这次选择中值滤波这个常规算法作为演示算…

Springboot电脑商城项目

目录 系统概述与环境搭建 1 系统开发及运行环境 2 项目分析 3 创建数据库 4 创建Spring Initializr项目 5 配置并运行项目 6 导入前端项目 用户注册 1 用户-创建数据表 2 用户-创建实体类 3 用户-注册-持久层 4 用户-注册-业务层 5 用户-注册-控制器 6 用户-注册…

归并排序(递归实现)

上一次我们说了快排的其他版本&#xff0c;还有就是快排的非递归实现 这次我们就说一哈归并排序&#xff0c;归并排序也是很厉害的一种排序&#xff0c;而且归并排序的时间复杂度可以说成标准的O(n log n) 下面我们就来看一下归并排序 我们先来看一下什么是归并排序 假设我…

Scratch蓝桥杯实战训练 —— 巧解“韩信点兵”难题的五种方式

“韩信点兵”蓝桥杯问题描述&#xff1a; “蓝桥杯”中有一道有趣的 Scratch 编程题&#xff0c;题目要求为&#xff1a;韩信点兵 扩展知识&#xff1a; 这道题叫“中国余数定理”&#xff0c;又叫“孙子定理”&#xff0c;也叫“韩信点兵问题”&#xff0c;是我国古代数学智慧…

Faster-RCNN代码解读3:制作自己的数据加载器

Faster-RCNN代码解读3&#xff1a;制作自己的数据加载器 前言 ​ 因为最近打算尝试一下Faster-RCNN的复现&#xff0c;不要多想&#xff0c;我还没有厉害到可以一个人复现所有代码。所以&#xff0c;是参考别人的代码&#xff0c;进行自己的解读。 ​ 代码来自于B站的UP主&…

Node【三】Buffer 与 Stream

文章目录&#x1f31f;前言&#x1f31f;Buffer&#x1f31f; Buffer结构&#x1f31f; 什么时候用Buffer&#x1f31f; Buffer的转换&#x1f31f; Buffer使用&#x1f31f; 创建Buffer&#x1f31f; 字符串转Buffer&#x1f31f; Buffer转字符串&#x1f31f; 拼接Buffer&…

python 理解BN、LN、IN、GN归一化、分析torch.nn.LayerNorm()和torch.var()工作原理

目录 前言&#xff1a; 简言之BN、LN、IN、GN等归一化的区别&#xff1a; 批量归一化(Batch Normalization&#xff0c;BN) 优点 缺点 计算过程 层归一化(Layer Normalization&#xff0c;LN) 优点 计算过程 总结 分析torch.nn.LayerNorm()工作原理 分析torch.var(…

Vue2-黑马(十一)

目录&#xff1a; &#xff08;1&#xff09;vue2-联调准备 &#xff08;2&#xff09;vue2-登录实战-国际化 &#xff08;3&#xff09;vue2实战-登录-login-index.vue &#xff08;1&#xff09;vue2-联调准备 登录这个请求&#xff0c;并不是发给后台的&#xff0c;现在还…