Skip to content

Commit 02bb510

Browse files
authored
Add regex parser golden configs (#65)
1 parent 7439d24 commit 02bb510

File tree

9 files changed

+205
-0
lines changed

9 files changed

+205
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// Copyright The OpenTelemetry Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
package regex
15+
16+
import (
17+
"fmt"
18+
"io/ioutil"
19+
"path"
20+
"testing"
21+
22+
"github.com/open-telemetry/opentelemetry-log-collection/entry"
23+
"github.com/open-telemetry/opentelemetry-log-collection/operator/helper"
24+
"github.com/stretchr/testify/require"
25+
"gopkg.in/yaml.v2"
26+
)
27+
28+
type testCase struct {
29+
name string
30+
expectErr bool
31+
expect *RegexParserConfig
32+
}
33+
34+
func TestRegexParserGoldenConfig(t *testing.T) {
35+
cases := []testCase{
36+
{
37+
"default",
38+
false,
39+
defaultCfg(),
40+
},
41+
{
42+
"parse_from_simple",
43+
false,
44+
func() *RegexParserConfig {
45+
cfg := defaultCfg()
46+
cfg.ParseFrom = entry.NewRecordField("from")
47+
return cfg
48+
}(),
49+
},
50+
{
51+
"parse_to_simple",
52+
false,
53+
func() *RegexParserConfig {
54+
cfg := defaultCfg()
55+
cfg.ParseTo = entry.NewRecordField("log")
56+
return cfg
57+
}(),
58+
},
59+
{
60+
"on_error_drop",
61+
false,
62+
func() *RegexParserConfig {
63+
cfg := defaultCfg()
64+
cfg.OnError = "drop"
65+
return cfg
66+
}(),
67+
},
68+
{
69+
"timestamp",
70+
false,
71+
func() *RegexParserConfig {
72+
cfg := defaultCfg()
73+
parseField := entry.NewRecordField("timestamp_field")
74+
newTime := helper.TimeParser{
75+
LayoutType: "strptime",
76+
Layout: "%Y-%m-%d",
77+
ParseFrom: &parseField,
78+
}
79+
cfg.TimeParser = &newTime
80+
return cfg
81+
}(),
82+
},
83+
{
84+
"severity",
85+
false,
86+
func() *RegexParserConfig {
87+
cfg := defaultCfg()
88+
parseField := entry.NewRecordField("severity_field")
89+
severityField := helper.NewSeverityParserConfig()
90+
severityField.ParseFrom = &parseField
91+
mapping := map[interface{}]interface{}{
92+
"critical": "5xx",
93+
"error": "4xx",
94+
"info": "3xx",
95+
"debug": "2xx",
96+
}
97+
severityField.Mapping = mapping
98+
cfg.SeverityParserConfig = &severityField
99+
return cfg
100+
}(),
101+
},
102+
{
103+
"preserve_to",
104+
false,
105+
func() *RegexParserConfig {
106+
cfg := defaultCfg()
107+
preserve := entry.NewRecordField("aField")
108+
cfg.PreserveTo = &preserve
109+
return cfg
110+
}(),
111+
},
112+
{
113+
"regex",
114+
false,
115+
func() *RegexParserConfig {
116+
cfg := defaultCfg()
117+
cfg.Regex = "^Host=(?P<host>[^,]+), Type=(?P<type>.*)$"
118+
return cfg
119+
}(),
120+
},
121+
}
122+
123+
for _, tc := range cases {
124+
t.Run("yaml/"+tc.name, func(t *testing.T) {
125+
cfgFromYaml, yamlErr := configFromFileViaYaml(path.Join(".", "testdata", fmt.Sprintf("%s.yaml", tc.name)))
126+
if tc.expectErr {
127+
require.Error(t, yamlErr)
128+
} else {
129+
require.NoError(t, yamlErr)
130+
require.Equal(t, tc.expect, cfgFromYaml)
131+
}
132+
})
133+
t.Run("mapstructure/"+tc.name, func(t *testing.T) {
134+
cfgFromMapstructure := defaultCfg()
135+
mapErr := configFromFileViaMapstructure(
136+
path.Join(".", "testdata", fmt.Sprintf("%s.yaml", tc.name)),
137+
cfgFromMapstructure,
138+
)
139+
if tc.expectErr {
140+
require.Error(t, mapErr)
141+
} else {
142+
require.NoError(t, mapErr)
143+
require.Equal(t, tc.expect, cfgFromMapstructure)
144+
}
145+
})
146+
}
147+
}
148+
149+
func configFromFileViaYaml(file string) (*RegexParserConfig, error) {
150+
bytes, err := ioutil.ReadFile(file)
151+
if err != nil {
152+
return nil, fmt.Errorf("could not find config file: %s", err)
153+
}
154+
155+
config := defaultCfg()
156+
if err := yaml.Unmarshal(bytes, config); err != nil {
157+
return nil, fmt.Errorf("failed to read config file as yaml: %s", err)
158+
}
159+
160+
return config, nil
161+
}
162+
163+
func configFromFileViaMapstructure(file string, result *RegexParserConfig) error {
164+
bytes, err := ioutil.ReadFile(file)
165+
if err != nil {
166+
return fmt.Errorf("could not find config file: %s", err)
167+
}
168+
169+
raw := map[string]interface{}{}
170+
171+
if err := yaml.Unmarshal(bytes, raw); err != nil {
172+
return fmt.Errorf("failed to read data from yaml: %s", err)
173+
}
174+
175+
err = helper.UnmarshalMapstructure(raw, result)
176+
return err
177+
}
178+
179+
func defaultCfg() *RegexParserConfig {
180+
return NewRegexParserConfig("regex_parser")
181+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
type: regex_parser
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
type: regex_parser
2+
on_error: "drop"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
type: regex_parser
2+
parse_from: "$.from"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
type: regex_parser
2+
parse_to: "log"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
type: regex_parser
2+
preserve_to: "aField"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
type: regex_parser
2+
regex: '^Host=(?P<host>[^,]+), Type=(?P<type>.*)$'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
type: regex_parser
2+
severity:
3+
parse_from: severity_field
4+
mapping:
5+
critical: 5xx
6+
error: 4xx
7+
info: 3xx
8+
debug: 2xx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
type: regex_parser
2+
timestamp:
3+
parse_from: timestamp_field
4+
layout_type: strptime
5+
layout: '%Y-%m-%d'

0 commit comments

Comments
 (0)