本文档介绍了如何在 OpenSearch 摄取管道中使用 dissect
处理器。如果您的用例涉及大型或复杂数据集,请考虑使用在 OpenSearch 集群上运行的 Data Prepper dissect
处理器。
解剖
dissect
处理器根据 dissect 模式从文档文本字段中提取值,并将其映射到单独的字段。该处理器非常适合从具有已知结构的日志消息中提取字段。与 grok
处理器不同,dissect
不使用正则表达式,并且语法更简单。
语法
以下是 dissect
处理器的语法
{
"dissect": {
"field": "source_field",
"pattern": "%{dissect_pattern}"
}
}
配置参数
下表列出了 dissect
处理器的必需和可选参数。
参数 | 必需/可选 | 描述 |
---|---|---|
field | 必需 | 包含要分解数据的字段名称。 |
模式 | 必需 | 用于从指定字段中提取数据的 dissect 模式。 |
append_separator | 可选 | 分隔追加字段的分隔符或字符串。默认值为 "" (空字符串)。 |
description | 可选 | 处理器的简要描述。 |
if | 可选 | 运行处理器的条件。 |
ignore_failure | 可选 | 指定处理器即使遇到错误是否继续执行。如果设置为 true ,则忽略处理器故障。默认值为 false 。 |
ignore_missing | 可选 | 指定处理器是否应忽略不包含指定字段的文档。如果设置为 true ,则如果字段不存在或为 null ,处理器不会修改文档。默认值为 false 。 |
on_failure | 可选 | 处理器失败时要运行的处理器列表。 |
tag | 可选 | 处理器的标识符标签。有助于调试以区分相同类型的处理器。 |
使用处理器
按照以下步骤在管道中使用处理器。
步骤 1:创建管道
以下查询创建了一个名为 dissect-test
的管道,该管道使用 dissect
处理器来解析日志行
PUT /_ingest/pipeline/dissect-test
{
"description": "Pipeline that dissects web server logs",
"processors": [
{
"dissect": {
"field": "message",
"pattern": "%{client_ip} - - [%{timestamp}] \"%{http_method} %{url} %{http_version}\" %{response_code} %{response_size}"
}
}
]
}
步骤 2(可选):测试管道
建议在摄取文档之前测试您的管道。
要测试管道,请运行以下查询
POST _ingest/pipeline/dissect-test/_simulate
{
"docs": [
{
"_index": "testindex1",
"_id": "1",
"_source": {
"message": "192.168.1.10 - - [03/Nov/2023:15:20:45 +0000] \"POST /login HTTP/1.1\" 200 3456"
}
}
]
}
响应
以下示例响应确认管道按预期工作
{
"docs": [
{
"doc": {
"_index": "testindex1",
"_id": "1",
"_source": {
"response_code": "200",
"http_method": "POST",
"http_version": "HTTP/1.1",
"client_ip": "192.168.1.10",
"message": """192.168.1.10 - - [03/Nov/2023:15:20:45 +0000] "POST /login HTTP/1.1" 200 3456""",
"url": "/login",
"response_size": "3456",
"timestamp": "03/Nov/2023:15:20:45 +0000"
},
"_ingest": {
"timestamp": "2023-11-03T22:28:32.830244044Z"
}
}
}
]
}
步骤 3:摄取文档
以下查询将文档摄取到名为 testindex1
的索引中
PUT testindex1/_doc/1?pipeline=dissect-test
{
"message": "192.168.1.10 - - [03/Nov/2023:15:20:45 +0000] \"POST /login HTTP/1.1\" 200 3456"
}
步骤 4(可选):检索文档
要检索文档,请运行以下查询
GET testindex1/_doc/1
Dissect 模式
Dissect 模式是一种告诉 dissect
处理器如何将字符串解析为结构化格式的方法。该模式由您希望丢弃的字符串部分定义。例如,%{client_ip} - - [%{timestamp}]
dissect 模式会将字符串 "192.168.1.10 - - [03/Nov/2023:15:20:45 +0000] \"POST /login HTTP/1.1\" 200 3456"
解析为以下字段
client_ip: "192.168.1.1"
@timestamp: "03/Nov/2023:15:20:45 +0000"
Dissect 模式通过将字符串与一组规则进行匹配来工作。例如,第一条规则丢弃一个空格。dissect
处理器将找到此空格,然后将 client_ip
的值分配给该空格之前的所有字符。下一条规则匹配 [
和 ]
字符,然后将 @timestamp
的值分配给其间的所有内容。
构建成功的 dissect 模式
在构建 dissect 模式时,重要的是要注意要丢弃的字符串部分。如果丢弃了过多字符串,则 dissect
处理器可能无法成功解析剩余数据。相反,如果丢弃的字符串不够,处理器可能会创建不必要的字段。
如果模式中定义的任何 %{keyname}
没有值,则会抛出异常。您可以通过在 on_failure
参数中提供错误处理步骤来处理此异常。
空和命名跳过键
空键 %{}
或命名跳过键可用于匹配值,但将该值从最终文档中排除。如果您想解析字符串但不需要存储其所有部分,这会很有用。
将匹配的值转换为非字符串数据类型
默认情况下,所有匹配的值都表示为字符串数据类型。如果需要将值转换为不同的数据类型,可以使用convert
处理器。
键修饰符
dissect
处理器支持可更改默认处理器行为的键修饰符。这些修饰符始终放置在 %{keyname}
的左侧或右侧,并且始终封装在 %{}
中。例如,%{+keyname->}
修饰符包含追加和右填充修饰符。键修饰符对于将多个字段组合成单行输出、创建格式化的数据项列表或聚合来自多个源的值非常有用。
下表列出了 dissect
处理器的主要修饰符。
修饰符 | 名称 | 位置 | 示例 | 描述 |
---|---|---|---|---|
-> | 跳过右填充 | (最)右 | %{keyname->} | 告诉 dissect 处理器跳过右侧任何重复的字符。例如,%{timestamp->} 可用于告诉处理器跳过 timestamp 后面的任何填充字符,例如两个连续的空格或任何变化的字符填充。 |
+ | 追加 | 左 | %{keyname} %{+keyname} | 追加两个或更多字段。 |
+ 与 /n | 按顺序追加 | 左和右 | %{+keyname}/2 %{+keyname/1} | 按指定顺序追加两个或更多字段。 |
? | 命名跳过键 | 左 | %{?skipme} | 跳过输出中匹配的值。与 %{} 行为相同。 |
* 和 & | 引用键 | 左 | %{*r1} %{&r1} | 将输出键设置为 * 的值,将输出值设置为 & 的值。 |
以下各节提供了每个键修饰符的详细描述以及使用示例。
右填充修饰符 (->
)
dissect 算法是精确的,要求模式中的每个字符都与源字符串完全匹配。例如,模式 %{hellokey} %{worldkey}
(一个空格)将匹配字符串 “Hello world”(一个空格),但不会匹配字符串 “Hello world”(两个空格),因为模式只有一个空格,而源字符串有两个。
右填充修饰符可用于解决此问题。当添加到模式 %{helloworldkey->} %{worldkey}
时,右填充修饰符将匹配 Hello world
(1 个空格)、Hello world
(2 个空格),甚至 Hello world
(10 个空格)。
右填充修饰符用于允许 %{keyname->}
后面的字符重复。右填充修饰符可以应用于任何键以及任何其他修饰符。它应始终是最右侧的修饰符,例如 %{+keyname/1->}
或 %{}
。
使用示例
以下是使用右填充修饰符的示例
%{city->}, %{state} %{zip}
在此模式中,右填充修饰符 ->
应用于 %{city}
键。两个地址都包含相同的信息,但第二个条目在 city
字段中有一个额外的单词 City
。右填充修饰符允许该模式匹配这两个地址条目,即使它们的格式略有不同
New York, NY 10017
New York City, NY 10017
以下示例管道使用带空键 %{->}
的右填充修饰符
PUT /_ingest/pipeline/dissect-test
{
"description": "Pipeline that dissects web server logs",
"processors": [
{
"dissect": {
"field": "message",
"pattern": "[%{client_ip}]%{->}[%{timestamp}]"
}
}
]
}
您可以使用以下示例管道测试管道
POST _ingest/pipeline/dissect-test/_simulate
{
"docs": [
{
"_index": "testindex1",
"_id": "1",
"_source": {
"message": "[192.168.1.10] [03/Nov/2023:15:20:45 +0000]"
}
}
]
}
您的响应应类似于以下内容
{
"docs": [
{
"doc": {
"_index": "testindex1",
"_id": "1",
"_source": {
"client_ip": "192.168.1.10",
"message": "[192.168.1.10] [03/Nov/2023:15:20:45 +0000]",
"timestamp": "03/Nov/2023:15:20:45 +0000"
},
"_ingest": {
"timestamp": "2024-01-22T22:55:42.090569297Z"
}
}
}
]
}
追加修饰符 (+
)
追加修饰符将两个或更多值组合成单个输出值。这些值从左到右追加。您还可以指定一个可选的分隔符插入到值之间。
使用示例
以下是带追加修饰符的示例管道
PUT /_ingest/pipeline/dissect-test
{
"description": "Pipeline that dissects web server logs",
"processors": [
{
"dissect": {
"field": "message",
"pattern": "%{+address}, %{+address} %{+address}",
"append_separator": "|"
}
}
]
}
您可以使用以下示例管道测试管道
POST _ingest/pipeline/dissect-test/_simulate
{
"docs": [
{
"_index": "testindex1",
"_id": "1",
"_source": {
"message": "New York, NY 10017"
}
}
]
}
子字符串被追加到 address
字段,如以下响应所示
{
"docs": [
{
"doc": {
"_index": "testindex1",
"_id": "1",
"_source": {
"address": "New York|NY|10017",
"message": "New York, NY 10017"
},
"_ingest": {
"timestamp": "2024-01-22T22:30:54.516284637Z"
}
}
}
]
}
按顺序追加修饰符 (+
和 /n
)
按顺序追加修饰符根据 /
后指定的顺序将两个或更多键的值组合成单个输出值。您可以灵活地自定义分隔追加值的分隔符。追加修饰符对于将多个字段编译成单个格式化输出行、构建结构化数据项列表以及整合来自各种源的值非常有用。
使用示例
以下示例管道使用按顺序追加修饰符来反转前面管道中定义的模式顺序。此管道指定一个分隔符插入到追加字段之间。如果您不指定分隔符,所有值将不带分隔符地追加。
PUT /_ingest/pipeline/dissect-test
{
"description": "Pipeline that dissects web server logs",
"processors": [
{
"dissect": {
"field": "message",
"pattern": "%{+address/3}, %{+address/2} %{+address/1}",
"append_separator": "|"
}
}
]
}
您可以使用以下示例管道测试管道
POST _ingest/pipeline/dissect-test/_simulate
{
"docs": [
{
"_index": "testindex1",
"_id": "1",
"_source": {
"message": "New York, NY 10017"
}
}
]
}
子字符串以相反的顺序追加到 address
字段,如以下响应所示
{
"docs": [
{
"doc": {
"_index": "testindex1",
"_id": "1",
"_source": {
"address": "10017|NY|New York",
"message": "New York, NY 10017"
},
"_ingest": {
"timestamp": "2024-01-22T22:38:24.305974178Z"
}
}
}
]
}
命名跳过键修饰符
命名跳过键修饰符通过在模式中使用空键 {}
或 ?
修饰符将特定匹配从最终输出中排除。例如,以下模式是等效的:%{firstName} %{lastName} %{?ignore}
和 %{firstName} %{lastName} %{}
。命名跳过键修饰符对于从输出中排除不相关或不必要的字段很有用。
使用示例
以下模式使用命名跳过键从输出中排除一个字段(在本例中为 ignore
)。您可以为该空键分配一个描述性名称,例如 %{?ignore}
,以明确相应的值应从最终输出中排除
PUT /_ingest/pipeline/dissect-test
{
"description": "Pipeline that dissects web server logs",
"processors": [
{
"dissect": {
"field": "message",
"pattern": "%{firstName} %{lastName} %{?ignore}"
}
}
]
}
您可以使用以下示例管道测试管道
POST _ingest/pipeline/dissect-test/_simulate
{
"docs": [
{
"_index": "testindex1",
"_id": "1",
"_source": {
"message": "John Doe M.D."
}
}
]
}
您的响应应类似于以下内容
{
"docs": [
{
"doc": {
"_index": "testindex1",
"_id": "1",
"_source": {
"firstName": "John",
"lastName": "Doe",
"message": "John Doe M.D."
},
"_ingest": {
"timestamp": "2024-01-22T22:41:58.161475555Z"
}
}
}
]
}
引用键 (*
和 &
)
引用键使用解析的值作为结构化内容的键值对。这在处理部分以键值对形式记录数据的系统时会很有用。通过使用引用键,可以保留键值关系并维护提取信息的完整性。
使用示例
以下模式使用引用键将数据提取为结构化格式。在此示例中,client_ip
和两个键值对被提取为后续值
PUT /_ingest/pipeline/dissect-test
{
"description": "Pipeline that dissects web server logs",
"processors": [
{
"dissect": {
"field": "message",
"pattern": "%{client_ip} %{*a}:%{&a} %{*b}:%{&b}"
}
}
]
}
您可以使用以下示例管道测试管道
POST _ingest/pipeline/dissect-test/_simulate
{
"docs": [
{
"_index": "testindex1",
"_id": "1",
"_source": {
"message": "192.168.1.10 response_code:200 response_size:3456"
}
}
]
}
这两个键值对被提取到字段中,如以下响应所示
{
"docs": [
{
"doc": {
"_index": "testindex1",
"_id": "1",
"_source": {
"client_ip": "192.168.1.10",
"response_code": "200",
"message": "192.168.1.10 response_code:200 response_size:3456",
"response_size": "3456"
},
"_ingest": {
"timestamp": "2024-01-22T22:48:51.475535635Z"
}
}
}
]
}