使用 DISSECT 和 GROK 进行数据处理
编辑使用 DISSECT 和 GROK 进行数据处理
编辑您的数据可能包含您想要结构化的非结构化字符串。这使得数据分析更容易。例如,日志消息可能包含您想要提取的 IP 地址,以便您可以找到最活跃的 IP 地址。
Elasticsearch 可以在索引时或查询时结构化您的数据。在索引时,您可以使用 Dissect 和 Grok 摄取处理器,或者使用 Logstash 的 Dissect 和 Grok 过滤器。在查询时,您可以使用 ES|QL 的 DISSECT
和 GROK
命令。
DISSECT
或 GROK
?或者两者都用?
编辑DISSECT
通过使用基于分隔符的模式来分解字符串。 GROK
的工作方式类似,但使用正则表达式。这使得 GROK
更强大,但通常也更慢。DISSECT
在数据可靠重复时效果很好。GROK
是一款更好的选择,当您确实需要正则表达式的强大功能时,例如,当文本的结构在各行之间发生变化时。
您可以将 DISSECT
和 GROK
用于混合用例。例如,当某一部分行可靠地重复,但整行不重复时。DISSECT
可以分解重复的行部分。GROK
可以使用正则表达式处理其余的字段值。
使用 DISSECT
处理数据
编辑DISSECT
处理命令将字符串与基于分隔符的模式匹配,并将指定的键提取为列。
例如,以下模式
%{clientip} [%{@timestamp}] %{status}
匹配此格式的日志行
1.2.3.4 [2023-01-23T12:15:00.000Z] Connected
并导致将以下列添加到输入表中
clientip:keyword | @timestamp:keyword | status:keyword |
---|---|---|
1.2.3.4 |
2023-01-23T12:15:00.000Z |
已连接 |
Dissect 模式
编辑Dissect 模式由将被丢弃的字符串部分定义。在前面的示例中,第一个要丢弃的部分是一个空格。Dissect 找到这个空格,然后将 clientip
的值分配到该空格之前的全部内容。接下来,dissect 匹配 [
和 ]
,然后将 @timestamp
分配到 [
和 ]
之间的所有内容。特别注意要丢弃的字符串部分将有助于构建成功的 dissect 模式。
可以使用空键 (%{}
) 或 命名跳过键 来匹配值,但将值从输出中排除。
所有匹配的值都将作为关键字字符串数据类型输出。使用 类型转换函数 转换为另一种数据类型。
Dissect 还支持 键修饰符,可以更改 dissect 的默认行为。例如,您可以指示 dissect 忽略某些字段、追加字段、跳过填充等。
术语
编辑- dissect 模式
- 描述文本格式的一组字段和分隔符。也称为剖析。剖析使用一组
%{}
部分来描述:%{a} - %{b} - %{c}
- 字段
- 从
%{
到}
(包含)的文本。 - 分隔符
- 在
}
和下一个%{
字符之间的文本。除%{
、'not }'
或}
之外的任何字符集都是分隔符。 - 键
-
在
%{
和}
之间的文本,不包括?
、+
、&
前缀和序数后缀。示例
-
%{?aaa}
- 键是aaa
-
%{+bbb/3}
- 键是bbb
-
%{&ccc}
- 键是ccc
-
示例
编辑以下示例解析包含时间戳、一些文本和 IP 地址的字符串
ROW a = "2023-01-23T12:15:00.000Z - some text - 127.0.0.1" | DISSECT a """%{date} - %{msg} - %{ip}""" | KEEP date, msg, ip
date:keyword | msg:keyword | ip:keyword |
---|---|---|
2023-01-23T12:15:00.000Z |
一些文本 |
127.0.0.1 |
默认情况下,DISSECT
输出关键字字符串列。要转换为其他类型,请使用 类型转换函数
ROW a = "2023-01-23T12:15:00.000Z - some text - 127.0.0.1" | DISSECT a """%{date} - %{msg} - %{ip}""" | KEEP date, msg, ip | EVAL date = TO_DATETIME(date)
msg:keyword | ip:keyword | date:date |
---|---|---|
一些文本 |
127.0.0.1 |
2023-01-23T12:15:00.000Z |
Dissect 键修饰符
编辑键修饰符可以更改剖析的默认行为。键修饰符可能位于 %{keyname}
的左侧或右侧,始终位于 %{
和 }
之内。例如 %{+keyname ->}
具有追加和右填充修饰符。
右填充修饰符 (->
)
编辑执行剖析的算法非常严格,因为它要求模式中的所有字符都与源字符串匹配。例如,模式 %{fookey} %{barkey}
(1 个空格) 将匹配字符串 "foo bar" (1 个空格),但不会匹配字符串 "foo bar" (2 个空格),因为模式只有一个空格,而源字符串有两个空格。
右填充修饰符可以解决此问题。将右填充修饰符添加到模式 %{fookey->} %{barkey}
中,它现在将匹配 "foo bar" (1 个空格) 和 "foo bar" (2 个空格),甚至 "foo bar" (10 个空格)。
使用右填充修饰符允许在 %{keyname->}
后重复字符。
右填充修饰符可以与任何其他修饰符一起放置在任何键上。它应该始终是最右边的修饰符。例如:%{+keyname/1->}
和 %{->}
例如
ROW message="1998-08-10T17:15:42 WARN" | DISSECT message """%{ts->} %{level}"""
message:keyword | ts:keyword | level:keyword |
---|---|---|
1998-08-10T17:15:42 WARN |
1998-08-10T17:15:42 |
WARN |
右填充修饰符可以与空键一起使用,以帮助跳过不需要的数据。例如,相同的输入字符串,但用括号括起来,需要使用右填充空键才能获得相同的结果。
例如
ROW message="[1998-08-10T17:15:42] [WARN]" | DISSECT message """[%{ts}]%{->}[%{level}]"""
message:keyword | ts:keyword | level:keyword |
---|---|---|
["[1998-08-10T17:15:42] [WARN]"] |
1998-08-10T17:15:42 |
WARN |
追加修饰符 (+
)
编辑Dissect 支持将两个或多个结果追加到输出中。值从左到右追加。可以指定追加分隔符。在此示例中,append_separator 定义为空格。
ROW message="john jacob jingleheimer schmidt" | DISSECT message """%{+name} %{+name} %{+name} %{+name}""" APPEND_SEPARATOR=" "
message:keyword | name:keyword |
---|---|
john jacob jingleheimer schmidt |
john jacob jingleheimer schmidt |
按顺序追加修饰符 (+
和 /n
)
编辑Dissect 支持将两个或多个结果追加到输出中。值根据定义的顺序追加 (/n
)。可以指定追加分隔符。在此示例中,append_separator 定义为逗号。
ROW message="john jacob jingleheimer schmidt" | DISSECT message """%{+name/2} %{+name/4} %{+name/3} %{+name/1}""" APPEND_SEPARATOR=","
message:keyword | name:keyword |
---|---|
john jacob jingleheimer schmidt |
schmidt,john,jingleheimer,jacob |
命名跳过键 (?
)
编辑Dissect 支持忽略最终结果中的匹配项。这可以使用空键 %{}
来完成,但为了可读性,可能需要为该空键命名。
这可以使用 {?name}
语法使用命名跳过键来完成。在下面的查询中,ident
和 auth
没有添加到输出表中
ROW message="1.2.3.4 - - 30/Apr/1998:22:00:52 +0000" | DISSECT message """%{clientip} %{?ident} %{?auth} %{@timestamp}"""
message:keyword | clientip:keyword | @timestamp:keyword |
---|---|---|
1.2.3.4 - - 30/Apr/1998:22:00:52 +0000 |
1.2.3.4 |
30/Apr/1998:22:00:52 +0000 |
限制
编辑DISSECT
命令不支持引用键。
使用 GROK
处理数据
编辑GROK
处理命令将字符串与基于正则表达式的模式匹配,并将指定的键提取为列。
例如,以下模式
%{IP:ip} \[%{TIMESTAMP_ISO8601:@timestamp}\] %{GREEDYDATA:status}
匹配此格式的日志行
1.2.3.4 [2023-01-23T12:15:00.000Z] Connected
将其组合为 ES|QL 查询
ROW a = "1.2.3.4 [2023-01-23T12:15:00.000Z] Connected" | GROK a """%{IP:ip} \[%{TIMESTAMP_ISO8601:@timestamp}\] %{GREEDYDATA:status}"""
GROK
将以下列添加到输入表中
@timestamp:keyword | ip:keyword | status:keyword |
---|---|---|
2023-01-23T12:15:00.000Z |
1.2.3.4 |
已连接 |
Grok 模式中的特殊正则表达式字符,例如 [
和 ]
,需要使用 \
进行转义。例如,在之前的模式中
%{IP:ip} \[%{TIMESTAMP_ISO8601:@timestamp}\] %{GREEDYDATA:status}
在 ES|QL 查询中,当使用单引号表示字符串时,反斜杠字符本身就是一个特殊字符,需要使用另一个 \
进行转义。对于此示例,相应的 ES|QL 查询变为
ROW a = "1.2.3.4 [2023-01-23T12:15:00.000Z] Connected" | GROK a "%{IP:ip} \\[%{TIMESTAMP_ISO8601:@timestamp}\\] %{GREEDYDATA:status}"
因此,通常使用三引号 """
表示 GROK 模式更方便,因为不需要转义反斜杠。
ROW a = "1.2.3.4 [2023-01-23T12:15:00.000Z] Connected" | GROK a """%{IP:ip} \[%{TIMESTAMP_ISO8601:@timestamp}\] %{GREEDYDATA:status}"""
Grok 模式
编辑Grok 模式的语法为 %{SYNTAX:SEMANTIC}
SYNTAX
是匹配文本的模式名称。例如,3.44
由 NUMBER
模式匹配,55.3.244.1
由 IP
模式匹配。语法是匹配的方式。
SEMANTIC
是您赋予被匹配文本片段的标识符。例如,3.44
可以是事件的持续时间,因此您可以简单地将其称为 duration
。此外,字符串 55.3.244.1
可能标识发出请求的 client
。
默认情况下,匹配的值以关键字字符串数据类型输出。要转换语义的数据类型,请在其后附加目标数据类型。例如 %{NUMBER:num:int}
,它将 num
语义从字符串转换为整数。当前仅支持 int
和 float
转换。对于其他类型,请使用类型转换函数。
正则表达式
编辑Grok 基于正则表达式。任何正则表达式在 grok 中也都是有效的。Grok 使用 Oniguruma 正则表达式库。有关完整支持的正则表达式语法的详细信息,请参阅Oniguruma GitHub 存储库。
自定义模式
编辑如果 grok 没有您需要的模式,您可以使用 Oniguruma 语法进行命名捕获,这允许您匹配一段文本并将其保存为一列
(?<field_name>the pattern here)
例如,postfix 日志具有一个 queue id
,它是一个 10 或 11 个字符的十六进制值。这可以使用以下方式捕获到名为 queue_id
的列中:
(?<queue_id>[0-9A-F]{10,11})
示例
编辑以下示例解析包含时间戳、IP 地址、电子邮件地址和数字的字符串
ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 [email protected] 42" | GROK a """%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num}""" | KEEP date, ip, email, num
date:keyword | ip:keyword | email:keyword | num:keyword |
---|---|---|---|
2023-01-23T12:15:00.000Z |
127.0.0.1 |
42 |
默认情况下,GROK
输出关键字字符串列。int
和 float
类型可以通过在模式中的语义后附加 :type
来转换。例如 {NUMBER:num:int}
ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 [email protected] 42" | GROK a """%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num:int}""" | KEEP date, ip, email, num
date:keyword | ip:keyword | email:keyword | num:integer |
---|---|---|---|
2023-01-23T12:15:00.000Z |
127.0.0.1 |
42 |
对于其他类型转换,请使用类型转换函数
ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 [email protected] 42" | GROK a """%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num:int}""" | KEEP date, ip, email, num | EVAL date = TO_DATETIME(date)
ip:keyword | email:keyword | num:integer | date:date |
---|---|---|---|
127.0.0.1 |
42 |
2023-01-23T12:15:00.000Z |
如果字段名称使用多次,GROK
将创建一个多值列
FROM addresses | KEEP city.name, zip_code | GROK zip_code """%{WORD:zip_parts} %{WORD:zip_parts}"""
city.name:keyword | zip_code:keyword | zip_parts:keyword |
---|---|---|
Amsterdam |
1016 ED |
["1016", "ED"] |
San Francisco |
CA 94108 |
["CA", "94108"] |
Tokyo |
100-7014 |
null |
限制
编辑GROK
命令不支持配置自定义模式或多个模式。GROK
命令不受Grok 看门狗设置的约束。