logstash-patterns-core 4.0.1 → 4.2.0

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.
@@ -31,7 +31,7 @@ HAPROXYCAPTUREDRESPONSEHEADERS %{DATA:captured_response_headers}
31
31
  # HAPROXYCAPTUREDRESPONSEHEADERS %{DATA:response_header_content_type}\|%{DATA:response_header_content_encoding}\|%{DATA:response_header_cache_control}\|%{DATA:response_header_last_modified}
32
32
 
33
33
  # parse a haproxy 'httplog' line
34
- HAPROXYHTTPBASE %{IP:client_ip}:%{INT:client_port} \[%{HAPROXYDATE:accept_date}\] %{NOTSPACE:frontend_name} %{NOTSPACE:backend_name}/%{NOTSPACE:server_name} %{INT:time_request}/%{INT:time_queue}/%{INT:time_backend_connect}/%{INT:time_backend_response}/%{NOTSPACE:time_duration} %{INT:http_status_code} %{NOTSPACE:bytes_read} %{DATA:captured_request_cookie} %{DATA:captured_response_cookie} %{NOTSPACE:termination_state} %{INT:actconn}/%{INT:feconn}/%{INT:beconn}/%{INT:srvconn}/%{NOTSPACE:retries} %{INT:srv_queue}/%{INT:backend_queue} (\{%{HAPROXYCAPTUREDREQUESTHEADERS}\})?( )?(\{%{HAPROXYCAPTUREDRESPONSEHEADERS}\})?( )?"(<BADREQ>|(%{WORD:http_verb} (%{URIPROTO:http_proto}://)?(?:%{USER:http_user}(?::[^@]*)?@)?(?:%{URIHOST:http_host})?(?:%{URIPATHPARAM:http_request})?( HTTP/%{NUMBER:http_version})?))?"
34
+ HAPROXYHTTPBASE %{IP:client_ip}:%{INT:client_port} \[%{HAPROXYDATE:accept_date}\] %{NOTSPACE:frontend_name} %{NOTSPACE:backend_name}/%{NOTSPACE:server_name} %{INT:time_request}/%{INT:time_queue}/%{INT:time_backend_connect}/%{INT:time_backend_response}/%{NOTSPACE:time_duration} %{INT:http_status_code} %{NOTSPACE:bytes_read} %{DATA:captured_request_cookie} %{DATA:captured_response_cookie} %{NOTSPACE:termination_state} %{INT:actconn}/%{INT:feconn}/%{INT:beconn}/%{INT:srvconn}/%{NOTSPACE:retries} %{INT:srv_queue}/%{INT:backend_queue} (\{%{HAPROXYCAPTUREDREQUESTHEADERS}\})?( )?(\{%{HAPROXYCAPTUREDRESPONSEHEADERS}\})?( )?"(<BADREQ>|(%{WORD:http_verb} (%{URIPROTO:http_proto}://)?(?:%{USER:http_user}(?::[^@]*)?@)?(?:%{URIHOST:http_host})?(?:%{URIPATHPARAM:http_request})?( HTTP/%{NUMBER:http_version})?))?"?
35
35
 
36
36
  HAPROXYHTTP (?:%{SYSLOGTIMESTAMP:syslog_timestamp}|%{TIMESTAMP_ISO8601:timestamp8601}) %{IPORHOST:syslog_server} %{SYSLOGPROG}: %{HAPROXYHTTPBASE}
37
37
 
