用于匹配重复 k/v 对的正则表达式加上 logstash 中的尾随字符串
Regex for matching repeating k/v pairs plus trailing string in logstash
我需要编写一些让我头疼的正则表达式。这里的目标是在 logstash 过滤器中解析以下类型的日志行:
severity=I time=2017-02-23T10:04:31Z [SKYLIGHT] [0.5.1] Unable to start
severity=I time=2017-02-23T10:04:31Z adapter=redis adapter_host=1.1.1.1 Cache read: /model/reference/6235290d29a17a935f4d3d72d2e0a903750dd54b
severity=I time=2017-02-23T10:04:31Z remote_ip=1.1.1.1 uuid=daa8090d method=GET path=/somepath.json format=json controller=app action=index status=200 duration=30.47 view=10.04
severity=D time=2017-02-23T10:04:31Z remote_ip=1.1.1.1 uuid=daa8090d SOLR Request (18.3ms) [path=/admin/luke parameters={numTerms: 0}]
本质上,输出格式是一组任意的 k=v 对,后跟偶尔的 "raw message"。直接使用 logstash k/v 过滤器会产生不良行为,因为尾随 "message" 可以在其中嵌套 k=v 格式 - 例如上面最后一行中的 path=/admin/luke 。我的工作计划是将日志分为两部分,k/v 对作为字符串和尾随消息,此时 k/v 字符串可以发送到普通的 logstash kv 过滤器中。因此,例如,最后的日志行将产生两组:
severity=D time=2017-02-23T10:04:31Z remote_ip=1.1.1.1 uuid=daa8090d
SOLR Request (18.3ms) [path=/admin/luke parameters={numTerms: 0}]
日志文档的最终目标是:
[
{
"severity": "I",
"time": "2017-02-23T10:04:31Z",
"message": "[SKYLIGHT] [0.5.1] Unable to start"
},
{
"severity": "I",
"time": "2017-02-23T10:04:31Z"
"adapter": "redis",
"adapter_host": "1.1.1.1",
"message": "Cache read: /model/reference/6235290d29a17a935f4d3d72d2e0a903750dd54b"
},
{
"severity": "I",
"time": "2017-02-23T10:04:31Z",
"message": "[SKYLIGHT] [0.5.1] Unable to start"
},
{
"severity": "I",
"time": "2017-02-23T10:04:31Z",
"remote_ip": "1.1.1.1",
"uuid": "daa8090d",
"method": "GET",
"path": "/somepath.json",
"format": "json",
"controller": "app",
"action": "index",
"status": "200",
"duration": "30.47",
"view": "10.04"
},
{
"severity": "D",
"time": "2017-02-23T10:04:31Z",
"remote_ip": "1.1.1.1",
"uuid": "daa8090d",
"message": "SOLR Request (18.3ms) [path=/admin/luke parameters={numTerms: 0}]"
}
]
谢谢!
对每一行使用以下正则表达式:
(?:([^ =]+)=([^ =]+) ?)|(.+)
解释:
(?:
- "External",非捕获组 (xxxx=yyyy
)。
([^ =]+)
- 第一个捕获组 (xxxx
)。
=
- 等号(在 xxxx
和 yyyy
之间)。
([^ =]+)
- 第二个捕获组 (yyyy
)。
?
- A space(可能发生)。
)
- "external" 组结束。
|
- 变体之间的分隔符。
(.+)
- 第二个变体 - 第三个捕获组,任何非空字符序列。
请注意,正则表达式处理器最初会尝试第一个变体(在 |
之前),
捕获 xxxx=yyyy
对。
然后,如果第一个变体失败(在所有 xxxx=yyyy
对之后),
尝试第二个变体,捕获消息(如果有)。
我使用在线验证器 (regex101.com) 为每个输入行尝试了此正则表达式。
例如最后一行
(severity=D time=2017-02-23T10:04:31Z remote_ip=1.1.1.1 uuid=daa8090d SOLR Request (18.3ms) [path=/admin/luke parameters={numTerms: 0}
)
我得到以下结果:
Match 1
Full match 0-11 `severity=D `
Group 1. 0-8 `severity`
Group 2. 9-10 `D`
Match 2
Full match 11-37 `time=2017-02-23T10:04:31Z `
Group 1. 11-15 `time`
Group 2. 16-36 `2017-02-23T10:04:31Z`
Match 3
Full match 37-55 `remote_ip=1.1.1.1 `
Group 1. 37-46 `remote_ip`
Group 2. 47-54 `1.1.1.1`
Match 4
Full match 55-69 `uuid=daa8090d `
Group 1. 55-59 `uuid`
Group 2. 60-68 `daa8090d`
Match 5
Full match 69-133 `SOLR Request (18.3ms) [path=/admin/luke parameters={numTerms: 0}`
Group 3. 69-133 `SOLR Request (18.3ms) [path=/admin/luke parameters={numTerms: 0}`
请注意,在第 1 到 4 号匹配的情况下,找到了第 1 组和第 2 组。
但在最后一场比赛中,找到了第 3 组。
因此,在处理每场比赛时,您必须检查:
如果第1组不为空,则第2组也不为空
它们包含 k
和 v
.
否则,第3组保留消息内容。
我需要编写一些让我头疼的正则表达式。这里的目标是在 logstash 过滤器中解析以下类型的日志行:
severity=I time=2017-02-23T10:04:31Z [SKYLIGHT] [0.5.1] Unable to start
severity=I time=2017-02-23T10:04:31Z adapter=redis adapter_host=1.1.1.1 Cache read: /model/reference/6235290d29a17a935f4d3d72d2e0a903750dd54b
severity=I time=2017-02-23T10:04:31Z remote_ip=1.1.1.1 uuid=daa8090d method=GET path=/somepath.json format=json controller=app action=index status=200 duration=30.47 view=10.04
severity=D time=2017-02-23T10:04:31Z remote_ip=1.1.1.1 uuid=daa8090d SOLR Request (18.3ms) [path=/admin/luke parameters={numTerms: 0}]
本质上,输出格式是一组任意的 k=v 对,后跟偶尔的 "raw message"。直接使用 logstash k/v 过滤器会产生不良行为,因为尾随 "message" 可以在其中嵌套 k=v 格式 - 例如上面最后一行中的 path=/admin/luke 。我的工作计划是将日志分为两部分,k/v 对作为字符串和尾随消息,此时 k/v 字符串可以发送到普通的 logstash kv 过滤器中。因此,例如,最后的日志行将产生两组:
severity=D time=2017-02-23T10:04:31Z remote_ip=1.1.1.1 uuid=daa8090d
SOLR Request (18.3ms) [path=/admin/luke parameters={numTerms: 0}]
日志文档的最终目标是:
[
{
"severity": "I",
"time": "2017-02-23T10:04:31Z",
"message": "[SKYLIGHT] [0.5.1] Unable to start"
},
{
"severity": "I",
"time": "2017-02-23T10:04:31Z"
"adapter": "redis",
"adapter_host": "1.1.1.1",
"message": "Cache read: /model/reference/6235290d29a17a935f4d3d72d2e0a903750dd54b"
},
{
"severity": "I",
"time": "2017-02-23T10:04:31Z",
"message": "[SKYLIGHT] [0.5.1] Unable to start"
},
{
"severity": "I",
"time": "2017-02-23T10:04:31Z",
"remote_ip": "1.1.1.1",
"uuid": "daa8090d",
"method": "GET",
"path": "/somepath.json",
"format": "json",
"controller": "app",
"action": "index",
"status": "200",
"duration": "30.47",
"view": "10.04"
},
{
"severity": "D",
"time": "2017-02-23T10:04:31Z",
"remote_ip": "1.1.1.1",
"uuid": "daa8090d",
"message": "SOLR Request (18.3ms) [path=/admin/luke parameters={numTerms: 0}]"
}
]
谢谢!
对每一行使用以下正则表达式:
(?:([^ =]+)=([^ =]+) ?)|(.+)
解释:
(?:
- "External",非捕获组 (xxxx=yyyy
)。([^ =]+)
- 第一个捕获组 (xxxx
)。=
- 等号(在xxxx
和yyyy
之间)。([^ =]+)
- 第二个捕获组 (yyyy
)。?
- A space(可能发生)。)
- "external" 组结束。|
- 变体之间的分隔符。(.+)
- 第二个变体 - 第三个捕获组,任何非空字符序列。
请注意,正则表达式处理器最初会尝试第一个变体(在 |
之前),
捕获 xxxx=yyyy
对。
然后,如果第一个变体失败(在所有 xxxx=yyyy
对之后),
尝试第二个变体,捕获消息(如果有)。
我使用在线验证器 (regex101.com) 为每个输入行尝试了此正则表达式。
例如最后一行
(severity=D time=2017-02-23T10:04:31Z remote_ip=1.1.1.1 uuid=daa8090d SOLR Request (18.3ms) [path=/admin/luke parameters={numTerms: 0}
)
我得到以下结果:
Match 1
Full match 0-11 `severity=D `
Group 1. 0-8 `severity`
Group 2. 9-10 `D`
Match 2
Full match 11-37 `time=2017-02-23T10:04:31Z `
Group 1. 11-15 `time`
Group 2. 16-36 `2017-02-23T10:04:31Z`
Match 3
Full match 37-55 `remote_ip=1.1.1.1 `
Group 1. 37-46 `remote_ip`
Group 2. 47-54 `1.1.1.1`
Match 4
Full match 55-69 `uuid=daa8090d `
Group 1. 55-59 `uuid`
Group 2. 60-68 `daa8090d`
Match 5
Full match 69-133 `SOLR Request (18.3ms) [path=/admin/luke parameters={numTerms: 0}`
Group 3. 69-133 `SOLR Request (18.3ms) [path=/admin/luke parameters={numTerms: 0}`
请注意,在第 1 到 4 号匹配的情况下,找到了第 1 组和第 2 组。
但在最后一场比赛中,找到了第 3 组。
因此,在处理每场比赛时,您必须检查:
如果第1组不为空,则第2组也不为空 它们包含
k
和v
.否则,第3组保留消息内容。