Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/component/otelcol/receiver/prometheus/internal/logger_test.go
5406 views
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
15
package internal
16
17
import (
18
"fmt"
19
"net/http"
20
"testing"
21
22
"github.com/go-kit/log"
23
"github.com/go-kit/log/level"
24
"github.com/stretchr/testify/assert"
25
"github.com/stretchr/testify/require"
26
"go.uber.org/zap"
27
"go.uber.org/zap/zapcore"
28
"go.uber.org/zap/zaptest/observer"
29
)
30
31
func TestLog(t *testing.T) {
32
tcs := []struct {
33
name string
34
input []interface{}
35
wantLevel zapcore.Level
36
wantMessage string
37
}{
38
{
39
name: "Starting provider",
40
input: []interface{}{
41
"level",
42
level.DebugValue(),
43
"msg",
44
"Starting provider",
45
"provider",
46
"string/0",
47
"subs",
48
"[target1]",
49
},
50
wantLevel: zapcore.DebugLevel,
51
wantMessage: "Starting provider",
52
},
53
{
54
name: "Scrape failed",
55
input: []interface{}{
56
"level",
57
level.ErrorValue(),
58
"scrape_pool",
59
"target1",
60
"msg",
61
"Scrape failed",
62
"err",
63
"server returned HTTP status 500 Internal Server Error",
64
},
65
wantLevel: zapcore.ErrorLevel,
66
wantMessage: "Scrape failed",
67
},
68
}
69
70
for _, tc := range tcs {
71
t.Run(tc.name, func(t *testing.T) {
72
conf := zap.NewProductionConfig()
73
conf.Level.SetLevel(zapcore.DebugLevel)
74
75
// capture zap log entry
76
var entry zapcore.Entry
77
h := func(e zapcore.Entry) error {
78
entry = e
79
return nil
80
}
81
82
logger, err := conf.Build(zap.Hooks(h))
83
require.NoError(t, err)
84
85
adapter := NewZapToGokitLogAdapter(logger)
86
err = adapter.Log(tc.input...)
87
require.NoError(t, err)
88
89
assert.Equal(t, tc.wantLevel, entry.Level)
90
assert.Equal(t, tc.wantMessage, entry.Message)
91
})
92
}
93
}
94
95
func TestExtractLogData(t *testing.T) {
96
tcs := []struct {
97
name string
98
input []interface{}
99
wantLevel level.Value
100
wantMessage string
101
wantOutput []interface{}
102
}{
103
{
104
name: "nil fields",
105
input: nil,
106
wantLevel: level.InfoValue(), // Default
107
wantMessage: "",
108
wantOutput: nil,
109
},
110
{
111
name: "empty fields",
112
input: []interface{}{},
113
wantLevel: level.InfoValue(), // Default
114
wantMessage: "",
115
wantOutput: nil,
116
},
117
{
118
name: "info level",
119
input: []interface{}{
120
"level",
121
level.InfoValue(),
122
},
123
wantLevel: level.InfoValue(),
124
wantMessage: "",
125
wantOutput: nil,
126
},
127
{
128
name: "warn level",
129
input: []interface{}{
130
"level",
131
level.WarnValue(),
132
},
133
wantLevel: level.WarnValue(),
134
wantMessage: "",
135
wantOutput: nil,
136
},
137
{
138
name: "error level",
139
input: []interface{}{
140
"level",
141
level.ErrorValue(),
142
},
143
wantLevel: level.ErrorValue(),
144
wantMessage: "",
145
wantOutput: nil,
146
},
147
{
148
name: "debug level + extra fields",
149
input: []interface{}{
150
"timestamp",
151
1596604719,
152
"level",
153
level.DebugValue(),
154
"msg",
155
"http client error",
156
},
157
wantLevel: level.DebugValue(),
158
wantMessage: "http client error",
159
wantOutput: []interface{}{
160
"timestamp", 1596604719,
161
},
162
},
163
{
164
name: "missing level field",
165
input: []interface{}{
166
"timestamp",
167
1596604719,
168
"msg",
169
"http client error",
170
},
171
wantLevel: level.InfoValue(), // Default
172
wantMessage: "http client error",
173
wantOutput: []interface{}{
174
"timestamp", 1596604719,
175
},
176
},
177
{
178
name: "invalid level type",
179
input: []interface{}{
180
"level",
181
"warn", // String is not recognized
182
},
183
wantLevel: level.InfoValue(), // Default
184
wantOutput: []interface{}{
185
"level", "warn", // Field is preserved
186
},
187
},
188
}
189
190
for _, tc := range tcs {
191
t.Run(tc.name, func(t *testing.T) {
192
ld := extractLogData(tc.input)
193
assert.Equal(t, tc.wantLevel, ld.level)
194
assert.Equal(t, tc.wantMessage, ld.msg)
195
assert.Equal(t, tc.wantOutput, ld.otherFields)
196
})
197
}
198
}
199
200
func TestE2E(t *testing.T) {
201
logger, observed := observer.New(zap.DebugLevel)
202
gLogger := NewZapToGokitLogAdapter(zap.New(logger))
203
204
const targetStr = "https://host.docker.internal:5000/prometheus"
205
206
tcs := []struct {
207
name string
208
log func() error
209
wantLevel zapcore.Level
210
wantMessage string
211
wantOutput []zapcore.Field
212
}{
213
{
214
name: "debug level",
215
log: func() error {
216
return level.Debug(gLogger).Log()
217
},
218
wantLevel: zapcore.DebugLevel,
219
wantMessage: "",
220
wantOutput: []zapcore.Field{},
221
},
222
{
223
name: "info level",
224
log: func() error {
225
return level.Info(gLogger).Log()
226
},
227
wantLevel: zapcore.InfoLevel,
228
wantMessage: "",
229
wantOutput: []zapcore.Field{},
230
},
231
{
232
name: "warn level",
233
log: func() error {
234
return level.Warn(gLogger).Log()
235
},
236
wantLevel: zapcore.WarnLevel,
237
wantMessage: "",
238
wantOutput: []zapcore.Field{},
239
},
240
{
241
name: "error level",
242
log: func() error {
243
return level.Error(gLogger).Log()
244
},
245
wantLevel: zapcore.ErrorLevel,
246
wantMessage: "",
247
wantOutput: []zapcore.Field{},
248
},
249
{
250
name: "logger with and msg",
251
log: func() error {
252
ngLogger := log.With(gLogger, "scrape_pool", "scrape_pool")
253
ngLogger = log.With(ngLogger, "target", targetStr)
254
return level.Debug(ngLogger).Log("msg", "http client error", "err", fmt.Errorf("%s %q: dial tcp 192.168.65.2:5000: connect: connection refused", http.MethodGet, targetStr))
255
},
256
wantLevel: zapcore.DebugLevel,
257
wantMessage: "http client error",
258
wantOutput: []zapcore.Field{
259
zap.String("scrape_pool", "scrape_pool"),
260
zap.String("target", "https://host.docker.internal:5000/prometheus"),
261
zap.Error(fmt.Errorf("%s %q: dial tcp 192.168.65.2:5000: connect: connection refused", http.MethodGet, targetStr)),
262
},
263
},
264
{
265
name: "missing level",
266
log: func() error {
267
ngLogger := log.With(gLogger, "target", "foo")
268
return ngLogger.Log("msg", "http client error")
269
},
270
wantLevel: zapcore.InfoLevel, // Default
271
wantMessage: "http client error",
272
wantOutput: []zapcore.Field{
273
zap.String("target", "foo"),
274
},
275
},
276
{
277
name: "invalid level type",
278
log: func() error {
279
ngLogger := log.With(gLogger, "target", "foo")
280
return ngLogger.Log("msg", "http client error", "level", "warn")
281
},
282
wantLevel: zapcore.InfoLevel, // Default
283
wantMessage: "http client error",
284
wantOutput: []zapcore.Field{
285
zap.String("target", "foo"),
286
zap.String("level", "warn"), // Field is preserved
287
},
288
},
289
}
290
291
for _, tc := range tcs {
292
t.Run(tc.name, func(t *testing.T) {
293
assert.NoError(t, tc.log())
294
entries := observed.TakeAll()
295
require.Len(t, entries, 1)
296
assert.Equal(t, tc.wantLevel, entries[0].Level)
297
assert.Equal(t, tc.wantMessage, entries[0].Message)
298
assert.Equal(t, tc.wantOutput, entries[0].Context)
299
})
300
}
301
}
302
303