替换
注意
Promtail 已弃用,并在 2026 年 2 月 28 日前处于长期支持 (LTS) 阶段。Promtail 将于 2026 年 3 月 2 日终止服务 (EOL)。您可以在此处找到迁移资源。
replace
阶段是一个解析阶段,它使用正则表达式解析日志行并替换日志行。正则表达式中的命名捕获组支持将数据添加到提取映射中。
Schema
replace:
# The RE2 regular expression. Each named capture group will be added to extracted.
# Each capture group and named capture group will be replaced with the value given in `replace`
expression: <string>
# Name from extracted data to parse. If empty, uses the log message.
# The replaced value will be assigned back to soure key
[source: <string>]
# Value to which the captured group will be replaced. The captured group or the named captured group will be
# replaced with this value and the log line will be replaced with new replaced values. An empty value will
# remove the captured group from the log line.
[replace: <string>]
expression
必须是 Go RE2 正则表达式字符串。每个命名捕获组 (?P<name>re)
将被设置到 extracted
映射中。捕获组的名称将用作提取映射中的键。
由于 YAML 处理双引号字符串中的反斜杠的方式,请注意在使用双引号时,正则表达式中的所有反斜杠都必须进行转义。例如,以下所有示例均有效
expression: \w*
expression: '\w*'
expression: "\\w*"
但以下示例无效
expression: \\w*
(仅在使用双引号时转义反斜杠)expression: '\\w*'
(仅在使用双引号时转义反斜杠)expression: "\w*"
(反斜杠必须转义)
示例
无 source
给定 pipeline
- replace:
expression: "password (\\S+)"
replace: "****"
以及日志行
2019-01-01T01:00:00.000000001Z stderr P i'm a log message who has sensitive information with password xyz!
日志行变为
2019-01-01T01:00:00.000000001Z stderr P i'm a log message who has sensitive information with password ****!
有 source
给定 pipeline
- json:
expressions:
level:
msg:
- replace:
expression: "\\S+ - \"POST (\\S+) .*"
source: "msg"
replace: "/loki/api/v1/push"
以及日志行
{"time":"2019-01-01T01:00:00.000000001Z", "level": "info", "msg":"11.11.11.11 - "POST /loki/api/push/ HTTP/1.1" 200 932 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 GTB6"}
第一个阶段会将以下键值对添加到 extracted
映射中
time
:2019-01-01T01:00:00.000000001Z
level
:info
msg
:11.11.11.11 - "POST /loki/api/push/ HTTP/1.1" 200 932 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 GTB6"
replace 阶段会解析 extracted 映射中 msg
的值并替换 msg
的值。extracted 中的 msg
现在会变为
msg
:11.11.11.11 - "POST /loki/api/v1/push/ HTTP/1.1" 200 932 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 GTB6"
replace 值采用模板格式
给定 pipeline
- replace:
expression: "^(\\S+) (\\S+) (\\S+) \\[([\\w:/]+\\s[+\\-]\\d{4})\\] \"(\\S+)\\s?(\\S+)?\\s?(\\S+)?\" (\\d{3}|-) (\\d+|-)\\s?\"?([^\"]*)\"?\\s?\"?([^\"]*)?\"?$"
replace: '{{ if eq .Value "200" }}{{ Replace .Value "200" "HttpStatusOk" -1 }}{{ else }}{{ .Value | ToUpper }}{{ end }}'
以及日志行
11.11.11.11 - frank [25/Jan/2000:14:00:01 -0500] "GET /1986.js HTTP/1.1" 200 932 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 GTB6"
replace 阶段会解析日志行,如果捕获组的值为 200
,则将其替换为 HttpStatusOk
。
日志行会变为
11.11.11.11 - frank [25/Jan/2000:14:00:01 -0500] "GET /1986.js HTTP/1.1" HttpStatusOk 932 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 GTB6"
replace 值采用模板格式,并使用哈希来混淆数据
为了混淆敏感数据,您可以将 replace
阶段与 Hash
模板方法结合使用。
- replace:
# SSN
expression: '([0-9]{3}-[0-9]{2}-[0-9]{4})'
replace: '*SSN*{{ .Value | Hash "salt" }}*'
- replace:
# IP4
expression: '(\d{1,3}[.]\d{1,3}[.]\d{1,3}[.]\d{1,3})'
replace: '*IP4*{{ .Value | Hash "salt" }}*'
- replace:
# email
expression: '([\w\.=-]+@[\w\.-]+\.[\w]{2,64})'
replace: '*email*{{ .Value | Hash "salt" }}*'
- replace:
# creditcard
expression: '((?:\d[ -]*?){13,16})'
replace: '*creditcard*{{ .Value | Hash "salt" }}*'
带命名捕获组的 replace
给定 pipeline
- replace:
expression: "^(?P<ip>\\S+) (?P<identd>\\S+) (?P<user>\\S+) \\[(?P<timestamp>[\\w:/]+\\s[+\\-]\\d{4})\\] \"(?P<action>\\S+)\\s?(?P<path>\\S+)?\\s?(?P<protocol>\\S+)?\" (?P<status>\\d{3}|-) (?P<size>\\d+|-)\\s?\"?(?P<referer>[^\"]*)\"?\\s?\"?(?P<useragent>[^\"]*)?\"?$"
replace: '{{ .Value | ToUpper }}'
以及日志行
11.11.11.11 - frank [25/Jan/2000:14:00:01 -0500] "GET /1986.js HTTP/1.1" 200 932 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 GTB6"
replace 阶段会解析日志行,并将所有命名捕获组的值替换为大写。命名的捕获组将被提取为
ip
:11.11.11.11
identd
:-
user
:FRANK
timestamp
:25/JAN/2000:14:00:01 -0500
action
:GET
path
:/1986.JS
protocol
:HTTP/1.1
status
:200
size
:932
referer
:-
useragent
:MOZILLA/5.0 (WINDOWS; U; WINDOWS NT 5.1; DE; RV:1.9.1.7) GECKO/20091221 FIREFOX/3.5.7 GTB6"
日志行会变为
11.11.11.11 - FRANK [25/JAN/2000:14:00:01 -0500] "GET /1986.JS HTTP/1.1" 200 932 "-" "MOZILLA/5.0 (WINDOWS; U; WINDOWS NT 5.1; DE; RV:1.9.1.7) GECKO/20091221 FIREFOX/3.5.7 GTB6"
带命名捕获组和普通捕获组的 replace
给定 pipeline
- replace:
expression: "^(?P<ip>\\S+) (?P<identd>\\S+) (\\S+) \\[(?P<timestamp>[\\w:/]+\\s[+\\-]\\d{4})\\] \"(?P<action>\\S+)\\s?(?P<path>\\S+)?\\s?(?P<protocol>\\S+)?\" (?P<status>\\d{3}|-) (?P<size>\\d+|-)\\s?\"?(?P<referer>[^\"]*)\"?\\s?\"?(?P<useragent>[^\"]*)?\"?$"
replace: '{{ .Value | ToUpper }}'
以及日志行
11.11.11.11 - frank [25/Jan/2000:14:00:01 -0500] "GET /1986.js HTTP/1.1" 200 932 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 GTB6"
replace 阶段会解析日志行,并将所有命名捕获组的值替换为大写。命名的捕获组将被提取。注意这里 user
没有被提取,因为它只是 (\\S+)
而不是 (?P<user>\\S+)
这样的命名捕获组
ip
:11.11.11.11
identd
:-
timestamp
:25/JAN/2000:14:00:01 -0500
action
:GET
path
:/1986.JS
protocol
:HTTP/1.1
status
:200
size
:932
referer
:-
useragent
:MOZILLA/5.0 (WINDOWS; U; WINDOWS NT 5.1; DE; RV:1.9.1.7) GECKO/20091221 FIREFOX/3.5.7 GTB6"
日志行会变为
11.11.11.11 - FRANK [25/JAN/2000:14:00:01 -0500] "GET /1986.JS HTTP/1.1" 200 932 "-" "MOZILLA/5.0 (WINDOWS; U; WINDOWS NT 5.1; DE; RV:1.9.1.7) GECKO/20091221 FIREFOX/3.5.7 GTB6"
空 replace
给定 pipeline
- replace:
expression: "11.11.11.11 - (\\S+\\s)"
replace: ""
以及日志行
11.11.11.11 - frank [25/Jan/2000:14:00:01 -0500] "GET /1986.js HTTP/1.1" 200 932 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 GTB6"
日志行变为
11.11.11.11 - [25/Jan/2000:14:00:01 -0500] "GET /1986.js HTTP/1.1" 200 932 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 GTB6"