Skip to content

Commit

Permalink
Add regex function to promtail template stage. (#2386)
Browse files Browse the repository at this point in the history
Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com>
  • Loading branch information
cyriltovena authored Jul 22, 2020
1 parent ec13681 commit 604ad16
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 1 deletion.
80 changes: 80 additions & 0 deletions docs/sources/clients/promtail/stages/template.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,83 @@ The template here uses Go's [`string.Replace`
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
`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=" }}'
```
9 changes: 9 additions & 0 deletions pkg/logentry/stages/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"errors"
"reflect"
"regexp"
"strings"
"text/template"
"time"
Expand Down Expand Up @@ -31,6 +32,14 @@ var (
"TrimPrefix": strings.TrimPrefix,
"TrimSuffix": strings.TrimSuffix,
"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)
},
}
)

Expand Down
62 changes: 61 additions & 1 deletion pkg/logentry/stages/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pipeline_stages:
- json:
expressions:
app: app
level: level
level: level
- template:
source: app
template: '{{ .Value | ToUpper }} doki'
Expand Down Expand Up @@ -232,6 +232,18 @@ func TestTemplateStage_Process(t *testing.T) {
"testval": "value",
},
},
"ToLowerParams": {
TemplateConfig{
Source: "testval",
Template: "{{ ToLower .Value }}",
},
map[string]interface{}{
"testval": "Value",
},
map[string]interface{}{
"testval": "value",
},
},
"ToLowerEmptyValue": {
TemplateConfig{
Source: "testval",
Expand All @@ -252,6 +264,54 @@ func TestTemplateStage_Process(t *testing.T) {
"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": {
TemplateConfig{
Source: "testval",
Expand Down

0 comments on commit 604ad16

Please sign in to comment.