Add regex function to promtail template stage. (#2386)

Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com>
pull/2391/head
Cyril Tovena 5 years ago committed by GitHub
parent ec1368156a
commit 604ad1632e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 80
      docs/sources/clients/promtail/stages/template.md
  2. 9
      pkg/logentry/stages/template.go
  3. 62
      pkg/logentry/stages/template_test.go

@ -98,3 +98,83 @@ The template here uses Go's [`string.Replace`
function](https://golang.org/pkg/strings/#Replace). When the template executes, function](https://golang.org/pkg/strings/#Replace). When the template executes,
the entire contents of the `app` key from the extracted map will have at most the entire contents of the `app` key from the extracted map will have at most
`1` instance of `loki` changed to `blokey`. `1` instance of `loki` changed to `blokey`.
## Supported Functions
### ToLower & ToUpper
ToLower and ToUpper convert the entire string respectively to lowercase and uppercase.
Examples:
```yaml
- template:
source: out
template: '{{ ToLower .app }}'
```
```yaml
- template:
source: out
template: '{{ .app | ToUpper }}'
```
### Replace
`Replace` returns a copy of the string s with the first n non-overlapping instances of old replaced by new. If old is empty, it matches at the beginning of the string and after each UTF-8 sequence, yielding up to k+1 replacements for a k-rune string. If n < 0, there is no limit on the number of replacements.
The example below will replace the first two words `loki` by `Loki`.
```yaml
- template:
source: output
template: '{{ Replace .Value "loki" "Loki" 2 }}'
```
### Trim
`Trim` returns a slice of the string s with all leading and
trailing Unicode code points contained in cutset removed.
`TrimLeft` and `TrimRight` are the same as `Trim` except that it respectively trim only leading and trailing characters.
```yaml
- template:
source: output
template: '{{ Trim .Value ",. " }}'
```
`TrimSpace` TrimSpace returns a slice of the string s, with all leading
and trailing white space removed, as defined by Unicode.
```yaml
- template:
source: output
template: '{{ TrimSpace .Value }}'
```
`TrimPrefix` and `TrimSuffix` will trim respectively the prefix or suffix supplied.
```yaml
- template:
source: output
template: '{{ TrimPrefix .Value "--" }}'
```
### Regex
`regexReplaceAll` returns a copy of the input string, replacing matches of the Regexp with the replacement string replacement. Inside string replacement, $ signs are interpreted as in Expand, so for instance $1 represents the text of the first submatch
```yaml
- template:
source: output
template: '{{ regexReplaceAllLiteral "(a*)bc" .Value "{1}a" }}'
```
`regexReplaceAllLiteral` returns a copy of the input string, replacing matches of the Regexp with the replacement string replacement The replacement string is substituted directly, without using Expand.
```yaml
- template:
source: output
template: '{{ regexReplaceAllLiteral "(ts=)" .Value "timestamp=" }}'
```

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"errors" "errors"
"reflect" "reflect"
"regexp"
"strings" "strings"
"text/template" "text/template"
"time" "time"
@ -31,6 +32,14 @@ var (
"TrimPrefix": strings.TrimPrefix, "TrimPrefix": strings.TrimPrefix,
"TrimSuffix": strings.TrimSuffix, "TrimSuffix": strings.TrimSuffix,
"TrimSpace": strings.TrimSpace, "TrimSpace": strings.TrimSpace,
"regexReplaceAll": func(regex string, s string, repl string) string {
r := regexp.MustCompile(regex)
return r.ReplaceAllString(s, repl)
},
"regexReplaceAllLiteral": func(regex string, s string, repl string) string {
r := regexp.MustCompile(regex)
return r.ReplaceAllLiteralString(s, repl)
},
} }
) )

@ -19,7 +19,7 @@ pipeline_stages:
- json: - json:
expressions: expressions:
app: app app: app
level: level level: level
- template: - template:
source: app source: app
template: '{{ .Value | ToUpper }} doki' template: '{{ .Value | ToUpper }} doki'
@ -232,6 +232,18 @@ func TestTemplateStage_Process(t *testing.T) {
"testval": "value", "testval": "value",
}, },
}, },
"ToLowerParams": {
TemplateConfig{
Source: "testval",
Template: "{{ ToLower .Value }}",
},
map[string]interface{}{
"testval": "Value",
},
map[string]interface{}{
"testval": "value",
},
},
"ToLowerEmptyValue": { "ToLowerEmptyValue": {
TemplateConfig{ TemplateConfig{
Source: "testval", Source: "testval",
@ -252,6 +264,54 @@ func TestTemplateStage_Process(t *testing.T) {
"testval": "some_silly_value_with_lots_of_spaces", "testval": "some_silly_value_with_lots_of_spaces",
}, },
}, },
"regexReplaceAll": {
TemplateConfig{
Source: "testval",
Template: `{{ regexReplaceAll "(Silly)" .Value "${1}foo" }}`,
},
map[string]interface{}{
"testval": "Some Silly Value With Lots Of Spaces",
},
map[string]interface{}{
"testval": "Some Sillyfoo Value With Lots Of Spaces",
},
},
"regexReplaceAllerr": {
TemplateConfig{
Source: "testval",
Template: `{{ regexReplaceAll "\\K" .Value "${1}foo" }}`,
},
map[string]interface{}{
"testval": "Some Silly Value With Lots Of Spaces",
},
map[string]interface{}{
"testval": "Some Silly Value With Lots Of Spaces",
},
},
"regexReplaceAllLiteral": {
TemplateConfig{
Source: "testval",
Template: `{{ regexReplaceAll "( |Of)" .Value "_" }}`,
},
map[string]interface{}{
"testval": "Some Silly Value With Lots Of Spaces",
},
map[string]interface{}{
"testval": "Some_Silly_Value_With_Lots___Spaces",
},
},
"regexReplaceAllLiteralerr": {
TemplateConfig{
Source: "testval",
Template: `{{ regexReplaceAll "\\K" .Value "err" }}`,
},
map[string]interface{}{
"testval": "Some Silly Value With Lots Of Spaces",
},
map[string]interface{}{
"testval": "Some Silly Value With Lots Of Spaces",
},
},
"Trim": { "Trim": {
TemplateConfig{ TemplateConfig{
Source: "testval", Source: "testval",

Loading…
Cancel
Save