Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/component/loki/source/syslog/internal/syslogtarget/syslogtarget_test.go
4097 views
1
package syslogtarget
2
3
// This code is copied from Promtail. The syslogtarget package is used to
4
// configure and run the targets that can read syslog entries and forward them
5
// to other loki components.
6
7
import (
8
"crypto/tls"
9
"crypto/x509"
10
"fmt"
11
"io"
12
"net"
13
"os"
14
"testing"
15
"time"
16
"unicode/utf8"
17
18
"github.com/grafana/agent/component/common/loki/client/fake"
19
20
"github.com/go-kit/log"
21
"github.com/grafana/loki/clients/pkg/promtail/scrapeconfig"
22
"github.com/grafana/loki/clients/pkg/promtail/targets/syslog/syslogparser"
23
"github.com/influxdata/go-syslog/v3"
24
promconfig "github.com/prometheus/common/config"
25
"github.com/prometheus/common/model"
26
"github.com/prometheus/prometheus/model/relabel"
27
"github.com/stretchr/testify/require"
28
"gopkg.in/yaml.v2"
29
)
30
31
var (
32
caCert = []byte(`
33
-----BEGIN CERTIFICATE-----
34
MIIFDTCCAvWgAwIBAgIRAL3YFsDcKtnEWCzE0qafwlQwDQYJKoZIhvcNAQELBQAw
35
IDEeMBwGA1UEAxMVUHJvbXRhaWwgVGVzdCBSb290IENBMB4XDTIyMDYyOTA4MTQy
36
MFoXDTQyMDYyOTA4MTQyMFowIDEeMBwGA1UEAxMVUHJvbXRhaWwgVGVzdCBSb290
37
IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1wHnEwW3Gc1Q3v4F
38
BgFL9N2rayHA7yFqViEwG8AiliaCnnN5VaAN29tpWMgr9sLpve5Ka8iCO8xnIxsM
39
5rtlSvLlFW0SInXyJsBT6NyqHrk2GZBhscgT+Qb9ouSYjil4UFRADAAEhBZPVisO
40
ZQiELKPS+BxyRL15QhMB7k7u1z0GRzlrG7CcopzrYM+4JLGE+2nXnoy7MSjdNduH
41
w4sWwI66hD192Lpkh83HZneONXiZhJdEJOHHJ8G+rYwuZRAlnLs82y+OROIozuKV
42
yFhWMk+BUGgkeftmAzIiUAneKwKugqz9QExVPo1imGAsiVHdprTTPn/34ZNpsDR7
43
MXwzitVqvu/pa3BYDha7RTpeCdVPFqDs8BPFgcAleM75QQcnPtbUD/apJHUQ5D5q
44
8c2U/2hTtcTMZIMCscoBBpx98bSOS9ojIJSGYKCdBj6rqnAFNYasayVCN5c5pPIw
45
Mj7HUww4gKXVKMvNDnjaXqFBEgEjSv5cquZ993C8gVGHLiMnq/Bj5k9SeOD0gTKD
46
/uLuLhKiMI6sOJQrYW5W0P3tTNcYGUeS0hBZW2Mo6PM+BimfzstZhsdFQnjzMEld
47
I5elwqWKysEvxXIvLnGLVWXJ6s0Pyr6J0ASmxpjskQEcPgaOxkRVwNzC18eSq3Ey
48
zUEWoyHiDedB4CCIq6nXY01FC5MCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgKkMA8G
49
A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFBj1+WwOdP8rb95R7kOmWena3RfMA0G
50
CSqGSIb3DQEBCwUAA4ICAQDQtOpfNPrv+V8ObOb+pie//UfTReOwXtBZgTxMu1Bi
51
uYIiFEveQ18HGAeIhbVm8wLjtfPkoJlZKzdCcMqSmLt0LZQNs13IQ8M+YuXeu5pX
52
PJOu0WrbdQHW5JMnPxwKMk5T2axbrX9dYW9gvr8sh5OlnNTx88fY1vMBsnNLVZT+
53
kC7Daf0zT0Go6VxBk6KRtfpoVCy/aYgwbJ1u5W61eYtXC4ezrpoLINo7zVs7Tob8
54
iIxJMQ/iEk/7BbIgVh9z8lNeexdjXCqm8952pPhkGONneCESTxJjgYqXyhlV0ict
55
OP+CiMHl5yf6+eklfXU78Jmkh/46XBqu7JV8lt8xbbSJ4AITWxi3csxC/Xztyu/g
56
H5nS2gAmpAbTjHq7lGicFScBuR3g0o3+64KN3XhVXN1KFrTlsGSOxyPE657p2xNw
57
tAAQs9IEBIPVqMInOGue6LbHTzCzW8hMClfu0CwPXiMY5DWKif7O9kzxnb9HdmAl
58
gnDn+9OzTw7oAW1UyVTSbzYy0Tw1ioYR7U77Z+Gcst2+mIuWp7BFNkaX5mPaacCT
59
GLnXoZk8UU0ph5/uBfZL3dNsJKeXlnCMAXACdLicnMC19g6P/dKqRZcI2w7kTPtF
60
2GlKMYjeKDuAUc9VeGzDc6PAX4oqF8XPfP5Mie4nrtpYnL0zKV1RcUS1yX1TC24O
61
ig==
62
-----END CERTIFICATE-----
63
`)
64
65
// Unused, but can be useful to (re)generate some certificates
66
// nolint:deadcode,unused,varcheck
67
caKey = []byte(`
68
-----BEGIN RSA PRIVATE KEY-----
69
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
118
-----END RSA PRIVATE KEY-----
119
`)
120
121
serverCert = []byte(`
122
-----BEGIN CERTIFICATE-----
123
MIIFWDCCA0CgAwIBAgIRAMWnlYEx52Vws2b3EzexW+UwDQYJKoZIhvcNAQELBQAw
124
IDEeMBwGA1UEAxMVUHJvbXRhaWwgVGVzdCBSb290IENBMB4XDTIyMDYyOTA4MTQy
125
NFoXDTQyMDYyOTA4MTQyNFowKzEpMCcGA1UEAxMgUHJvbXRhaWwgVGVzdCBTZXJ2
126
ZXIgQ2VydGlmaWNhdGUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCo
127
8+m8sVjG2tvRqzFWD6XRwvWIV/7nOHhuL7ygdouTJ5MKjpKHSudOXOoxHw9aNA4u
128
zmExqlSD4RVnwb2R/nXoqO1Ae5VavkNngeDw5Uk/RacqF4WFCnmFNxh523iA4ifo
129
ZxmVhQoE1t3O4kMrygK2SEpSTY58PfuqLfd7ZyHDEmpu9pYfuQQCqKLOsVQS5mqY
130
g7gyKQQLq0D4beCsSuih09PskMiG29uh/qCdSmDDR++j42xP/fwXVGm3nsOMLjQf
131
1DFlZFqmQS42Da1KtnKzz+SVDSHihyRKiZ0KAyyDHYdKToFO/zYlCgFGw86o4VGu
132
HKbolE6oPrBnqdXyIf9cON4RdnoTrChG4E6yq4LN8XoNRloePjoGQ9huoqwGie3m
133
c06Pnj2eV4oCJwdLarKZqZzdJnanx+ctObAGGGjjV1ocNGFc2EMBpTFVpy20Kqd/
134
E7t2yeGU6wJhzMNtvyFHhcOY+7PRTuvrUzbK1McFU/6NKBn4ioW2XBU8CjPEKGNx
135
itIZWnxppqkt2EemZEB+L1QpNtNlFmSYLqPm+j1134os3I3s+kkawiSjBcpqgzDf
136
stt64LiO/ULXDfPexbzE+mggQ3GsQ+b5v2O4KTQ4A4ilI48+0Qn3YxqfaVJmusGE
137
+Jkpo/Fnt3OCJaYBqsSzK5dIzF9TJhsOb+f5NGBJEQIDAQABo4GBMH8wDgYDVR0P
138
AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB
139
Af8EAjAAMB8GA1UdIwQYMBaAFFBj1+WwOdP8rb95R7kOmWena3RfMB8GA1UdEQQY
140
MBaCFHByb210YWlsLmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4ICAQApSDHl
141
IECz4Ix+6zZqNU0DgulYTXcHKtnXEKRJVTULbKy/mWzE5ZAgVV0rpRLHbRg0fWYh
142
4tjd5X/Pedf4OtnpV6ekkvBf+QCKAmDiWN9rKhjdVoTFw0+wavQv1yzz8++2HenR
143
rgq7wWuwg0hB9/KKOWW09ZuBynjB7aeoWHztIbD+/cugMlzqDX8hODRl3OaEAwM3
144
PBpYEqFSuPBNrCK5Y0tGgzZDdsxrDYcX5CjJdrgwtZ1kFOT8J2VE+2Sqc7KMCPFl
145
LQmmtIcwjljNABf5d2L978tISFtwRoZVxrsTODqLLF8l6B7JUQdCpmoM+549E0cS
146
bpTj4FVftJwEpElMFMVw/Uh5pA7hOLGAK3YYqBx6fbEGHn+WmwLA5Io7tbBSKUX/
147
hNlOFupAU3Q/OawqlmSPRflqKIg4b8TgSVlafJOFmvKg0WLGVuLtl65g9eNQVht9
148
KLlPPCPbpYKXpXya42eFazxEepOeaCkchOUB+x4tmAZ44NJTMR+UmiGLGCjdQTpU
149
m892bbGtLA0hGhYGrMsI546Xd8PjNI117CARrDpk57E1V+CsAO6ZTOPLgI4q976L
150
kWYB12V1t/BNtGyChdmfIYBqvTYAGk9hbqG80SjmcZtPu5JIEvIXCyaYXiWmEs2l
151
j1ieRNjgNYyG/7wJmilCsnpjbWza85/JzxE1cA==
152
-----END CERTIFICATE-----
153
`)
154
155
serverKey = []byte(`
156
-----BEGIN RSA PRIVATE KEY-----
157
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
206
-----END RSA PRIVATE KEY-----
207
`)
208
209
clientCert = []byte(`
210
-----BEGIN CERTIFICATE-----
211
MIIFNTCCAx2gAwIBAgIQWzE3b7oUqYGe2UvYWJBnyDANBgkqhkiG9w0BAQsFADAg
212
MR4wHAYDVQQDExVQcm9tdGFpbCBUZXN0IFJvb3QgQ0EwHhcNMjIwNjI5MDgxNDI0
213
WhcNNDIwNjI5MDgxNDI0WjArMSkwJwYDVQQDEyBQcm9tdGFpbCBUZXN0IENsaWVu
214
dCBDZXJ0aWZpY2F0ZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALcQ
215
KhIIL7EZLIDWPMIkT5cJdPRavs5/LO50isCVs2z+PTA4mIkj2NEk8qFqgc3+1LUh
216
SV/NQ3p0LikSx9M6g1oBJbqQ7W6BcCzzUOHb4QlGoa2DXXGONPdO3AJxTTDNU6Li
217
xT5ESTbuDe56JDw3x2V0pxOzCUSuTMa1mvHnIojVn/8qHOZB0l4o9c44oHGJDUGh
218
o1wAc3UXGMLsd6IEYsHzLyG6kG7ayqToFftI/rkpEK8tCWMbclewh22c0OCXejEZ
219
pS9mz2decoIG7NnkqrRwUj+RPNlKJgBJ2USYimbQZHmdZWNb+vP/HFXs1Eq0sin+
220
5HrRnzuB6yCwQlqvR7Db3buENEXG2OcglGmO/1mBfB4nW7JKFAvIqBBtHDRmBCYr
221
YS9htPiZte8Mfak3RncxLLccEzo1CNqtW9BLfryGH3l+6LR0yZkw+C95RZ9Wni4T
222
e5hy5yX8SW3z4AUb3ZYbFROW4sW/sSsh8VucZoa4OXw981OB4ZGrtJnncvc1KE5Q
223
BBF+bRZKdMQhzwb7pZq31kZjH0So53Ntyf4S6VHgUOTs8xorPSjnP85BKnnm7XsG
224
W/zP+kGCyjOCu4WIrNvSlIguF4KcVZulWbMljVCU0TwKNbxBm5SZrTXPoJeyRtE6
225
ai+fHPoMjJvwUaLYQUkzTpfdGg8OCV3NX/LvbCuVAgMBAAGjYDBeMA4GA1UdDwEB
226
/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/
227
BAIwADAfBgNVHSMEGDAWgBRQY9flsDnT/K2/eUe5Dplnp2t0XzANBgkqhkiG9w0B
228
AQsFAAOCAgEAxJvDifKqK6EQrN5VPL68IPORu1VK17HeSJ2xLScL3Hh7vulPs9Nf
229
HLixcOhixsYhgurFZ3M3K05tT0EKy1K7WLJzJEhPccAkbz+d2oIeghksq2l75u20
230
t2o1X8rgT+/7d/j+VBur/+igQdwvylo+wgGNosX8VmjyQrZBWIHvDTyzrvODFbZa
231
JYf3DfgLSF5tr4e/HNLhynUD9G40CmRLQh7PkojrMXMyeqqWpBPzDBlZgvH2QMK8
232
K9S8KUuaZhGUTLQmkR3NP/bx1V/Ks1/BtpmdIchQ42w+Uu2PM/pmuZsnX7bK0tzd
233
zCFjgSIxifN8BKdcKMEngo+MwYy/Fj3vzy4qXxtOCbnzB+A/ziLiJV3Tsdwm+nPO
234
xZFcXXfnCMoNF0ouv2/WAbUrKLTZXL712MZ14JT79TkKxWZ49AUHSiGfm1I45iky
235
xgcn4FVgJpsCheRqL+gecNDyq+4VdwlWuFAuqMI4UBUbWwyAntOL1iiyENGA1ygo
236
OVuQq9M0bh93d5U+Ct79CsL4LLaoRrvBGJ6WnO8PKTTLqfFC3T8ySCtVGZiLoSqn
237
fJ1uhxhK8YSYhod+81/nkpJuF1xRg1t2kXgvUxPR9jzf96QaZ/94oryEH3zr59Rb
238
wmOulo1MN6yRdGzWiJ8sZ8VXUuh0xBCUiwrpo++Dda2s0bF0YzJGI6E=
239
-----END CERTIFICATE-----
240
`)
241
clientKey = []byte(`
242
-----BEGIN RSA PRIVATE KEY-----
243
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
292
-----END RSA PRIVATE KEY-----
293
`)
294
)
295
296
type formatFunc func(string) string
297
298
var (
299
fmtOctetCounting = func(s string) string { return fmt.Sprintf("%d %s", len(s), s) }
300
fmtNewline = func(s string) string { return s + "\n" }
301
)
302
303
func Benchmark_SyslogTarget(b *testing.B) {
304
for _, tt := range []struct {
305
name string
306
protocol string
307
formatFunc formatFunc
308
}{
309
{"tcp", protocolTCP, fmtOctetCounting},
310
{"udp", protocolUDP, fmtOctetCounting},
311
} {
312
tt := tt
313
b.Run(tt.name, func(b *testing.B) {
314
client := fake.NewClient(func() {})
315
316
metrics := NewMetrics(nil)
317
tgt, _ := NewSyslogTarget(metrics, log.NewNopLogger(), client, []*relabel.Config{}, &scrapeconfig.SyslogTargetConfig{
318
ListenAddress: "127.0.0.1:0",
319
ListenProtocol: tt.protocol,
320
LabelStructuredData: true,
321
Labels: model.LabelSet{
322
"test": "syslog_target",
323
},
324
})
325
b.Cleanup(func() {
326
require.NoError(b, tgt.Stop())
327
})
328
require.Eventually(b, tgt.Ready, time.Second, 10*time.Millisecond)
329
330
addr := tgt.ListenAddress().String()
331
332
messages := []string{
333
`<165>1 2022-04-08T22:14:10.001Z host1 app - id1 [custom@32473 exkey="1"] An application event log entry...`,
334
`<165>1 2022-04-08T22:14:11.002Z host2 app - id2 [custom@32473 exkey="1"] An application event log entry...`,
335
`<165>1 2022-04-08T22:14:12.003Z host1 app - id3 [custom@32473 exkey="1"] An application event log entry...`,
336
`<165>1 2022-04-08T22:14:13.004Z host2 app - id4 [custom@32473 exkey="1"] An application event log entry...`,
337
`<165>1 2022-04-08T22:14:14.005Z host1 app - id5 [custom@32473 exkey="1"] An application event log entry...`,
338
`<165>1 2022-04-08T22:14:15.002Z host2 app - id6 [custom@32473 exkey="1"] An application event log entry...`,
339
`<165>1 2022-04-08T22:14:16.003Z host1 app - id7 [custom@32473 exkey="1"] An application event log entry...`,
340
`<165>1 2022-04-08T22:14:17.004Z host2 app - id8 [custom@32473 exkey="1"] An application event log entry...`,
341
`<165>1 2022-04-08T22:14:18.005Z host1 app - id9 [custom@32473 exkey="1"] An application event log entry...`,
342
`<165>1 2022-04-08T22:14:19.001Z host2 app - id10 [custom@32473 exkey="1"] An application event log entry...`,
343
}
344
345
b.ReportAllocs()
346
b.ResetTimer()
347
348
c, _ := net.Dial(tt.protocol, addr)
349
for n := 0; n < b.N; n++ {
350
_ = writeMessagesToStream(c, messages, tt.formatFunc)
351
}
352
c.Close()
353
354
require.Eventuallyf(b, func() bool {
355
return len(client.Received()) == len(messages)*b.N
356
}, 15*time.Second, time.Second, "expected: %d got:%d", len(messages)*b.N, len(client.Received()))
357
})
358
}
359
}
360
361
func TestSyslogTarget(t *testing.T) {
362
for _, tt := range []struct {
363
name string
364
protocol string
365
fmtFunc formatFunc
366
}{
367
{"tpc newline separated", protocolTCP, fmtNewline},
368
{"tpc octetcounting", protocolTCP, fmtOctetCounting},
369
{"udp newline separated", protocolUDP, fmtNewline},
370
{"udp octetcounting", protocolUDP, fmtOctetCounting},
371
} {
372
tt := tt
373
t.Run(tt.name, func(t *testing.T) {
374
w := log.NewSyncWriter(os.Stderr)
375
logger := log.NewLogfmtLogger(w)
376
client := fake.NewClient(func() {})
377
378
metrics := NewMetrics(nil)
379
tgt, err := NewSyslogTarget(metrics, logger, client, relabelConfig(t), &scrapeconfig.SyslogTargetConfig{
380
MaxMessageLength: 1 << 12, // explicitly not use default value
381
ListenAddress: "127.0.0.1:0",
382
ListenProtocol: tt.protocol,
383
LabelStructuredData: true,
384
Labels: model.LabelSet{
385
"test": "syslog_target",
386
},
387
})
388
require.NoError(t, err)
389
390
require.Eventually(t, tgt.Ready, time.Second, 10*time.Millisecond)
391
392
addr := tgt.ListenAddress().String()
393
c, err := net.Dial(tt.protocol, addr)
394
require.NoError(t, err)
395
396
messages := []string{
397
`<165>1 2018-10-11T22:14:15.003Z host5 e - id1 [custom@32473 exkey="1"] An application event log entry...`,
398
`<165>1 2018-10-11T22:14:15.005Z host5 e - id2 [custom@32473 exkey="2"] An application event log entry...`,
399
`<165>1 2018-10-11T22:14:15.007Z host5 e - id3 [custom@32473 exkey="3"] An application event log entry...`,
400
}
401
402
err = writeMessagesToStream(c, messages, tt.fmtFunc)
403
require.NoError(t, err)
404
require.NoError(t, c.Close())
405
406
if tt.protocol == protocolUDP {
407
time.Sleep(time.Second)
408
require.NoError(t, tgt.Stop())
409
} else {
410
defer func() {
411
require.NoError(t, tgt.Stop())
412
}()
413
}
414
415
require.Eventuallyf(t, func() bool {
416
return len(client.Received()) == len(messages)
417
}, time.Second, 10*time.Millisecond, "Expected to receive %d messages.", len(messages))
418
419
labels := make([]model.LabelSet, 0, len(messages))
420
for _, entry := range client.Received() {
421
labels = append(labels, entry.Labels)
422
}
423
// we only check if one of the received entries contain the wanted label set
424
// because UDP does not guarantee the order of the messages
425
require.Contains(t, labels, model.LabelSet{
426
"test": "syslog_target",
427
428
"severity": "notice",
429
"facility": "local4",
430
"hostname": "host5",
431
"app_name": "e",
432
"msg_id": "id1",
433
434
"sd_custom_exkey": "1",
435
})
436
require.Equal(t, "An application event log entry...", client.Received()[0].Line)
437
438
require.NotZero(t, client.Received()[0].Timestamp)
439
})
440
}
441
}
442
443
func relabelConfig(t *testing.T) []*relabel.Config {
444
relabelCfg := `
445
- source_labels: ['__syslog_message_severity']
446
target_label: 'severity'
447
- source_labels: ['__syslog_message_facility']
448
target_label: 'facility'
449
- source_labels: ['__syslog_message_hostname']
450
target_label: 'hostname'
451
- source_labels: ['__syslog_message_app_name']
452
target_label: 'app_name'
453
- source_labels: ['__syslog_message_proc_id']
454
target_label: 'proc_id'
455
- source_labels: ['__syslog_message_msg_id']
456
target_label: 'msg_id'
457
- source_labels: ['__syslog_message_sd_custom_32473_exkey']
458
target_label: 'sd_custom_exkey'
459
`
460
461
var relabels []*relabel.Config
462
err := yaml.Unmarshal([]byte(relabelCfg), &relabels)
463
require.NoError(t, err)
464
465
return relabels
466
}
467
468
func writeMessagesToStream(w io.Writer, messages []string, formatter formatFunc) error {
469
for _, msg := range messages {
470
_, err := fmt.Fprint(w, formatter(msg))
471
if err != nil {
472
return err
473
}
474
}
475
return nil
476
}
477
478
func TestSyslogTarget_RFC5424Messages(t *testing.T) {
479
for _, tt := range []struct {
480
name string
481
protocol string
482
fmtFunc formatFunc
483
}{
484
{"tpc newline separated", protocolTCP, fmtNewline},
485
{"tpc octetcounting", protocolTCP, fmtOctetCounting},
486
} {
487
tt := tt
488
t.Run(tt.name, func(t *testing.T) {
489
w := log.NewSyncWriter(os.Stderr)
490
logger := log.NewLogfmtLogger(w)
491
client := fake.NewClient(func() {})
492
493
metrics := NewMetrics(nil)
494
tgt, err := NewSyslogTarget(metrics, logger, client, []*relabel.Config{}, &scrapeconfig.SyslogTargetConfig{
495
ListenAddress: "127.0.0.1:0",
496
ListenProtocol: tt.protocol,
497
LabelStructuredData: true,
498
Labels: model.LabelSet{
499
"test": "syslog_target",
500
},
501
UseRFC5424Message: true,
502
})
503
require.NoError(t, err)
504
require.Eventually(t, tgt.Ready, time.Second, 10*time.Millisecond)
505
defer func() {
506
require.NoError(t, tgt.Stop())
507
}()
508
509
addr := tgt.ListenAddress().String()
510
c, err := net.Dial(tt.protocol, addr)
511
require.NoError(t, err)
512
513
messages := []string{
514
`<165>1 2018-10-11T22:14:15.003Z host5 e - id1 [custom@32473 exkey="1"] An application event log entry...`,
515
`<165>1 2018-10-11T22:14:15.005Z host5 e - id2 [custom@32473 exkey="2"] An application event log entry...`,
516
`<165>1 2018-10-11T22:14:15.007Z host5 e - id3 [custom@32473 exkey="3"] An application event log entry...`,
517
}
518
519
err = writeMessagesToStream(c, messages, tt.fmtFunc)
520
require.NoError(t, err)
521
require.NoError(t, c.Close())
522
523
require.Eventuallyf(t, func() bool {
524
return len(client.Received()) == len(messages)
525
}, time.Second, time.Millisecond, "Expected to receive %d messages, got %d.", len(messages), len(client.Received()))
526
527
for i := range messages {
528
require.Equal(t, model.LabelSet{
529
"test": "syslog_target",
530
}, client.Received()[i].Labels)
531
require.Contains(t, messages, client.Received()[i].Line)
532
require.NotZero(t, client.Received()[i].Timestamp)
533
}
534
})
535
}
536
}
537
538
func TestSyslogTarget_TLSConfigWithoutServerCertificate(t *testing.T) {
539
w := log.NewSyncWriter(os.Stderr)
540
logger := log.NewLogfmtLogger(w)
541
client := fake.NewClient(func() {})
542
543
metrics := NewMetrics(nil)
544
_, err := NewSyslogTarget(metrics, logger, client, relabelConfig(t), &scrapeconfig.SyslogTargetConfig{
545
ListenAddress: "127.0.0.1:0",
546
TLSConfig: promconfig.TLSConfig{
547
KeyFile: "foo",
548
},
549
})
550
require.Error(t, err, "error setting up syslog target: certificate and key files are required")
551
}
552
553
func TestSyslogTarget_TLSConfigWithoutServerKey(t *testing.T) {
554
w := log.NewSyncWriter(os.Stderr)
555
logger := log.NewLogfmtLogger(w)
556
client := fake.NewClient(func() {})
557
558
metrics := NewMetrics(nil)
559
_, err := NewSyslogTarget(metrics, logger, client, relabelConfig(t), &scrapeconfig.SyslogTargetConfig{
560
ListenAddress: "127.0.0.1:0",
561
TLSConfig: promconfig.TLSConfig{
562
CertFile: "foo",
563
},
564
})
565
require.Error(t, err, "error setting up syslog target: certificate and key files are required")
566
}
567
568
func TestSyslogTarget_TLSConfig(t *testing.T) {
569
t.Run("NewlineSeparatedMessages", func(t *testing.T) {
570
testSyslogTargetWithTLS(t, fmtNewline)
571
})
572
t.Run("OctetCounting", func(t *testing.T) {
573
testSyslogTargetWithTLS(t, fmtOctetCounting)
574
})
575
}
576
577
func testSyslogTargetWithTLS(t *testing.T, fmtFunc formatFunc) {
578
caCertPool := x509.NewCertPool()
579
caCertPool.AppendCertsFromPEM(caCert)
580
581
serverCertFile, err := createTempFile(serverCert)
582
if err != nil {
583
t.Fatalf("Unable to create server certificate temporary file: %s", err)
584
}
585
defer os.Remove(serverCertFile.Name())
586
587
serverKeyFile, err := createTempFile(serverKey)
588
if err != nil {
589
t.Fatalf("Unable to create server key temporary file: %s", err)
590
}
591
defer os.Remove(serverKeyFile.Name())
592
593
w := log.NewSyncWriter(os.Stderr)
594
logger := log.NewLogfmtLogger(w)
595
client := fake.NewClient(func() {})
596
597
metrics := NewMetrics(nil)
598
tgt, err := NewSyslogTarget(metrics, logger, client, relabelConfig(t), &scrapeconfig.SyslogTargetConfig{
599
ListenAddress: "127.0.0.1:0",
600
LabelStructuredData: true,
601
Labels: model.LabelSet{
602
"test": "syslog_target",
603
},
604
TLSConfig: promconfig.TLSConfig{
605
CertFile: serverCertFile.Name(),
606
KeyFile: serverKeyFile.Name(),
607
},
608
})
609
require.NoError(t, err)
610
defer func() {
611
require.NoError(t, tgt.Stop())
612
}()
613
614
tlsConfig := tls.Config{
615
RootCAs: caCertPool,
616
ServerName: "promtail.example.com",
617
}
618
619
addr := tgt.ListenAddress().String()
620
c, err := tls.Dial("tcp", addr, &tlsConfig)
621
require.NoError(t, err)
622
623
validMessages := []string{
624
`<165>1 2018-10-11T22:14:15.003Z host5 e - id1 [custom@32473 exkey="1"] An application event log entry...`,
625
`<165>1 2018-10-11T22:14:15.005Z host5 e - id2 [custom@32473 exkey="2"] An application event log entry...`,
626
`<165>1 2018-10-11T22:14:15.007Z host5 e - id3 [custom@32473 exkey="3"] An application event log entry...`,
627
}
628
// Messages that are malformed but still valid.
629
// This causes error messages being written, but the parser does not stop and close the connection.
630
malformeddMessages := []string{
631
`<165>1 - An application event log entry...`,
632
`<165>1 2018-10-11T22:14:15.007Z host5 e - An application event log entry...`,
633
}
634
messages := append(malformeddMessages, validMessages...)
635
636
err = writeMessagesToStream(c, messages, fmtFunc)
637
require.NoError(t, err)
638
require.NoError(t, c.Close())
639
640
require.Eventuallyf(t, func() bool {
641
return len(client.Received()) == len(validMessages)
642
}, time.Second, time.Millisecond, "Expected to receive %d messages, got %d.", len(validMessages), len(client.Received()))
643
644
require.Equal(t, model.LabelSet{
645
"test": "syslog_target",
646
647
"severity": "notice",
648
"facility": "local4",
649
"hostname": "host5",
650
"app_name": "e",
651
"msg_id": "id1",
652
653
"sd_custom_exkey": "1",
654
}, client.Received()[0].Labels)
655
require.Equal(t, "An application event log entry...", client.Received()[0].Line)
656
657
require.NotZero(t, client.Received()[0].Timestamp)
658
}
659
660
func createTempFile(data []byte) (*os.File, error) {
661
tmpFile, err := os.CreateTemp("", "")
662
if err != nil {
663
return nil, fmt.Errorf("failed to create temporary file: %s", err)
664
}
665
666
if _, err := tmpFile.Write(data); err != nil {
667
return nil, fmt.Errorf("failed to write data to temporary file: %s", err)
668
}
669
670
if err := tmpFile.Close(); err != nil {
671
return nil, err
672
}
673
674
return tmpFile, nil
675
}
676
677
func TestSyslogTarget_TLSConfigVerifyClientCertificate(t *testing.T) {
678
t.Run("NewlineSeparatedMessages", func(t *testing.T) {
679
testSyslogTargetWithTLSVerifyClientCertificate(t, fmtNewline)
680
})
681
t.Run("OctetCounting", func(t *testing.T) {
682
testSyslogTargetWithTLSVerifyClientCertificate(t, fmtOctetCounting)
683
})
684
}
685
686
func testSyslogTargetWithTLSVerifyClientCertificate(t *testing.T, fmtFunc formatFunc) {
687
caCertFile, err := createTempFile(caCert)
688
if err != nil {
689
t.Fatalf("Unable to create CA certificate temporary file: %s", err)
690
}
691
defer os.Remove(caCertFile.Name())
692
693
caCertPool := x509.NewCertPool()
694
caCertPool.AppendCertsFromPEM(caCert)
695
696
serverCertFile, err := createTempFile(serverCert)
697
if err != nil {
698
t.Fatalf("Unable to create server certificate temporary file: %s", err)
699
}
700
defer os.Remove(serverCertFile.Name())
701
702
serverKeyFile, err := createTempFile(serverKey)
703
if err != nil {
704
t.Fatalf("Unable to create server key temporary file: %s", err)
705
}
706
defer os.Remove(serverKeyFile.Name())
707
708
clientCertFile, err := createTempFile(clientCert)
709
if err != nil {
710
t.Fatalf("Unable to create client certificate temporary file: %s", err)
711
}
712
defer os.Remove(clientCertFile.Name())
713
714
clientKeyFile, err := createTempFile(clientKey)
715
if err != nil {
716
t.Fatalf("Unable to create client key temporary file: %s", err)
717
}
718
defer os.Remove(clientKeyFile.Name())
719
720
clientCerts, err := tls.LoadX509KeyPair(clientCertFile.Name(), clientKeyFile.Name())
721
if err != nil {
722
t.Fatalf("Unable to load client certificate or key: %s", err)
723
}
724
725
w := log.NewSyncWriter(os.Stderr)
726
logger := log.NewLogfmtLogger(w)
727
client := fake.NewClient(func() {})
728
729
metrics := NewMetrics(nil)
730
tgt, err := NewSyslogTarget(metrics, logger, client, relabelConfig(t), &scrapeconfig.SyslogTargetConfig{
731
ListenAddress: "127.0.0.1:0",
732
LabelStructuredData: true,
733
Labels: model.LabelSet{
734
"test": "syslog_target",
735
},
736
TLSConfig: promconfig.TLSConfig{
737
CAFile: caCertFile.Name(),
738
CertFile: serverCertFile.Name(),
739
KeyFile: serverKeyFile.Name(),
740
},
741
})
742
require.NoError(t, err)
743
defer func() {
744
require.NoError(t, tgt.Stop())
745
}()
746
747
tlsConfig := tls.Config{
748
RootCAs: caCertPool,
749
ServerName: "promtail.example.com",
750
}
751
752
addr := tgt.ListenAddress().String()
753
754
t.Run("WithoutClientCertificate", func(t *testing.T) {
755
c, err := tls.Dial("tcp", addr, &tlsConfig)
756
require.NoError(t, err)
757
758
err = c.SetDeadline(time.Now().Add(time.Second))
759
require.NoError(t, err)
760
761
buf := make([]byte, 1)
762
_, err = c.Read(buf)
763
require.EqualError(t, err, "remote error: tls: bad certificate")
764
})
765
766
t.Run("WithClientCertificate", func(t *testing.T) {
767
tlsConfig.Certificates = []tls.Certificate{clientCerts}
768
c, err := tls.Dial("tcp", addr, &tlsConfig)
769
require.NoError(t, err)
770
771
messages := []string{
772
`<165>1 2018-10-11T22:14:15.003Z host5 e - id1 [custom@32473 exkey="1"] An application event log entry...`,
773
`<165>1 2018-10-11T22:14:15.005Z host5 e - id2 [custom@32473 exkey="2"] An application event log entry...`,
774
`<165>1 2018-10-11T22:14:15.007Z host5 e - id3 [custom@32473 exkey="3"] An application event log entry...`,
775
}
776
777
err = writeMessagesToStream(c, messages, fmtFunc)
778
require.NoError(t, err)
779
require.NoError(t, c.Close())
780
781
require.Eventuallyf(t, func() bool {
782
return len(client.Received()) == len(messages)
783
}, time.Second, time.Millisecond, "Expected to receive %d messages, got %d.", len(messages), len(client.Received()))
784
785
require.Equal(t, model.LabelSet{
786
"test": "syslog_target",
787
788
"severity": "notice",
789
"facility": "local4",
790
"hostname": "host5",
791
"app_name": "e",
792
"msg_id": "id1",
793
794
"sd_custom_exkey": "1",
795
}, client.Received()[0].Labels)
796
require.Equal(t, "An application event log entry...", client.Received()[0].Line)
797
798
require.NotZero(t, client.Received()[0].Timestamp)
799
})
800
}
801
802
func TestSyslogTarget_InvalidData(t *testing.T) {
803
w := log.NewSyncWriter(os.Stderr)
804
logger := log.NewLogfmtLogger(w)
805
client := fake.NewClient(func() {})
806
metrics := NewMetrics(nil)
807
808
tgt, err := NewSyslogTarget(metrics, logger, client, relabelConfig(t), &scrapeconfig.SyslogTargetConfig{
809
ListenAddress: "127.0.0.1:0",
810
})
811
require.NoError(t, err)
812
defer func() {
813
require.NoError(t, tgt.Stop())
814
}()
815
816
addr := tgt.ListenAddress().String()
817
c, err := net.Dial("tcp", addr)
818
require.NoError(t, err)
819
defer c.Close()
820
821
_, err = fmt.Fprint(c, "xxx")
822
require.NoError(t, err)
823
824
// syslog target should immediately close the connection if sent invalid data
825
err = c.SetDeadline(time.Now().Add(time.Second))
826
require.NoError(t, err)
827
828
buf := make([]byte, 1)
829
_, err = c.Read(buf)
830
require.EqualError(t, err, "EOF")
831
}
832
833
func TestSyslogTarget_NonUTF8Message(t *testing.T) {
834
w := log.NewSyncWriter(os.Stderr)
835
logger := log.NewLogfmtLogger(w)
836
client := fake.NewClient(func() {})
837
metrics := NewMetrics(nil)
838
839
tgt, err := NewSyslogTarget(metrics, logger, client, relabelConfig(t), &scrapeconfig.SyslogTargetConfig{
840
ListenAddress: "127.0.0.1:0",
841
})
842
require.NoError(t, err)
843
defer func() {
844
require.NoError(t, tgt.Stop())
845
}()
846
847
addr := tgt.ListenAddress().String()
848
c, err := net.Dial("tcp", addr)
849
require.NoError(t, err)
850
851
msg1 := "Some non utf8 \xF8\xF7\xE3\xE4 characters"
852
require.False(t, utf8.ValidString(msg1), "msg must no be valid utf8")
853
msg2 := "\xF8 other \xF7\xE3\xE4 characters \xE3"
854
require.False(t, utf8.ValidString(msg2), "msg must no be valid utf8")
855
856
err = writeMessagesToStream(c, []string{
857
"<165>1 - - - - - - " + msg1,
858
"<123>1 - - - - - - " + msg2,
859
}, fmtOctetCounting)
860
require.NoError(t, err)
861
require.NoError(t, c.Close())
862
863
require.Eventuallyf(t, func() bool {
864
return len(client.Received()) == 2
865
}, time.Second, time.Millisecond, "Expected to receive 2 messages, got %d.", len(client.Received()))
866
867
require.Equal(t, msg1, client.Received()[0].Line)
868
require.Equal(t, msg2, client.Received()[1].Line)
869
}
870
871
func TestSyslogTarget_IdleTimeout(t *testing.T) {
872
w := log.NewSyncWriter(os.Stderr)
873
logger := log.NewLogfmtLogger(w)
874
client := fake.NewClient(func() {})
875
metrics := NewMetrics(nil)
876
877
tgt, err := NewSyslogTarget(metrics, logger, client, relabelConfig(t), &scrapeconfig.SyslogTargetConfig{
878
ListenAddress: "127.0.0.1:0",
879
IdleTimeout: time.Millisecond,
880
})
881
require.NoError(t, err)
882
defer func() {
883
require.NoError(t, tgt.Stop())
884
}()
885
886
addr := tgt.ListenAddress().String()
887
c, err := net.Dial("tcp", addr)
888
require.NoError(t, err)
889
defer c.Close()
890
891
// connection should be closed before the higher timeout
892
// from SetDeadline fires
893
err = c.SetDeadline(time.Now().Add(time.Second))
894
require.NoError(t, err)
895
896
buf := make([]byte, 1)
897
_, err = c.Read(buf)
898
require.EqualError(t, err, "EOF")
899
}
900
901
func TestParseStream_WithAsyncPipe(t *testing.T) {
902
lines := [3]string{
903
"<165>1 2018-10-11T22:14:15.003Z host5 e - id1 [custom@32473 exkey=\"1\"] An application event log entry...\n",
904
"<165>1 2018-10-11T22:14:15.005Z host5 e - id2 [custom@32473 exkey=\"2\"] An application event log entry...\n",
905
"<165>1 2018-10-11T22:14:15.007Z host5 e - id3 [custom@32473 exkey=\"3\"] An application event log entry...\n",
906
}
907
908
addr := &net.UDPAddr{IP: net.IP{127, 0, 0, 1}, Port: 1514}
909
pipe := NewConnPipe(addr)
910
go func() {
911
for _, line := range lines {
912
_, _ = pipe.Write([]byte(line))
913
}
914
pipe.Close()
915
}()
916
917
results := make([]*syslog.Result, 0)
918
cb := func(res *syslog.Result) {
919
results = append(results, res)
920
}
921
922
err := syslogparser.ParseStream(pipe, cb, DefaultMaxMessageLength)
923
require.NoError(t, err)
924
require.Equal(t, 3, len(results))
925
}
926
927