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/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
|