logstash-patterns-core 4.1.2 → 4.3.2
Sign up to get free protection for your applications and to get access to all the features.
- 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/httpd_spec.rb
CHANGED
@@ -2,142 +2,304 @@
|
|
2
2
|
require "spec_helper"
|
3
3
|
require "logstash/patterns/core"
|
4
4
|
|
5
|
-
|
5
|
+
describe_pattern "HTTPD_COMBINEDLOG", ['legacy', 'ecs-v1'] do
|
6
6
|
|
7
|
-
context "
|
7
|
+
context "typical test case" do
|
8
8
|
|
9
|
-
let(:
|
9
|
+
let(:message) { '83.149.9.216 - - [24/Feb/2015:23:13:42 +0000] "GET /presentations/logstash-monitorama-2013/images/kibana-search.png HTTP/1.1" 200 203023 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"'}
|
10
10
|
|
11
|
-
it "
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
11
|
+
it "matches" do
|
12
|
+
if ecs_compatibility?
|
13
|
+
expect(grok).to include(
|
14
|
+
"http" => {
|
15
|
+
"request" => {
|
16
|
+
"method" => "GET",
|
17
|
+
"referrer" => "http://semicomplete.com/presentations/logstash-monitorama-2013/"
|
18
|
+
},
|
19
|
+
"response" => {
|
20
|
+
"body" => { "bytes" => 203023 },
|
21
|
+
"status_code" => 200
|
22
|
+
},
|
23
|
+
"version"=>"1.1"
|
24
|
+
},
|
25
|
+
"source" => { "address" => "83.149.9.216" },
|
26
|
+
"url" => { "original" => "/presentations/logstash-monitorama-2013/images/kibana-search.png" },
|
27
|
+
"user_agent" => { "original" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36" }
|
28
|
+
)
|
29
|
+
else
|
30
|
+
expect(grok).to include(
|
31
|
+
'clientip' => '83.149.9.216',
|
32
|
+
'verb' => 'GET',
|
33
|
+
'request' => '/presentations/logstash-monitorama-2013/images/kibana-search.png',
|
34
|
+
'httpversion' => '1.1',
|
35
|
+
'response' => '200',
|
36
|
+
'bytes' => '203023',
|
37
|
+
'referrer' => '"http://semicomplete.com/presentations/logstash-monitorama-2013/"',
|
38
|
+
'agent' => '"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"'
|
39
|
+
)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it "does not capture 'null' fields" do
|
44
|
+
if ecs_compatibility?
|
45
|
+
expect(grok.keys).to_not include('user') # 'user' => 'name'
|
46
|
+
expect(grok.keys).to_not include('apache') # apache.access.user.identity
|
47
|
+
else
|
48
|
+
expect(grok).to include('auth' => '-', 'ident' => '-')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
context "email address in auth field" do
|
55
|
+
|
56
|
+
let(:message) { '10.0.0.1 - username@example.com [07/Apr/2016:18:42:24 +0000] "GET /bar/foo/users/1/username%40example.com/authenticate?token=blargh&client_id=15 HTTP/1.1" 400 75 "" "Mozilla/5.0 (iPad; CPU OS 9_3_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13E238 Safari/601.1"'}
|
57
|
+
|
58
|
+
it "gets captured" do
|
59
|
+
if ecs_compatibility?
|
60
|
+
expect(grok).to include("user" => { 'name' => "username@example.com" })
|
61
|
+
else
|
62
|
+
expect(grok).to include("auth" => "username@example.com")
|
63
|
+
end
|
22
64
|
end
|
23
65
|
|
24
66
|
end
|
25
67
|
|
26
|
-
context
|
68
|
+
context 'sample OPTIONS line' do
|
69
|
+
|
70
|
+
let(:message) { '83.149.9.216 - a.user [11/Jan/2020:23:05:27 +0100] "OPTIONS /remote.php/ HTTP/1.1" - 7908 "-" "monitoring-client (v2.2)"' }
|
27
71
|
|
28
|
-
|
72
|
+
it 'matches' do
|
73
|
+
if ecs_compatibility?
|
74
|
+
expect(grok).to include("http" => hash_including("response" => hash_including("body" => { "bytes" => 7908 })))
|
75
|
+
expect(grok).to include("http" => hash_including("request" => { "method" => "OPTIONS" }, "version" => "1.1"))
|
76
|
+
expect(grok).to include(
|
77
|
+
"url" => { "original" => "/remote.php/" },
|
78
|
+
"user_agent" => { "original" => "monitoring-client (v2.2)" }
|
79
|
+
)
|
80
|
+
else
|
81
|
+
expect(grok).to include("verb" => "OPTIONS", 'request' => '/remote.php/', 'httpversion' => '1.1', "bytes" => '7908')
|
82
|
+
end
|
83
|
+
end
|
29
84
|
|
30
|
-
it
|
31
|
-
|
85
|
+
it 'does not capture optional response code' do
|
86
|
+
if ecs_compatibility?
|
87
|
+
expect(grok['http']['response'].keys).to_not include("status_code")
|
88
|
+
else
|
89
|
+
expect(grok.keys).to_not include("response")
|
90
|
+
end
|
32
91
|
end
|
33
92
|
|
34
93
|
end
|
35
94
|
|
36
95
|
end
|
37
96
|
|
38
|
-
|
97
|
+
describe_pattern "HTTPD_ERRORLOG", ['legacy', 'ecs-v1'] do
|
39
98
|
|
40
|
-
context "
|
41
|
-
let(:
|
99
|
+
context "a full httpd 2.4 message" do
|
100
|
+
let(:message) do
|
42
101
|
"[Mon Aug 31 09:30:48.958285 2015] [proxy_fcgi:error] [pid 28787:tid 140169587934976] (70008)Partial results are valid but processing is incomplete: [client 58.13.45.166:59307] AH01075: Error dispatching request to : (reading input brigade), referer: http://example.com/index.php?id_product=11&controller=product"
|
43
|
-
|
44
|
-
it "generates the fields" do
|
102
|
+
end
|
45
103
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
104
|
+
it "generates the fields" do
|
105
|
+
expect(grok).to include('timestamp' => 'Mon Aug 31 09:30:48.958285 2015')
|
106
|
+
if ecs_compatibility?
|
107
|
+
expect(grok).to include("log" => { "level" => "error" })
|
108
|
+
expect(grok).to include("process" => { "pid" => 28787, "thread" => { "id" => 140169587934976 } })
|
109
|
+
expect(grok).to include("source" => { "address"=>"58.13.45.166", "port" => 59307 })
|
110
|
+
expect(grok).to include("error" => { "code" => 'AH01075' })
|
111
|
+
expect(grok).to include("apache" => { "error" => {
|
112
|
+
"module" => "proxy_fcgi",
|
113
|
+
"proxy" => { "error" => { "code" => '70008', "message" => "Partial results are valid but processing is incomplete" }}}
|
114
|
+
})
|
115
|
+
else
|
116
|
+
expect(grok).to include(
|
117
|
+
'timestamp' => 'Mon Aug 31 09:30:48.958285 2015',
|
118
|
+
'module' => 'proxy_fcgi',
|
119
|
+
'loglevel' => 'error',
|
120
|
+
'pid' => '28787',
|
121
|
+
'tid' => '140169587934976',
|
122
|
+
'proxy_errorcode' => '70008',
|
123
|
+
'proxy_message' => 'Partial results are valid but processing is incomplete',
|
124
|
+
'clientip' => '58.13.45.166',
|
125
|
+
'clientport' => '59307',
|
126
|
+
'errorcode' => 'AH01075'
|
127
|
+
)
|
128
|
+
end
|
129
|
+
expect(grok).to include('message' => [ message, 'Error dispatching request to : (reading input brigade), referer: http://example.com/index.php?id_product=11&controller=product' ])
|
59
130
|
end
|
60
131
|
end
|
61
132
|
|
62
|
-
context "
|
63
|
-
let(:
|
133
|
+
context "a httpd 2.2 log message" do
|
134
|
+
let(:message) do
|
64
135
|
"[Mon Aug 31 16:27:04 2015] [error] [client 10.17.42.3] Premature end of script headers: example.com"
|
65
|
-
|
136
|
+
end
|
137
|
+
|
66
138
|
it "generates the fields" do
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
139
|
+
if ecs_compatibility?
|
140
|
+
expect(grok).to include(
|
141
|
+
"timestamp"=>"Mon Aug 31 16:27:04 2015",
|
142
|
+
"log"=>{"level"=>"error"},
|
143
|
+
"source"=>{"address"=>"10.17.42.3"})
|
144
|
+
expect(grok.keys).to_not include("error") # error.code
|
145
|
+
else
|
146
|
+
expect(grok).to include(
|
147
|
+
'timestamp' => 'Mon Aug 31 16:27:04 2015',
|
148
|
+
'loglevel' => 'error',
|
149
|
+
'clientip' => '10.17.42.3'
|
150
|
+
)
|
151
|
+
expect(grok.keys).to_not include('errorcode')
|
152
|
+
end
|
153
|
+
expect(grok).to include('message' => [ message, 'Premature end of script headers: example.com' ])
|
73
154
|
end
|
74
155
|
end
|
75
156
|
|
76
|
-
context "
|
157
|
+
context "a short httpd 2.4 message" do
|
77
158
|
let(:value1) {
|
78
159
|
"[Mon Aug 31 07:15:38.664897 2015] [proxy_fcgi:error] [pid 28786:tid 140169629898496] [client 81.139.1.34:52042] AH01071: Got error 'Primary script unknown\n'"
|
79
160
|
}
|
80
161
|
it "generates the fields" do
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
162
|
+
match_result = grok_match(pattern, value1)
|
163
|
+
expect(match_result).to include('timestamp' => 'Mon Aug 31 07:15:38.664897 2015')
|
164
|
+
if ecs_compatibility?
|
165
|
+
expect(match_result).to include(
|
166
|
+
"apache"=>{"error"=>{"module"=>"proxy_fcgi"}},
|
167
|
+
"log"=>{"level"=>"error"},
|
168
|
+
"process"=>{"pid"=>28786, "thread"=>{"id"=>140169629898496}},
|
169
|
+
"source"=>{"address"=>"81.139.1.34", "port"=>52042},
|
170
|
+
"error"=>{"code"=>"AH01071"},
|
171
|
+
)
|
172
|
+
else
|
173
|
+
expect(match_result).to include(
|
174
|
+
'module' => 'proxy_fcgi',
|
175
|
+
'loglevel' => 'error',
|
176
|
+
'pid' => '28786',
|
177
|
+
'tid' => '140169629898496',
|
178
|
+
'clientip' => '81.139.1.34',
|
179
|
+
'clientport' => '52042',
|
180
|
+
'errorcode' => 'AH01071'
|
181
|
+
)
|
182
|
+
end
|
183
|
+
expect(match_result).to include('message' => [ value1, "Got error 'Primary script unknown\n'" ])
|
92
184
|
end
|
93
185
|
|
94
186
|
let(:value2) {
|
95
187
|
"[Thu Apr 27 10:39:46.719636 2017] [php7:notice] [pid 17] [client 10.255.0.3:49580] Test error log record"
|
96
188
|
}
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
189
|
+
it "generates the fields" do
|
190
|
+
match_result = grok_match(pattern, value2)
|
191
|
+
expect(match_result).to include('timestamp' => 'Thu Apr 27 10:39:46.719636 2017')
|
192
|
+
if ecs_compatibility?
|
193
|
+
expect(match_result).to include(
|
194
|
+
"apache"=>{"error"=>{"module"=>"php7"}},
|
195
|
+
"log"=>{"level"=>"notice"},
|
196
|
+
"process"=>{"pid"=>17},
|
197
|
+
"source"=>{"port"=>49580, "address"=>"10.255.0.3"}
|
198
|
+
)
|
199
|
+
else
|
200
|
+
expect(match_result).to include(
|
201
|
+
'module' => 'php7',
|
202
|
+
'loglevel' => 'notice',
|
203
|
+
'pid' => '17',
|
204
|
+
'clientip' => '10.255.0.3',
|
205
|
+
'clientport' => '49580'
|
206
|
+
)
|
207
|
+
end
|
208
|
+
expect(match_result).to include('message' => [ value2, "Test error log record" ])
|
107
209
|
end
|
108
210
|
end
|
109
211
|
|
110
|
-
context "
|
212
|
+
context "a httpd 2.4 restart message" do
|
111
213
|
let(:value1) {
|
112
214
|
"[Mon Aug 31 06:29:47.406518 2015] [mpm_event:notice] [pid 24968:tid 140169861986176] AH00489: Apache/2.4.16 (Ubuntu) configured -- resuming normal operations"
|
113
215
|
}
|
114
216
|
it "generates the fields" do
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
217
|
+
match_result = grok_match(pattern, value1)
|
218
|
+
expect(match_result).to include('timestamp' => 'Mon Aug 31 06:29:47.406518 2015')
|
219
|
+
if ecs_compatibility?
|
220
|
+
expect(match_result).to include(
|
221
|
+
"apache"=>{"error"=>{"module"=>"mpm_event"}},
|
222
|
+
"log"=>{"level"=>"notice"},
|
223
|
+
"process"=>{"pid"=>24968, "thread"=>{"id"=>140169861986176}},
|
224
|
+
"error"=>{"code"=>"AH00489"}
|
225
|
+
)
|
226
|
+
|
227
|
+
else
|
228
|
+
expect(match_result).to include(
|
229
|
+
'module' => 'mpm_event',
|
230
|
+
'loglevel' => 'notice',
|
231
|
+
'pid' => '24968',
|
232
|
+
'tid' => '140169861986176',
|
233
|
+
'errorcode' => 'AH00489'
|
234
|
+
)
|
235
|
+
end
|
236
|
+
expect(match_result).to include('message' => [ value1, 'Apache/2.4.16 (Ubuntu) configured -- resuming normal operations' ])
|
124
237
|
end
|
125
238
|
|
126
239
|
let(:value2) {
|
127
240
|
"[Mon Aug 31 06:29:47.406530 2015] [core:notice] [pid 24968:tid 140169861986176] AH00094: Command line: '/usr/sbin/apache2'"
|
128
241
|
}
|
129
242
|
it "generates the fields" do
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
243
|
+
match_result = grok_match(pattern, value2)
|
244
|
+
expect(match_result).to include('timestamp' => 'Mon Aug 31 06:29:47.406530 2015')
|
245
|
+
if ecs_compatibility?
|
246
|
+
expect(match_result).to include(
|
247
|
+
"apache"=>{"error"=>{"module"=>"core"}},
|
248
|
+
"log"=>{"level"=>"notice"},
|
249
|
+
"process"=>{"pid"=>24968, "thread"=>{"id"=>140169861986176}},
|
250
|
+
"error"=>{"code"=>"AH00094"}
|
251
|
+
)
|
252
|
+
else
|
253
|
+
expect(match_result).to include(
|
254
|
+
'module' => 'core',
|
255
|
+
'loglevel' => 'notice',
|
256
|
+
'pid' => '24968',
|
257
|
+
'tid' => '140169861986176',
|
258
|
+
'errorcode' => 'AH00094'
|
259
|
+
)
|
260
|
+
end
|
261
|
+
expect(match_result).to include('message' => [ value2, 'Command line: \'/usr/sbin/apache2\'' ])
|
139
262
|
end
|
140
263
|
end
|
141
264
|
|
265
|
+
context "a httpd 2.4 message witout module" do
|
266
|
+
let(:message) do
|
267
|
+
"[Tue Apr 14 14:27:52.605084 2020] [:error] [pid 5688] [client 192.168.10.110:8196] script '/login/wp-login.php' not found or unable to stat"
|
268
|
+
end
|
269
|
+
|
270
|
+
it "matches" do
|
271
|
+
expect(grok).to include('timestamp' => 'Tue Apr 14 14:27:52.605084 2020')
|
272
|
+
if ecs_compatibility?
|
273
|
+
expect(grok).to include("log"=>{"level" => "error"})
|
274
|
+
expect(grok).to include("process"=>{"pid" => 5688})
|
275
|
+
expect( ((grok['apache'] || {})['error'] || {}).keys ).to_not include('module')
|
276
|
+
else
|
277
|
+
expect(grok).to include('loglevel' => 'error', 'pid' => '5688')
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
context 'a debug message' do
|
283
|
+
let(:message) do
|
284
|
+
'[Fri Feb 01 22:03:08.319124 2019] [authz_core:debug] [pid 9:tid 140597881775872] mod_authz_core.c(820): [client 172.17.0.1:50752] AH01626: authorization result of <RequireAny>: granted'
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'matches imperfectly (legacy)' do
|
288
|
+
if ecs_compatibility?
|
289
|
+
pending
|
290
|
+
raise NotImplementedError, "TODO: would be nice to 'improve' matching on these debug logs as well"
|
291
|
+
else
|
292
|
+
expect(grok).to include({
|
293
|
+
"timestamp"=>"Fri Feb 01 22:03:08.319124 2019",
|
294
|
+
"module"=>"authz_core",
|
295
|
+
"loglevel"=>"debug",
|
296
|
+
"pid"=>"9",
|
297
|
+
"tid"=>"140597881775872",
|
298
|
+
"errorcode"=>"mod_authz_core.c(820)",
|
299
|
+
"message"=>[message, "[client 172.17.0.1:50752] AH01626: authorization result of <RequireAny>: granted"]
|
300
|
+
})
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
142
304
|
|
143
305
|
end
|