@@ -0,0 +1,15 @@
1
+ HTTPDUSER %{EMAILADDRESS}|%{USER}
2
+ HTTPDERROR_DATE %{DAY} %{MONTH} %{MONTHDAY} %{TIME} %{YEAR}
3
+
4
+ # Log formats
5
+ HTTPD_COMMONLOG %{IPORHOST:clientip} %{HTTPDUSER:ident} %{HTTPDUSER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" (?:-|%{NUMBER:response}) (?:-|%{NUMBER:bytes})
6
+ HTTPD_COMBINEDLOG %{HTTPD_COMMONLOG} %{QS:referrer} %{QS:agent}
7
+
8
+ # Error logs
9
+ HTTPD20_ERRORLOG \[%{HTTPDERROR_DATE:timestamp}\] \[%{LOGLEVEL:loglevel}\] (?:\[client %{IPORHOST:clientip}\] ){0,1}%{GREEDYDATA:message}
10
+ HTTPD24_ERRORLOG \[%{HTTPDERROR_DATE:timestamp}\] \[%{WORD:module}:%{LOGLEVEL:loglevel}\] \[pid %{POSINT:pid}(:tid %{NUMBER:tid})?\]( \(%{POSINT:proxy_errorcode}\)%{DATA:proxy_message}:)?( \[client %{IPORHOST:clientip}:%{POSINT:clientport}\])?( %{DATA:errorcode}:)? %{GREEDYDATA:message}
11
+ HTTPD_ERRORLOG %{HTTPD20_ERRORLOG}|%{HTTPD24_ERRORLOG}
12
+
13
+ # Deprecated
14
+ COMMONAPACHELOG %{HTTPD_COMMONLOG}
15
+ COMBINEDAPACHELOG %{HTTPD_COMBINEDLOG}
@@ -1,15 +1,12 @@
1
1
  JAVACLASS (?:[a-zA-Z$_][a-zA-Z$_0-9]*\.)*[a-zA-Z$_][a-zA-Z$_0-9]*
2
2
  #Space is an allowed character to match special cases like 'Native Method' or 'Unknown Source'
3
- JAVAFILE (?:[A-Za-z0-9_. -]+)
4
- #Allow special <init> method
5
- JAVAMETHOD (?:(<init>)|[a-zA-Z$_][a-zA-Z$_0-9]*)
3
+ JAVAFILE (?:[a-zA-Z$_0-9. -]+)
4
+ #Allow special <init>, <clinit> methods
5
+ JAVAMETHOD (?:(<(?:cl)?init>)|[a-zA-Z$_][a-zA-Z$_0-9]*)
6
6
  #Line number is optional in special cases 'Native method' or 'Unknown source'
7
7
  JAVASTACKTRACEPART %{SPACE}at %{JAVACLASS:class}\.%{JAVAMETHOD:method}\(%{JAVAFILE:file}(?::%{NUMBER:line})?\)
8
8
  # Java Logs
9
9
  JAVATHREAD (?:[A-Z]{2}-Processor[\d]+)
10
- JAVACLASS (?:[a-zA-Z0-9-]+\.)+[A-Za-z0-9$]+
11
- JAVAFILE (?:[A-Za-z0-9_.-]+)
12
- JAVASTACKTRACEPART at %{JAVACLASS:class}\.%{WORD:method}\(%{JAVAFILE:file}:%{NUMBER:line}\)
13
10
  JAVALOGMESSAGE (.*)
14
11
  # MMM dd, yyyy HH:mm:ss eg: Jan 9, 2014 7:13:13 AM
15
12
  CATALINA_DATESTAMP %{MONTH} %{MONTHDAY}, 20%{YEAR} %{HOUR}:?%{MINUTE}(?::?%{SECOND}) (?:AM|PM)
@@ -11,6 +11,6 @@ SYSLOGLINE %{SYSLOGBASE2} %{GREEDYDATA:message}
11
11
  # IETF 5424 syslog(8) format (see http://www.rfc-editor.org/info/rfc5424)
12
12
  SYSLOG5424PRI <%{NONNEGINT:syslog5424_pri}>
13
13
  SYSLOG5424SD \[%{DATA}\]+
14
- SYSLOG5424BASE %{SYSLOG5424PRI}%{NONNEGINT:syslog5424_ver} +(?:%{TIMESTAMP_ISO8601:syslog5424_ts}|-) +(?:%{HOSTNAME:syslog5424_host}|-) +(-|%{SYSLOG5424PRINTASCII:syslog5424_app}) +(-|%{SYSLOG5424PRINTASCII:syslog5424_proc}) +(-|%{SYSLOG5424PRINTASCII:syslog5424_msgid}) +(?:%{SYSLOG5424SD:syslog5424_sd}|-|)
14
+ SYSLOG5424BASE %{SYSLOG5424PRI}%{NONNEGINT:syslog5424_ver} +(?:%{TIMESTAMP_ISO8601:syslog5424_ts}|-) +(?:%{IPORHOST:syslog5424_host}|-) +(-|%{SYSLOG5424PRINTASCII:syslog5424_app}) +(-|%{SYSLOG5424PRINTASCII:syslog5424_proc}) +(-|%{SYSLOG5424PRINTASCII:syslog5424_msgid}) +(?:%{SYSLOG5424SD:syslog5424_sd}|-|)
15
15
 
16
16
  SYSLOG5424LINE %{SYSLOG5424BASE} +%{GREEDYDATA:syslog5424_msg}
@@ -0,0 +1 @@
1
+ MAVEN_VERSION (?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)(?:[.-](RELEASE|SNAPSHOT))?
@@ -89,7 +89,7 @@ NAGIOS_PASSIVE_HOST_CHECK %{NAGIOS_TYPE_PASSIVE_HOST_CHECK:nagios_type}: %{DATA:
89
89
  NAGIOS_SERVICE_EVENT_HANDLER %{NAGIOS_TYPE_SERVICE_EVENT_HANDLER:nagios_type}: %{DATA:nagios_hostname};%{DATA:nagios_service};%{DATA:nagios_state};%{DATA:nagios_statelevel};%{DATA:nagios_event_handler_name}
90
90
  NAGIOS_HOST_EVENT_HANDLER %{NAGIOS_TYPE_HOST_EVENT_HANDLER:nagios_type}: %{DATA:nagios_hostname};%{DATA:nagios_state};%{DATA:nagios_statelevel};%{DATA:nagios_event_handler_name}
91
91
 
92
- NAGIOS_TIMEPERIOD_TRANSITION %{NAGIOS_TYPE_TIMEPERIOD_TRANSITION:nagios_type}: %{DATA:nagios_service};%{DATA:nagios_unknown1};%{DATA:nagios_unknown2}
92
+ NAGIOS_TIMEPERIOD_TRANSITION %{NAGIOS_TYPE_TIMEPERIOD_TRANSITION:nagios_type}: %{DATA:nagios_service};%{NUMBER:nagios_unknown1};%{NUMBER:nagios_unknown2}
93
93
 
94
94
  ####################
95
95
  #### External checks
@@ -1,3 +1,3 @@
1
1
  REDISTIMESTAMP %{MONTHDAY} %{MONTH} %{TIME}
2
2
  REDISLOG \[%{POSINT:pid}\] %{REDISTIMESTAMP:timestamp} \*
3
-
3
+ REDISMONLOG %{NUMBER:timestamp} \[%{INT:database} %{IP:client}:%{NUMBER:port}\] "%{WORD:command}"\s?%{GREEDYDATA:params}
@@ -0,0 +1,4 @@
1
+ # Pattern squid3
2
+ # Documentation of squid3 logs formats can be found at the following link:
3
+ # http://wiki.squid-cache.org/Features/LogFormat
4
+ SQUID3 %{NUMBER:timestamp}\s+%{NUMBER:duration}\s%{IP:client_address}\s%{WORD:cache_result}/%{POSINT:status_code}\s%{NUMBER:bytes}\s%{WORD:request_method}\s%{NOTSPACE:url}\s(%{NOTSPACE:user}|-)\s%{WORD:hierarchy_code}/%{IPORHOST:server}\s%{NOTSPACE:content_type}
@@ -20,16 +20,6 @@ describe "SYSLOGLINE" do
20
20
 
21
21
  end
22
22
 
23
- describe "COMMONAPACHELOG" do
24
-
25
- let(:value) { '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'}
26
-
27
- it "generates the clientip field" do
28
- expect(grok_match(subject, value)).to include("clientip" => "83.149.9.216")
29
- end
30
-
31
- end
32
-
33
23
  describe "HTTP DATE parsing" do
34
24
 
35
25
  context "HTTPDATE", "when having a German month" do
@@ -73,6 +63,19 @@ describe "TOMCATLOG" do
73
63
  end
74
64
  end
75
65
 
66
+ describe 'LOGLEVEL' do
67
+ it 'matches info label' do
68
+ expect(grok_match(subject, 'INFO')).to pass
69
+ expect(grok_match(subject, 'info')).to pass
70
+ end
71
+
72
+ it 'matches information label' do
73
+ expect(grok_match(subject, 'information')).to pass
74
+ expect(grok_match(subject, 'Information')).to pass
75
+ expect(grok_match(subject, 'INFORMATION')).to pass
76
+ end
77
+ end
78
+
76
79
  describe "IPORHOST" do
77
80
 
78
81
  let(:pattern) { "IPORHOST" }
@@ -100,14 +103,224 @@ describe "UNIXPATH" do
100
103
  let(:value) { '/foo/bar' }
101
104
 
102
105
  it "should match the path" do
103
- expect(grok_match(pattern,value)).to pass
106
+ expect(grok_match(pattern, value, true)).to pass
104
107
  end
105
108
 
106
109
  context "when using comma separators and other regexp" do
107
110
 
111
+ let(:pattern) { '((a=(?<a>%{UNIXPATH})?|b=(?<b>%{UNIXPATH})?)(,\s)?)+' }
112
+
113
+ let(:grok) do
114
+ grok = LogStash::Filters::Grok.new("match" => ["message", pattern])
115
+ grok.register
116
+ grok
117
+ end
118
+
108
119
  let(:value) { 'a=/some/path, b=/some/other/path' }
109
120
 
121
+ it "was expected to extract both but never really did" do # or maybe on JRuby 1.7
122
+ event = build_event(value)
123
+ grok.filter(event)
124
+ expect( event.to_hash['a'] ).to eql '/some/path,'
125
+ expect( event.to_hash['b'] ).to be nil
126
+ end
127
+
128
+ end
129
+
130
+ context 'relative path' do
131
+
132
+ let(:path_matcher) do # non-exact matcher
133
+ grok = LogStash::Filters::Grok.new("match" => ["message", '%{UNIXPATH:path}'])
134
+ grok.register
135
+ lambda { |msg| event = build_event(msg); grok.filter(event); event }
136
+ end
137
+
138
+ it "should not match (only partially)" do
139
+ expect(grok_match(pattern, 'a/./b/c', true)).to_not pass
140
+ event = path_matcher.('a/./b/c')
141
+ expect( event.to_hash['path'] ).to eql '/./b/c'
142
+
143
+ expect(grok_match(pattern, ',/.', true)).to_not pass
144
+ event = path_matcher.(',/.')
145
+ expect( event.to_hash['path'] ).to eql '/.'
146
+
147
+ expect(grok_match(pattern, '+/.../', true)).to_not pass
148
+ event = path_matcher.('+/.../')
149
+ expect( event.to_hash['path'] ).to eql '/.../'
150
+
151
+ expect(grok_match(pattern, '~/b/', true)).to_not pass
152
+ event = path_matcher.('~/b/')
153
+ expect( event.to_hash['path'] ).to eql '/b/'
154
+
155
+ expect(grok_match(pattern, './b//', true)).to_not pass
156
+ expect(grok_match(pattern, 'a//b', true)).to_not pass
157
+ end
158
+
159
+ it "should not match paths starting with ." do
160
+ expect(grok_match(pattern, '../0', true)).to_not pass
161
+ expect(grok_match(pattern, './~', true)).to_not pass
162
+ expect(grok_match(pattern, '.../-', true)).to_not pass
163
+ expect(grok_match(pattern, './', true)).to_not pass
164
+ expect(grok_match(pattern, './,', true)).to_not pass
165
+ expect(grok_match(pattern, '../', true)).to_not pass
166
+ expect(grok_match(pattern, '.a/', true)).to_not pass
167
+ expect(grok_match(pattern, '.~/', true)).to_not pass
168
+ end
169
+
170
+ it "should not match expression wout separator" do
171
+ expect(grok_match(pattern, '.')).to_not pass
172
+ expect(grok_match(pattern, '..')).to_not pass
173
+ expect(grok_match(pattern, '...')).to_not pass
174
+ expect(grok_match(pattern, '.,')).to_not pass
175
+ expect(grok_match(pattern, '.-')).to_not pass
176
+ end
177
+
178
+ end
179
+
180
+ context "dotted path" do
181
+
182
+ it "should match path containing ." do
183
+ expect(grok_match(pattern, '/some/./path/', true)).to pass
184
+ expect(grok_match(pattern, '/some/../path', true)).to pass
185
+ expect(grok_match(pattern, '/../.', true)).to pass
186
+ expect(grok_match(pattern, '/.', true)).to pass
187
+ expect(grok_match(pattern, '/..', true)).to pass
188
+ expect(grok_match(pattern, '/...', true)).to pass
189
+ end
190
+
191
+ end
192
+
193
+ context "separators" do
194
+
195
+ it "should match root" do
196
+ expect(grok_match(pattern, '/', true)).to pass
197
+ end
198
+
199
+ it "should match" do
200
+ expect(grok_match(pattern, '//', true)).to pass
201
+ expect(grok_match(pattern, '//00', true)).to pass
202
+ expect(grok_match(pattern, '///a', true)).to pass
203
+ expect(grok_match(pattern, '/a//', true)).to pass
204
+ expect(grok_match(pattern, '///a//b/c///', true)).to pass
205
+ end
206
+
207
+ it "should not match windows separator" do
208
+ expect(grok_match(pattern, "\\a", true)).to_not pass
209
+ expect(grok_match(pattern, '/0\\', true)).to_not pass
210
+ expect(grok_match(pattern, "/a\\b", true)).to_not pass
211
+ end
212
+
213
+ end
214
+
215
+ context "long path" do
216
+
217
+ let(:grok) do
218
+ grok = LogStash::Filters::Grok.new("match" => ["message", '%{UNIXPATH:path} '], 'timeout_millis' => 1500)
219
+ grok.register
220
+ grok
221
+ end
222
+
223
+ let(:value) { '/opt/abcdef/1/.22/3:3+3/foo@BAR/X-Y+Z/~Sample_l_SUBc b' }
224
+
110
225
  it "should match the path" do
226
+ event = build_event(value)
227
+ grok.filter(event)
228
+ expect( event.to_hash['path'] ).to eql '/opt/abcdef/1/.22/3:3+3/foo@BAR/X-Y+Z/~Sample_l_SUBc'
229
+ end
230
+
231
+ it "should not match with invalid chars (or cause DoS)" do
232
+ event = build_event(value.sub('SUB', '&^_'))
233
+ grok.filter(event) # used to call a looong looop (DoS) despite the timeout guard
234
+ expect( event.to_hash['tags'] ).to include '_grokparsefailure'
235
+ end
236
+ end
237
+
238
+ it "matches paths with non-ascii characters" do
239
+ event = build_event path = '/opt/Čierný_Peter/.中'
240
+ build_grok('UNIXPATH:path').filter event
241
+ expect( event.get('path') ).to eql path
242
+ end
243
+
244
+ end
245
+
246
+ describe "WINPATH" do
247
+
248
+ let(:pattern) { 'WINPATH' }
249
+ let(:value) { 'C:\\foo\\bar' }
250
+
251
+ it "should match the path" do
252
+ expect(grok_match(pattern, value, true)).to pass
253
+ end
254
+
255
+ it "should match root path" do
256
+ expect(grok_match(pattern, 'C:\\', true)).to pass
257
+ expect(grok_match(pattern, 'C:\\\\', true)).to pass
258
+ expect(grok_match(pattern, 'a:\\', true)).to pass
259
+ expect(grok_match(pattern, 'x:\\\\', true)).to pass
260
+ end
261
+
262
+ it "should match paths with spaces" do
263
+ expect(grok_match(pattern, 'C:\\Documents and Settings\\Public', true)).to pass
264
+ expect(grok_match(pattern, 'C:\\\\Users\\\\Public\\\\.Mozilla Firefox', true)).to pass
265
+ end
266
+
267
+ it "should not match unix-style paths" do
268
+ expect(grok_match(pattern, '/foo', true)).to_not pass
269
+ expect(grok_match(pattern, '//C/path', true)).to_not pass
270
+ expect(grok_match(pattern, '/', true)).to_not pass
271
+ expect(grok_match(pattern, '/foo/bar', true)).to_not pass
272
+ expect(grok_match(pattern, '/..', true)).to_not pass
273
+ expect(grok_match(pattern, 'C://', true)).to_not pass
274
+ end
275
+
276
+ it "matches paths with non-ascii characters" do
277
+ expect(grok_match(pattern, 'C:\\Čierný Peter\\.中.exe', true)).to pass
278
+ end
279
+
280
+ context 'relative paths' do
281
+
282
+ it "should not match" do
283
+ expect(grok_match(pattern, 'a\\bar', true)).to_not pass
284
+ expect(grok_match(pattern, 'foo\\bar', true)).to_not pass
285
+ expect(grok_match(pattern, 'C\\A\\B', true)).to_not pass
286
+ expect(grok_match(pattern, 'C\\\\0', true)).to_not pass
287
+ expect(grok_match(pattern, '.\\0', true)).to_not pass
288
+ expect(grok_match(pattern, '..\\', true)).to_not pass
289
+ expect(grok_match(pattern, '...\\-', true)).to_not pass
290
+ expect(grok_match(pattern, '.\\', true)).to_not pass
291
+ expect(grok_match(pattern, '.\\,', true)).to_not pass
292
+ expect(grok_match(pattern, '..\\', true)).to_not pass
293
+ expect(grok_match(pattern, '.a\\', true)).to_not pass
294
+ end
295
+
296
+ it "should not match expression wout separator" do
297
+ expect(grok_match(pattern, '.')).to_not pass
298
+ expect(grok_match(pattern, '..')).to_not pass
299
+ expect(grok_match(pattern, '...')).to_not pass
300
+ expect(grok_match(pattern, 'C:')).to_not pass
301
+ expect(grok_match(pattern, 'C')).to_not pass
302
+ end
303
+
304
+ end
305
+
306
+ end
307
+
308
+
309
+ describe "URIPROTO" do
310
+ let(:pattern) { 'URIPROTO' }
311
+
312
+ context "http is a valid URIPROTO" do
313
+ let(:value) { 'http' }
314
+
315
+ it "should match" do
316
+ expect(grok_match(pattern,value)).to pass
317
+ end
318
+ end
319
+
320
+ context "android-app is a valid URIPROTO" do
321
+ let(:value) { 'android-app' }
322
+
323
+ it "should match" do
111
324
  expect(grok_match(pattern,value)).to pass
112
325
  end
113
326
  end
@@ -193,5 +406,92 @@ describe "IPV4" do
193
406
  expect(grok_match(pattern,value)).not_to pass
194
407
  end
195
408
  end
409
+ end
410
+
411
+ describe "URN" do
412
+
413
+ let(:pattern) { "URN" }
414
+
415
+ # Valid URNs
416
+ # http://tools.ietf.org/html/rfc2141#section-2
417
+ let(:simple) { "urn:example:foo" }
418
+ let(:unreserved) { "urn:example:" +
419
+ [*'A'..'Z', *'a'..'z', *'0'..'9', "()+,-.::=@;$_!*'"].join() }
420
+ let(:reserved) { "urn:example:/#?" }
421
+ let(:escaped_upper) { "urn:example:%25foo%2Fbar%3F%23" }
422
+ let(:escaped_lower) { "urn:example:%25foo%2fbar%3f%23" }
423
+ let(:only_escaped) { "urn:example:%00" }
424
+ let(:long_nid) { "urn:example-example-example-example-:foo" }
425
+
426
+ # Invalid URNs
427
+ let(:bad_prefix) { "URN:example:foo" }
428
+ let(:empty_nid) { "urn::foo" }
429
+ let(:leading_hyphen) { "urn:-example:foo" }
430
+ let(:bad_nid) { "urn:example.com:foo" }
431
+ let(:percent_nid) { "urn:example%41com:foo" }
432
+ let(:too_long_nid) { "urn:example-example-example-example-x:foo" }
433
+ let(:empty_nss) { "urn:example:" }
434
+ let(:naked_percent) { "urn:example:%" }
435
+ let(:short_percent) { "urn:example:%a" }
436
+ let(:nonhex_percent) { "urn:example:%ax" }
437
+
438
+ context "when testing a valid URN" do
439
+ it "should match a simple URN" do
440
+ expect(grok_match(pattern, simple)).to pass
441
+ end
442
+
443
+ it "should match a complex URN" do
444
+ expect(grok_match(pattern, unreserved)).to pass
445
+ end
446
+
447
+ it "should allow reserved characters" do
448
+ expect(grok_match(pattern, reserved)).to pass
449
+ end
450
+
451
+ it "should allow percent-escapes" do
452
+ expect(grok_match(pattern, escaped_upper)).to pass
453
+ expect(grok_match(pattern, escaped_lower)).to pass
454
+ expect(grok_match(pattern, only_escaped)).to pass
455
+ end
456
+
457
+ it "should match a URN with a 32-character NID" do
458
+ expect(grok_match(pattern, long_nid)).to pass
459
+ end
460
+ end
461
+
462
+ context "when testing an invalid URN" do
463
+ it "should reject capitalized 'URN'" do
464
+ expect(grok_match(pattern, bad_prefix)).not_to pass
465
+ end
196
466
 
467
+ it "should reject an empty NID" do
468
+ expect(grok_match(pattern, empty_nid)).not_to pass
469
+ end
470
+
471
+ it "should reject an NID with a leading hyphen" do
472
+ expect(grok_match(pattern, leading_hyphen)).not_to pass
473
+ end
474
+
475
+ it "should reject an NID with a special character" do
476
+ expect(grok_match(pattern, bad_nid)).not_to pass
477
+ end
478
+
479
+ it "should reject an NID with a percent sign" do
480
+ expect(grok_match(pattern, percent_nid)).not_to pass
481
+ end
482
+
483
+ it "should reject an NID longer than 32 characters" do
484
+ expect(grok_match(pattern, too_long_nid)).not_to pass
485
+ end
486
+
487
+ it "should reject a URN with an empty NSS" do
488
+ expect(grok_match(pattern, empty_nss)).not_to pass
489
+ end
490
+
491
+ it "should reject non-escape percent signs" do
492
+ expect(grok_match(pattern, naked_percent)).not_to pass
493
+ expect(grok_match(pattern, short_percent)).not_to pass
494
+ expect(grok_match(pattern, nonhex_percent)).not_to pass
495
+ end
496
+ end
197
497
  end
@@ -19,6 +19,21 @@ describe "FIREWALLS" do
19
19
  expect(subject["message"]).to include("(Secondary) Switching to ACTIVE - Service card in other unit has failed")
20
20
  end
21
21
  end
22
+
23
+ let(:pattern106015) { "CISCOFW106015" }
24
+
25
+ context "parsing a 106015 message" do
26
+
27
+ let(:value) { "Deny TCP (no connection) from 192.168.150.65/2278 to 64.101.128.83/80 flags RST on interface inside" }
28
+
29
+ subject { grok_match(pattern106015, value) }
30
+
31
+ it { should include("interface" => "inside") }
32
+
33
+ it "generates a message field" do
34
+ expect(subject["message"]).to include("Deny TCP (no connection) from 192.168.150.65/2278 to 64.101.128.83/80 flags RST on interface inside")
35
+ end
36
+ end
22
37
 
23
38
  let(:pattern106100) { "CISCOFW106100" }
24
39
 
@@ -50,6 +65,22 @@ describe "FIREWALLS" do
50
65
  end
51
66
  end
52
67
 
68
+ let(:pattern304001) { "CISCOFW304001" }
69
+
70
+ context "parsing a 304001 message" do
71
+
72
+ let(:value) { "10.20.30.40(DOMAIN\\login) Accessed URL 10.11.12.13:http://example.org/" }
73
+
74
+ subject { grok_match(pattern304001, value) }
75
+
76
+ it 'should break the message up into fields' do
77
+ expect(subject['src_ip']).to eq('10.20.30.40')
78
+ expect(subject['src_fwuser']).to eq('DOMAIN\\login')
79
+ expect(subject['dst_ip']).to eq('10.11.12.13')
80
+ expect(subject['dst_url']).to eq('http://example.org/')
81
+ end
82
+ end
83
+
53
84
  let(:pattern106023) { "CISCOFW106023" }
54
85
 
55
86
  context "parsing a 106023 message" do