logstash-patterns-core 4.1.2 → 4.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.md +119 -0
- data/Gemfile +8 -1
- data/LICENSE +199 -10
- data/README.md +12 -19
- data/lib/logstash/patterns/core.rb +11 -3
- data/logstash-patterns-core.gemspec +1 -1
- data/patterns/ecs-v1/aws +28 -0
- data/patterns/ecs-v1/bacula +53 -0
- data/patterns/ecs-v1/bind +13 -0
- data/patterns/ecs-v1/bro +30 -0
- data/patterns/ecs-v1/exim +26 -0
- data/patterns/ecs-v1/firewalls +111 -0
- data/patterns/ecs-v1/grok-patterns +95 -0
- data/patterns/ecs-v1/haproxy +40 -0
- data/patterns/ecs-v1/httpd +17 -0
- data/patterns/ecs-v1/java +34 -0
- data/patterns/ecs-v1/junos +13 -0
- data/patterns/ecs-v1/linux-syslog +16 -0
- data/patterns/{maven → ecs-v1/maven} +0 -0
- data/patterns/ecs-v1/mcollective +4 -0
- data/patterns/ecs-v1/mongodb +7 -0
- data/patterns/ecs-v1/nagios +124 -0
- data/patterns/ecs-v1/postgresql +2 -0
- data/patterns/ecs-v1/rails +13 -0
- data/patterns/ecs-v1/redis +3 -0
- data/patterns/ecs-v1/ruby +2 -0
- data/patterns/ecs-v1/squid +6 -0
- data/patterns/ecs-v1/zeek +33 -0
- data/patterns/{aws → legacy/aws} +1 -1
- data/patterns/{bacula → legacy/bacula} +5 -5
- data/patterns/legacy/bind +3 -0
- data/patterns/{bro → legacy/bro} +0 -0
- data/patterns/{exim → legacy/exim} +8 -2
- data/patterns/{firewalls → legacy/firewalls} +2 -2
- data/patterns/{grok-patterns → legacy/grok-patterns} +4 -4
- data/patterns/{haproxy → legacy/haproxy} +1 -1
- data/patterns/{httpd → legacy/httpd} +2 -2
- data/patterns/{java → legacy/java} +1 -3
- data/patterns/{junos → legacy/junos} +0 -0
- data/patterns/{linux-syslog → legacy/linux-syslog} +0 -0
- data/patterns/legacy/maven +1 -0
- data/patterns/{mcollective → legacy/mcollective} +0 -0
- data/patterns/{mcollective-patterns → legacy/mcollective-patterns} +0 -0
- data/patterns/{mongodb → legacy/mongodb} +0 -0
- data/patterns/{nagios → legacy/nagios} +1 -1
- data/patterns/{postgresql → legacy/postgresql} +0 -0
- data/patterns/{rails → legacy/rails} +0 -0
- data/patterns/{redis → legacy/redis} +0 -0
- data/patterns/{ruby → legacy/ruby} +0 -0
- data/patterns/legacy/squid +4 -0
- data/spec/patterns/aws_spec.rb +395 -0
- data/spec/patterns/bacula_spec.rb +367 -0
- data/spec/patterns/bind_spec.rb +92 -0
- data/spec/patterns/bro_spec.rb +613 -0
- data/spec/patterns/core_spec.rb +260 -15
- data/spec/patterns/exim_spec.rb +201 -0
- data/spec/patterns/firewalls_spec.rb +707 -66
- data/spec/patterns/haproxy_spec.rb +253 -28
- data/spec/patterns/httpd_spec.rb +248 -86
- data/spec/patterns/java_spec.rb +375 -0
- data/spec/patterns/junos_spec.rb +101 -0
- data/spec/patterns/mcollective_spec.rb +35 -0
- data/spec/patterns/mongodb_spec.rb +170 -33
- data/spec/patterns/nagios_spec.rb +299 -78
- data/spec/patterns/netscreen_spec.rb +123 -0
- data/spec/patterns/rails3_spec.rb +87 -29
- data/spec/patterns/redis_spec.rb +216 -140
- data/spec/patterns/shorewall_spec.rb +85 -74
- data/spec/patterns/squid_spec.rb +139 -0
- data/spec/patterns/syslog_spec.rb +266 -22
- data/spec/spec_helper.rb +83 -5
- metadata +70 -31
- data/patterns/bind +0 -3
- data/patterns/squid +0 -4
- data/spec/patterns/bro.rb +0 -126
- data/spec/patterns/s3_spec.rb +0 -173
data/spec/patterns/core_spec.rb
CHANGED
@@ -2,20 +2,20 @@
|
|
2
2
|
require "spec_helper"
|
3
3
|
require "logstash/patterns/core"
|
4
4
|
|
5
|
-
|
5
|
+
describe_pattern "SYSLOGLINE", ['legacy', 'ecs-v1'] do
|
6
|
+
|
7
|
+
let(:message) { "Mar 16 00:01:25 evita postfix/smtpd[1713]: connect from camomile.cloud9.net[168.100.1.3]" }
|
6
8
|
|
7
|
-
let(:value) { "Mar 16 00:01:25 evita postfix/smtpd[1713]: connect from camomile.cloud9.net[168.100.1.3]" }
|
8
|
-
let(:grok) { grok_match(subject, value) }
|
9
9
|
it "a pattern pass the grok expression" do
|
10
10
|
expect(grok).to pass
|
11
11
|
end
|
12
12
|
|
13
|
-
it "matches a simple message" do
|
14
|
-
expect(subject).to match(value)
|
15
|
-
end
|
16
|
-
|
17
13
|
it "generates the program field" do
|
18
|
-
|
14
|
+
if ecs_compatibility?
|
15
|
+
expect(grok).to include("process" => hash_including('name' => 'postfix/smtpd'))
|
16
|
+
else
|
17
|
+
expect(grok).to include("program" => "postfix/smtpd")
|
18
|
+
end
|
19
19
|
end
|
20
20
|
|
21
21
|
end
|
@@ -54,12 +54,16 @@ describe "HTTP DATE parsing" do
|
|
54
54
|
|
55
55
|
end
|
56
56
|
|
57
|
-
describe
|
58
|
-
|
59
|
-
|
57
|
+
describe 'LOGLEVEL' do
|
58
|
+
it 'matches info label' do
|
59
|
+
expect(grok_match(subject, 'INFO')).to pass
|
60
|
+
expect(grok_match(subject, 'info')).to pass
|
61
|
+
end
|
60
62
|
|
61
|
-
it
|
62
|
-
expect(grok_match(subject,
|
63
|
+
it 'matches information label' do
|
64
|
+
expect(grok_match(subject, 'information')).to pass
|
65
|
+
expect(grok_match(subject, 'Information')).to pass
|
66
|
+
expect(grok_match(subject, 'INFORMATION')).to pass
|
63
67
|
end
|
64
68
|
end
|
65
69
|
|
@@ -90,19 +94,209 @@ describe "UNIXPATH" do
|
|
90
94
|
let(:value) { '/foo/bar' }
|
91
95
|
|
92
96
|
it "should match the path" do
|
93
|
-
expect(grok_match(pattern,value)).to pass
|
97
|
+
expect(grok_match(pattern, value, true)).to pass
|
94
98
|
end
|
95
99
|
|
96
100
|
context "when using comma separators and other regexp" do
|
97
101
|
|
102
|
+
let(:pattern) { '((a=(?<a>%{UNIXPATH})?|b=(?<b>%{UNIXPATH})?)(,\s)?)+' }
|
103
|
+
|
104
|
+
let(:grok) do
|
105
|
+
grok = LogStash::Filters::Grok.new("match" => ["message", pattern])
|
106
|
+
grok.register
|
107
|
+
grok
|
108
|
+
end
|
109
|
+
|
98
110
|
let(:value) { 'a=/some/path, b=/some/other/path' }
|
99
111
|
|
112
|
+
it "was expected to extract both but never really did" do # or maybe on JRuby 1.7
|
113
|
+
event = build_event(value)
|
114
|
+
grok.filter(event)
|
115
|
+
expect( event.to_hash['a'] ).to eql '/some/path,'
|
116
|
+
expect( event.to_hash['b'] ).to be nil
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'relative path' do
|
122
|
+
|
123
|
+
let(:path_matcher) do # non-exact matcher
|
124
|
+
grok = LogStash::Filters::Grok.new("match" => ["message", '%{UNIXPATH:path}'])
|
125
|
+
grok.register
|
126
|
+
lambda { |msg| event = build_event(msg); grok.filter(event); event }
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should not match (only partially)" do
|
130
|
+
expect(grok_match(pattern, 'a/./b/c', true)).to_not pass
|
131
|
+
event = path_matcher.('a/./b/c')
|
132
|
+
expect( event.to_hash['path'] ).to eql '/./b/c'
|
133
|
+
|
134
|
+
expect(grok_match(pattern, ',/.', true)).to_not pass
|
135
|
+
event = path_matcher.(',/.')
|
136
|
+
expect( event.to_hash['path'] ).to eql '/.'
|
137
|
+
|
138
|
+
expect(grok_match(pattern, '+/.../', true)).to_not pass
|
139
|
+
event = path_matcher.('+/.../')
|
140
|
+
expect( event.to_hash['path'] ).to eql '/.../'
|
141
|
+
|
142
|
+
expect(grok_match(pattern, '~/b/', true)).to_not pass
|
143
|
+
event = path_matcher.('~/b/')
|
144
|
+
expect( event.to_hash['path'] ).to eql '/b/'
|
145
|
+
|
146
|
+
expect(grok_match(pattern, './b//', true)).to_not pass
|
147
|
+
expect(grok_match(pattern, 'a//b', true)).to_not pass
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should not match paths starting with ." do
|
151
|
+
expect(grok_match(pattern, '../0', true)).to_not pass
|
152
|
+
expect(grok_match(pattern, './~', true)).to_not pass
|
153
|
+
expect(grok_match(pattern, '.../-', true)).to_not pass
|
154
|
+
expect(grok_match(pattern, './', true)).to_not pass
|
155
|
+
expect(grok_match(pattern, './,', true)).to_not pass
|
156
|
+
expect(grok_match(pattern, '../', true)).to_not pass
|
157
|
+
expect(grok_match(pattern, '.a/', true)).to_not pass
|
158
|
+
expect(grok_match(pattern, '.~/', true)).to_not pass
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should not match expression wout separator" do
|
162
|
+
expect(grok_match(pattern, '.')).to_not pass
|
163
|
+
expect(grok_match(pattern, '..')).to_not pass
|
164
|
+
expect(grok_match(pattern, '...')).to_not pass
|
165
|
+
expect(grok_match(pattern, '.,')).to_not pass
|
166
|
+
expect(grok_match(pattern, '.-')).to_not pass
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
context "dotted path" do
|
172
|
+
|
173
|
+
it "should match path containing ." do
|
174
|
+
expect(grok_match(pattern, '/some/./path/', true)).to pass
|
175
|
+
expect(grok_match(pattern, '/some/../path', true)).to pass
|
176
|
+
expect(grok_match(pattern, '/../.', true)).to pass
|
177
|
+
expect(grok_match(pattern, '/.', true)).to pass
|
178
|
+
expect(grok_match(pattern, '/..', true)).to pass
|
179
|
+
expect(grok_match(pattern, '/...', true)).to pass
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
context "separators" do
|
185
|
+
|
186
|
+
it "should match root" do
|
187
|
+
expect(grok_match(pattern, '/', true)).to pass
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should match" do
|
191
|
+
expect(grok_match(pattern, '//', true)).to pass
|
192
|
+
expect(grok_match(pattern, '//00', true)).to pass
|
193
|
+
expect(grok_match(pattern, '///a', true)).to pass
|
194
|
+
expect(grok_match(pattern, '/a//', true)).to pass
|
195
|
+
expect(grok_match(pattern, '///a//b/c///', true)).to pass
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should not match windows separator" do
|
199
|
+
expect(grok_match(pattern, "\\a", true)).to_not pass
|
200
|
+
expect(grok_match(pattern, '/0\\', true)).to_not pass
|
201
|
+
expect(grok_match(pattern, "/a\\b", true)).to_not pass
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
context "long path" do
|
207
|
+
|
208
|
+
let(:grok) do
|
209
|
+
grok = LogStash::Filters::Grok.new("match" => ["message", '%{UNIXPATH:path} '], 'timeout_millis' => 1500)
|
210
|
+
grok.register
|
211
|
+
grok
|
212
|
+
end
|
213
|
+
|
214
|
+
let(:value) { '/opt/abcdef/1/.22/3:3+3/foo@BAR/X-Y+Z/~Sample_l_SUBc b' }
|
215
|
+
|
100
216
|
it "should match the path" do
|
101
|
-
|
217
|
+
event = build_event(value)
|
218
|
+
grok.filter(event)
|
219
|
+
expect( event.to_hash['path'] ).to eql '/opt/abcdef/1/.22/3:3+3/foo@BAR/X-Y+Z/~Sample_l_SUBc'
|
102
220
|
end
|
221
|
+
|
222
|
+
it "should not match with invalid chars (or cause DoS)" do
|
223
|
+
event = build_event(value.sub('SUB', '&^_'))
|
224
|
+
grok.filter(event) # used to call a looong looop (DoS) despite the timeout guard
|
225
|
+
expect( event.to_hash['tags'] ).to include '_grokparsefailure'
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
it "matches paths with non-ascii characters" do
|
230
|
+
event = build_event path = '/opt/Čierný_Peter/.中'
|
231
|
+
build_grok('UNIXPATH:path').filter event
|
232
|
+
expect( event.get('path') ).to eql path
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|
236
|
+
|
237
|
+
describe "WINPATH" do
|
238
|
+
|
239
|
+
let(:pattern) { 'WINPATH' }
|
240
|
+
let(:value) { 'C:\\foo\\bar' }
|
241
|
+
|
242
|
+
it "should match the path" do
|
243
|
+
expect(grok_match(pattern, value, true)).to pass
|
244
|
+
end
|
245
|
+
|
246
|
+
it "should match root path" do
|
247
|
+
expect(grok_match(pattern, 'C:\\', true)).to pass
|
248
|
+
expect(grok_match(pattern, 'C:\\\\', true)).to pass
|
249
|
+
expect(grok_match(pattern, 'a:\\', true)).to pass
|
250
|
+
expect(grok_match(pattern, 'x:\\\\', true)).to pass
|
251
|
+
end
|
252
|
+
|
253
|
+
it "should match paths with spaces" do
|
254
|
+
expect(grok_match(pattern, 'C:\\Documents and Settings\\Public', true)).to pass
|
255
|
+
expect(grok_match(pattern, 'C:\\\\Users\\\\Public\\\\.Mozilla Firefox', true)).to pass
|
256
|
+
end
|
257
|
+
|
258
|
+
it "should not match unix-style paths" do
|
259
|
+
expect(grok_match(pattern, '/foo', true)).to_not pass
|
260
|
+
expect(grok_match(pattern, '//C/path', true)).to_not pass
|
261
|
+
expect(grok_match(pattern, '/', true)).to_not pass
|
262
|
+
expect(grok_match(pattern, '/foo/bar', true)).to_not pass
|
263
|
+
expect(grok_match(pattern, '/..', true)).to_not pass
|
264
|
+
expect(grok_match(pattern, 'C://', true)).to_not pass
|
265
|
+
end
|
266
|
+
|
267
|
+
it "matches paths with non-ascii characters" do
|
268
|
+
expect(grok_match(pattern, 'C:\\Čierný Peter\\.中.exe', true)).to pass
|
269
|
+
end
|
270
|
+
|
271
|
+
context 'relative paths' do
|
272
|
+
|
273
|
+
it "should not match" do
|
274
|
+
expect(grok_match(pattern, 'a\\bar', true)).to_not pass
|
275
|
+
expect(grok_match(pattern, 'foo\\bar', true)).to_not pass
|
276
|
+
expect(grok_match(pattern, 'C\\A\\B', true)).to_not pass
|
277
|
+
expect(grok_match(pattern, 'C\\\\0', true)).to_not pass
|
278
|
+
expect(grok_match(pattern, '.\\0', true)).to_not pass
|
279
|
+
expect(grok_match(pattern, '..\\', true)).to_not pass
|
280
|
+
expect(grok_match(pattern, '...\\-', true)).to_not pass
|
281
|
+
expect(grok_match(pattern, '.\\', true)).to_not pass
|
282
|
+
expect(grok_match(pattern, '.\\,', true)).to_not pass
|
283
|
+
expect(grok_match(pattern, '..\\', true)).to_not pass
|
284
|
+
expect(grok_match(pattern, '.a\\', true)).to_not pass
|
285
|
+
end
|
286
|
+
|
287
|
+
it "should not match expression wout separator" do
|
288
|
+
expect(grok_match(pattern, '.')).to_not pass
|
289
|
+
expect(grok_match(pattern, '..')).to_not pass
|
290
|
+
expect(grok_match(pattern, '...')).to_not pass
|
291
|
+
expect(grok_match(pattern, 'C:')).to_not pass
|
292
|
+
expect(grok_match(pattern, 'C')).to_not pass
|
293
|
+
end
|
294
|
+
|
103
295
|
end
|
296
|
+
|
104
297
|
end
|
105
298
|
|
299
|
+
|
106
300
|
describe "URIPROTO" do
|
107
301
|
let(:pattern) { 'URIPROTO' }
|
108
302
|
|
@@ -292,3 +486,54 @@ describe "URN" do
|
|
292
486
|
end
|
293
487
|
end
|
294
488
|
end
|
489
|
+
|
490
|
+
describe_pattern "EMAILADDRESS", ['legacy', 'ecs-v1'] do
|
491
|
+
|
492
|
+
# NOTE: EMAILLOCALPART was only updated in ECS mode, as following the RFC is
|
493
|
+
# actually a breaking change -> legacy does match incorrect e-mail addresses.
|
494
|
+
|
495
|
+
it "matches 'hello.world@123.net' address" do
|
496
|
+
expect(grok_exact_match(pattern, 'hello.world@123.net')).to pass
|
497
|
+
end
|
498
|
+
|
499
|
+
[
|
500
|
+
'a@example.com',
|
501
|
+
'a{b}@example.com',
|
502
|
+
'Foo+Bar@x.exposed',
|
503
|
+
].each do |valid_email|
|
504
|
+
it "matches #{valid_email.inspect} address" do
|
505
|
+
expect(grok_exact_match(pattern, valid_email)).to pass if ecs_compatibility?
|
506
|
+
end
|
507
|
+
end
|
508
|
+
|
509
|
+
it "does not match 'x y@example.com' address" do
|
510
|
+
expect(grok_exact_match(pattern, 'hello.world@123.net')).to pass
|
511
|
+
end
|
512
|
+
|
513
|
+
[
|
514
|
+
'a:b@example.com',
|
515
|
+
'a..b@example.com',
|
516
|
+
].each do |invalid_email|
|
517
|
+
it "does not match #{invalid_email.inspect} address" do
|
518
|
+
expect(grok_exact_match(pattern, invalid_email)).to_not pass if ecs_compatibility?
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
it "matches e-mail with digits only local-part" do
|
523
|
+
expect(grok_exact_match(pattern, '00@q.ro')).to pass if ecs_compatibility?
|
524
|
+
end
|
525
|
+
|
526
|
+
it "matches e-mail with 64 chars in local-part" do
|
527
|
+
expect(grok_exact_match(pattern, ('ab' * 32) + '@root.cz')).to pass
|
528
|
+
expect(grok_exact_match(pattern, ('a.bc' * 16) + '@00.cz')).to pass
|
529
|
+
end
|
530
|
+
|
531
|
+
it "does not match e-mail with more than 64 char length local-part" do
|
532
|
+
if ecs_compatibility?
|
533
|
+
expect(grok_exact_match(pattern, ('ab' * 32) + 'a' + '@root.cz')).to_not pass
|
534
|
+
# NOTE: we allow longer with '.' but at least we limit "too long" :
|
535
|
+
expect(grok_exact_match(pattern, ('a.bc' * 64) + '@00.cz')).to_not pass
|
536
|
+
end
|
537
|
+
end
|
538
|
+
|
539
|
+
end
|
@@ -0,0 +1,201 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
require "logstash/patterns/core"
|
4
|
+
|
5
|
+
describe_pattern 'EXIM', ['legacy', 'ecs-v1'] do
|
6
|
+
|
7
|
+
context 'message arrival (old)' do
|
8
|
+
|
9
|
+
let(:message) do
|
10
|
+
"1995-10-31 08:57:53 0tACW1-0005MB-00 <= kryten@dwarf.fict.example H=mailer.fict.example [192.168.123.123] " +
|
11
|
+
"U=exim P=smtp S=5678 id=f828ca60127d8646a0fa75cbf8db9ba3@dwarf.fict.example"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "matches" do
|
15
|
+
expect(grok).to include("timestamp" => "1995-10-31 08:57:53")
|
16
|
+
|
17
|
+
if ecs_compatibility?
|
18
|
+
expect(grok).to include("exim"=>{"log"=>{
|
19
|
+
"flags"=>"<=",
|
20
|
+
"sender"=>{"email"=>"kryten@dwarf.fict.example"},
|
21
|
+
"message"=>{"id"=>"0tACW1-0005MB-00", "size"=>5678},
|
22
|
+
"header_id"=>"f828ca60127d8646a0fa75cbf8db9ba3@dwarf.fict.example"
|
23
|
+
}})
|
24
|
+
expect(grok).to include("source"=>{"address"=>"mailer.fict.example", "ip"=>"192.168.123.123"})
|
25
|
+
expect(grok).to include("network"=>{"protocol"=>"smtp"})
|
26
|
+
else
|
27
|
+
expect(grok).to include("exim_year" => "1995", "exim_month" => "10", "exim_day" => "31", "@version" => "1", "exim_time" => "08:57:53")
|
28
|
+
expect(grok.keys).to_not include("pid")
|
29
|
+
expect(grok).to include("exim_sender_email" => "kryten@dwarf.fict.example")
|
30
|
+
expect(grok).to include("exim_flags" => "<=")
|
31
|
+
expect(grok).to include("exim_msg_size" => "5678")
|
32
|
+
expect(grok).to include("exim_msgid" => "0tACW1-0005MB-00")
|
33
|
+
expect(grok).to include("remote_hostname" => "mailer.fict.example", "remote_host" => "192.168.123.123")
|
34
|
+
expect(grok).to include("protocol" => "smtp")
|
35
|
+
expect(grok).to include("exim_header_id" => "f828ca60127d8646a0fa75cbf8db9ba3@dwarf.fict.example")
|
36
|
+
end
|
37
|
+
|
38
|
+
expect(grok).to include("message" => message)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'message arrival (new)' do
|
44
|
+
let(:message) do
|
45
|
+
'2010-09-13 05:00:13 [1487] 1Ov4tU-0000Nz-Rm <= mailling.list@domain.com ' +
|
46
|
+
'H=mailhost.domain.com [208.42.54.2]:51792 I=[67.215.162.175]:25 P=esmtps X=TLSv1:AES256-SHA:256 CV=no S=21778 ' +
|
47
|
+
'id=384a86a39e83be0d9b3a94d1feb3119f@domain.com T="Daily List: Chameleon" for user@example.com'
|
48
|
+
end
|
49
|
+
|
50
|
+
it "matches" do
|
51
|
+
expect(grok).to include("timestamp" => "2010-09-13 05:00:13") # new in legacy mode
|
52
|
+
|
53
|
+
if ecs_compatibility?
|
54
|
+
expect(grok).to include("process"=>{"pid"=>1487})
|
55
|
+
expect(grok).to include("exim"=>{"log"=>hash_including(
|
56
|
+
"message"=>{"id"=>"1Ov4tU-0000Nz-Rm", "size"=>21778, "subject"=>"Daily List: Chameleon"},
|
57
|
+
"flags"=>"<=",
|
58
|
+
"header_id"=>"384a86a39e83be0d9b3a94d1feb3119f@domain.com",
|
59
|
+
"sender"=>{"email"=>"mailling.list@domain.com"},
|
60
|
+
"recipient"=>{"email"=>"user@example.com"},
|
61
|
+
)})
|
62
|
+
expect(grok).to include("source"=>{"address"=>"mailhost.domain.com", "ip"=>"208.42.54.2", "port"=>51792})
|
63
|
+
expect(grok).to include("destination"=>{"ip"=>"67.215.162.175", "port"=>25})
|
64
|
+
else
|
65
|
+
|
66
|
+
expect(grok).to include("exim_year" => "2010", "exim_month" => "09", "exim_day" => "13", "exim_time" => "05:00:13")
|
67
|
+
expect(grok).to include("pid" => "1487") # new
|
68
|
+
expect(grok).to include("exim_sender_email" => "mailling.list@domain.com") # new
|
69
|
+
expect(grok).to include("remote_hostname" => "mailhost.domain.com", "remote_host" => "208.42.54.2", "remote_port" => "51792") # (remote_port) new
|
70
|
+
expect(grok).to include("exim_interface" => "67.215.162.175", "exim_interface_port" => "25")
|
71
|
+
expect(grok).to include("protocol" => "esmtps")
|
72
|
+
expect(grok).to include("exim_msg_size" => "21778")
|
73
|
+
expect(grok).to include("exim_header_id" => "384a86a39e83be0d9b3a94d1feb3119f@domain.com")
|
74
|
+
expect(grok).to include("exim_subject" => '"Daily List: Chameleon"')
|
75
|
+
expect(grok).to include("exim_recipient_email" => "user@example.com") # new
|
76
|
+
end
|
77
|
+
|
78
|
+
expect(grok).to include("message" => message)
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'message arrival (simple)' do
|
84
|
+
|
85
|
+
let(:message) do
|
86
|
+
'2020-02-11 17:09:46 1j1Z2g-00Faoy-Uh <= example@strawberry.active-ns.com U=example P=local ' +
|
87
|
+
'T="[Examples Galore] Please moderate: \"Hello world!\"" for admin@example.net'
|
88
|
+
end
|
89
|
+
|
90
|
+
it "matches" do
|
91
|
+
expect(grok).to include("timestamp"=>"2020-02-11 17:09:46")
|
92
|
+
if ecs_compatibility?
|
93
|
+
expect(grok).to include("exim"=>{"log"=>{
|
94
|
+
"flags"=>"<=",
|
95
|
+
"message"=>{"id"=>"1j1Z2g-00Faoy-Uh", "subject"=>'[Examples Galore] Please moderate: \\"Hello world!\\"'},
|
96
|
+
"sender"=>{"email"=>"example@strawberry.active-ns.com"},
|
97
|
+
"recipient"=>{"email"=>"admin@example.net"}
|
98
|
+
}})
|
99
|
+
expect(grok).to include("network"=>{"protocol"=>"local"})
|
100
|
+
else
|
101
|
+
expect(grok).to include(
|
102
|
+
"exim_msgid"=>"1j1Z2g-00Faoy-Uh",
|
103
|
+
"exim_sender_email"=>"example@strawberry.active-ns.com",
|
104
|
+
"exim_flags"=>"<=",
|
105
|
+
"protocol"=>"local",
|
106
|
+
"exim_subject"=>"\"[Examples Galore] Please moderate: \\\"Hello world!\\\"\""
|
107
|
+
)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
context 'message arrival with quoted hostname' do
|
114
|
+
|
115
|
+
let(:message) do
|
116
|
+
'2013-03-20 12:44:02 1UIIN7-0004t9-8R <= root@example.com ' +
|
117
|
+
'H=localhost (hostname.example.com) [127.0.0.1] ' +
|
118
|
+
'P=esmtps X=TLSv1:DHE-RSA-AES256-SHA:256 S=811 id=201303201244.r2KCi11V018784@hostname.example.com'
|
119
|
+
end
|
120
|
+
|
121
|
+
it "matches" do
|
122
|
+
expect(grok).to include("timestamp"=>"2013-03-20 12:44:02")
|
123
|
+
|
124
|
+
if ecs_compatibility?
|
125
|
+
expect(grok).to include("exim"=>{"log"=>hash_including(
|
126
|
+
"sender"=>{ "email"=>"root@example.com" },
|
127
|
+
"message"=>{ "id"=>"1UIIN7-0004t9-8R", "size"=>811 },
|
128
|
+
"header_id"=>"201303201244.r2KCi11V018784@hostname.example.com",
|
129
|
+
"remote_address"=>"hostname.example.com")})
|
130
|
+
expect(grok).to include("source"=>{"address"=>"localhost", "ip"=>"127.0.0.1"})
|
131
|
+
expect(grok).to include("network"=>{"protocol"=>"esmtps"})
|
132
|
+
else
|
133
|
+
expect(grok).to include(
|
134
|
+
"exim_msgid"=>"1UIIN7-0004t9-8R",
|
135
|
+
"exim_sender_email"=>"root@example.com",
|
136
|
+
"exim_flags"=>"<=",
|
137
|
+
"protocol"=>"esmtps",
|
138
|
+
"exim_header_id"=>"201303201244.r2KCi11V018784@hostname.example.com"
|
139
|
+
)
|
140
|
+
expect(grok).to include(
|
141
|
+
"remote_host"=>"127.0.0.1",
|
142
|
+
"remote_heloname"=>"hostname.example.com",
|
143
|
+
"remote_hostname"=>"localhost"
|
144
|
+
)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
context 'message arrival with quoted hostname and port' do
|
152
|
+
|
153
|
+
let(:message) do
|
154
|
+
'2014-08-10 11:18:35 [28107] 1gsu1C-003dCu-Hb <= aaron@domain.com ' +
|
155
|
+
'H=localhost (10.5.40.204) [127.0.0.1]:39753 I=[127.0.0.1]:25 ' +
|
156
|
+
'P=esmtpa A=dovecot_plain:aaron@domain.com S=4315 M8S=0 id=d2b648f00f1a1b0813c483d552778dc6@domain.com ' +
|
157
|
+
"T=\"what's up?!? ;-)\" from <aaron@domain.com> for aaron+forward@domain.com"
|
158
|
+
end
|
159
|
+
|
160
|
+
it "matches" do
|
161
|
+
if ecs_compatibility?
|
162
|
+
expect(grok).to include("exim"=>{"log"=>hash_including(
|
163
|
+
"message"=>hash_including("id"=>"1gsu1C-003dCu-Hb", "subject"=>"what's up?!? ;-)"),
|
164
|
+
)})
|
165
|
+
expect(grok).to include("destination"=>{"ip"=>"127.0.0.1", "port"=>25})
|
166
|
+
expect(grok).to include("exim"=>{"log"=>hash_including(
|
167
|
+
"sender"=>{"email"=>"aaron@domain.com", 'original'=>'aaron@domain.com'}
|
168
|
+
)})
|
169
|
+
expect(grok).to include("exim"=>{"log"=>hash_including("recipient"=>{"email"=>"aaron+forward@domain.com"})})
|
170
|
+
expect(grok).to include("source"=>{"address"=>"localhost", "ip"=>"127.0.0.1", "port"=>39753})
|
171
|
+
expect(grok).to include("exim"=>{"log" => hash_including("remote_address"=>'10.5.40.204')})
|
172
|
+
else
|
173
|
+
expect(grok).to include(
|
174
|
+
"exim_msgid"=>"1gsu1C-003dCu-Hb",
|
175
|
+
"exim_sender_email"=>"aaron@domain.com",
|
176
|
+
"exim_flags"=>"<=",
|
177
|
+
"protocol"=>"esmtpa"
|
178
|
+
)
|
179
|
+
expect(grok).to include(
|
180
|
+
"remote_host"=>"127.0.0.1", "remote_port"=>"39753",
|
181
|
+
"remote_heloname"=>"10.5.40.204",
|
182
|
+
"remote_hostname"=>"localhost"
|
183
|
+
)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
context 'delivery failed' do
|
190
|
+
|
191
|
+
let(:message) do
|
192
|
+
'2020-02-11 17:09:47 1j1Z2g-00Faoy-Uh ** admin@example.net R=virtual_aliases: No such person at this address.'
|
193
|
+
end
|
194
|
+
|
195
|
+
it "does not parse" do # matching not implemented
|
196
|
+
expect(grok['tags']).to include("_grokparsefailure")
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|