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.
Files changed (77) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +119 -0
  3. data/Gemfile +8 -1
  4. data/LICENSE +199 -10
  5. data/README.md +12 -19
  6. data/lib/logstash/patterns/core.rb +11 -3
  7. data/logstash-patterns-core.gemspec +1 -1
  8. data/patterns/ecs-v1/aws +28 -0
  9. data/patterns/ecs-v1/bacula +53 -0
  10. data/patterns/ecs-v1/bind +13 -0
  11. data/patterns/ecs-v1/bro +30 -0
  12. data/patterns/ecs-v1/exim +26 -0
  13. data/patterns/ecs-v1/firewalls +111 -0
  14. data/patterns/ecs-v1/grok-patterns +95 -0
  15. data/patterns/ecs-v1/haproxy +40 -0
  16. data/patterns/ecs-v1/httpd +17 -0
  17. data/patterns/ecs-v1/java +34 -0
  18. data/patterns/ecs-v1/junos +13 -0
  19. data/patterns/ecs-v1/linux-syslog +16 -0
  20. data/patterns/{maven → ecs-v1/maven} +0 -0
  21. data/patterns/ecs-v1/mcollective +4 -0
  22. data/patterns/ecs-v1/mongodb +7 -0
  23. data/patterns/ecs-v1/nagios +124 -0
  24. data/patterns/ecs-v1/postgresql +2 -0
  25. data/patterns/ecs-v1/rails +13 -0
  26. data/patterns/ecs-v1/redis +3 -0
  27. data/patterns/ecs-v1/ruby +2 -0
  28. data/patterns/ecs-v1/squid +6 -0
  29. data/patterns/ecs-v1/zeek +33 -0
  30. data/patterns/{aws → legacy/aws} +1 -1
  31. data/patterns/{bacula → legacy/bacula} +5 -5
  32. data/patterns/legacy/bind +3 -0
  33. data/patterns/{bro → legacy/bro} +0 -0
  34. data/patterns/{exim → legacy/exim} +8 -2
  35. data/patterns/{firewalls → legacy/firewalls} +2 -2
  36. data/patterns/{grok-patterns → legacy/grok-patterns} +4 -4
  37. data/patterns/{haproxy → legacy/haproxy} +1 -1
  38. data/patterns/{httpd → legacy/httpd} +2 -2
  39. data/patterns/{java → legacy/java} +1 -3
  40. data/patterns/{junos → legacy/junos} +0 -0
  41. data/patterns/{linux-syslog → legacy/linux-syslog} +0 -0
  42. data/patterns/legacy/maven +1 -0
  43. data/patterns/{mcollective → legacy/mcollective} +0 -0
  44. data/patterns/{mcollective-patterns → legacy/mcollective-patterns} +0 -0
  45. data/patterns/{mongodb → legacy/mongodb} +0 -0
  46. data/patterns/{nagios → legacy/nagios} +1 -1
  47. data/patterns/{postgresql → legacy/postgresql} +0 -0
  48. data/patterns/{rails → legacy/rails} +0 -0
  49. data/patterns/{redis → legacy/redis} +0 -0
  50. data/patterns/{ruby → legacy/ruby} +0 -0
  51. data/patterns/legacy/squid +4 -0
  52. data/spec/patterns/aws_spec.rb +395 -0
  53. data/spec/patterns/bacula_spec.rb +367 -0
  54. data/spec/patterns/bind_spec.rb +92 -0
  55. data/spec/patterns/bro_spec.rb +613 -0
  56. data/spec/patterns/core_spec.rb +260 -15
  57. data/spec/patterns/exim_spec.rb +201 -0
  58. data/spec/patterns/firewalls_spec.rb +707 -66
  59. data/spec/patterns/haproxy_spec.rb +253 -28
  60. data/spec/patterns/httpd_spec.rb +248 -86
  61. data/spec/patterns/java_spec.rb +375 -0
  62. data/spec/patterns/junos_spec.rb +101 -0
  63. data/spec/patterns/mcollective_spec.rb +35 -0
  64. data/spec/patterns/mongodb_spec.rb +170 -33
  65. data/spec/patterns/nagios_spec.rb +299 -78
  66. data/spec/patterns/netscreen_spec.rb +123 -0
  67. data/spec/patterns/rails3_spec.rb +87 -29
  68. data/spec/patterns/redis_spec.rb +216 -140
  69. data/spec/patterns/shorewall_spec.rb +85 -74
  70. data/spec/patterns/squid_spec.rb +139 -0
  71. data/spec/patterns/syslog_spec.rb +266 -22
  72. data/spec/spec_helper.rb +83 -5
  73. metadata +70 -31
  74. data/patterns/bind +0 -3
  75. data/patterns/squid +0 -4
  76. data/spec/patterns/bro.rb +0 -126
  77. data/spec/patterns/s3_spec.rb +0 -173
@@ -2,242 +2,463 @@
2
2
  require "spec_helper"
3
3
  require "logstash/patterns/core"
4
4
 
5
- describe "NAGIOSLOGLINE - CURRENT HOST STATE" do
5
+ describe_pattern "NAGIOSLOGLINE - CURRENT HOST STATE", [ 'legacy', 'ecs-v1' ] do
6
6
 
7
- let(:value) { "[1427925600] CURRENT HOST STATE: nagioshost;UP;HARD;1;PING OK - Packet loss = 0%, RTA = 2.24 ms" }
8
- let(:grok) { grok_match(subject, value) }
7
+ let(:message) { "[1427925600] CURRENT HOST STATE: nagioshost;UP;HARD;1;PING OK - Packet loss = 0%, RTA = 2.24 ms" }
9
8
 
10
9
  it "a pattern pass the grok expression" do
11
10
  expect(grok).to pass
12
11
  end
13
12
 
14
13
  it "matches a simple message" do
15
- expect(subject).to match(value)
14
+ expect(pattern).to match(message)
16
15
  end
17
16
 
18
17
  it "generates the nagios_epoch field" do
19
- expect(grok).to include("nagios_epoch" => "1427925600")
18
+ if ecs_compatibility?
19
+ expect(grok).to include("timestamp" => "1427925600")
20
+ else
21
+ expect(grok).to include("nagios_epoch" => "1427925600")
22
+ end
20
23
  end
21
24
 
22
25
  it "generates the nagios_message field" do
23
- expect(grok).to include("nagios_message" => "PING OK - Packet loss = 0%, RTA = 2.24 ms")
26
+ if ecs_compatibility?
27
+ expect(grok).to include("message" => [message, "PING OK - Packet loss = 0%, RTA = 2.24 ms"])
28
+ else
29
+ expect(grok).to include("nagios_message" => "PING OK - Packet loss = 0%, RTA = 2.24 ms")
30
+ end
24
31
  end
25
32
 
26
33
  it "generates the nagios_hostname field" do
27
- expect(grok).to include("nagios_hostname" => "nagioshost")
34
+ if ecs_compatibility?
35
+ expect(grok).to include("host" => { "hostname" => "nagioshost" })
36
+ else
37
+ expect(grok).to include("nagios_hostname" => "nagioshost")
38
+ end
28
39
  end
29
40
 
30
41
  it "generates the nagios_state field" do
31
- expect(grok).to include("nagios_state" => "UP")
42
+ if ecs_compatibility?
43
+ expect(grok).to include("service" => hash_including("state" => "UP"))
44
+ else
45
+ expect(grok).to include("nagios_state" => "UP")
46
+ end
32
47
  end
33
48
 
34
49
  it "generates the nagios_statetype field" do
35
- expect(grok).to include("nagios_statetype" => "HARD")
50
+ if ecs_compatibility?
51
+ expect(grok).to include("nagios" => hash_including("log" => hash_including("state_type" => "HARD")))
52
+ else
53
+ expect(grok).to include("nagios_statetype" => "HARD")
54
+ end
36
55
  end
37
56
 
38
57
  end
39
58
 
40
- describe "NAGIOSLOGLINE - CURRENT SERVICE STATE" do
59
+ describe_pattern "NAGIOSLOGLINE - CURRENT SERVICE STATE", [ 'legacy', 'ecs-v1' ] do
41
60
 
42
- let(:value) { "[1427925600] CURRENT SERVICE STATE: nagioshost;nagiosservice;OK;HARD;1;nagiosmessage" }
43
- let(:grok) { grok_match(subject, value) }
61
+ let(:message) { "[1427925600] CURRENT SERVICE STATE: nagioshost;SSH;OK;HARD;1;nagiosmessage" }
44
62
 
45
63
  it "a pattern pass the grok expression" do
46
64
  expect(grok).to pass
47
65
  end
48
66
 
49
67
  it "matches a simple message" do
50
- expect(subject).to match(value)
68
+ expect(pattern).to match(message)
51
69
  end
52
70
 
53
71
  it "generates the nagios_type field" do
54
- expect(grok).to include("nagios_type" => "CURRENT SERVICE STATE")
72
+ if ecs_compatibility?
73
+ expect(grok).to include("nagios" => hash_including("log" => hash_including("type" => "CURRENT SERVICE STATE")))
74
+ else
75
+ expect(grok).to include("nagios_type" => "CURRENT SERVICE STATE")
76
+ end
55
77
  end
56
78
 
57
79
  it "generates the nagios_epoch field" do
58
- expect(grok).to include("nagios_epoch" => "1427925600")
80
+ if ecs_compatibility?
81
+ expect(grok).to include("timestamp" => "1427925600")
82
+ else
83
+ expect(grok).to include("nagios_epoch" => "1427925600")
84
+ end
59
85
  end
60
86
 
61
87
  it "generates the nagios_message field" do
62
- expect(grok).to include("nagios_message" => "nagiosmessage")
88
+ if ecs_compatibility?
89
+ expect(grok).to include("message" => [message, "nagiosmessage"])
90
+ else
91
+ expect(grok).to include("nagios_message" => "nagiosmessage")
92
+ end
63
93
  end
64
94
 
65
- it "generates the nagios_hostname field" do
66
- expect(grok).to include("nagios_hostname" => "nagioshost")
95
+ it "generates the hostname field" do
96
+ if ecs_compatibility?
97
+ expect(grok).to include("host" => { "hostname" => "nagioshost" })
98
+ else
99
+ expect(grok).to include("nagios_hostname" => "nagioshost")
100
+ end
67
101
  end
68
102
 
69
- it "generates the nagios_service field" do
70
- expect(grok).to include("nagios_service" => "nagiosservice")
103
+ it "generates the service field" do
104
+ if ecs_compatibility?
105
+ expect(grok).to include("service" => hash_including("name" => "SSH"))
106
+ else
107
+ expect(grok).to include("nagios_service" => "SSH")
108
+ end
71
109
  end
72
110
 
73
111
  it "generates the nagios_state field" do
74
- expect(grok).to include("nagios_state" => "OK")
112
+ if ecs_compatibility?
113
+ expect(grok).to include("service" => hash_including("state" => "OK"))
114
+ else
115
+ expect(grok).to include("nagios_state" => "OK")
116
+ end
75
117
  end
76
118
 
77
119
  it "generates the nagios_statetype field" do
78
- expect(grok).to include("nagios_statetype" => "HARD")
79
- end
120
+ if ecs_compatibility?
121
+ expect(grok).to include("nagios" => hash_including("log" => hash_including("state_type" => "HARD")))
122
+ else
123
+ expect(grok).to include("nagios_statetype" => "HARD")
124
+ end
125
+ end
126
+
127
+ it "generates the nagios_statecode field" do
128
+ if ecs_compatibility?
129
+ expect(grok).to include("nagios" => hash_including("log" => hash_including("attempt" => 1)))
130
+ else
131
+ # NOTE: (legacy) nagios_statecode corresponds to current_attempt (according to Nagios' source)
132
+ expect(grok).to include("nagios_statecode" => "1")
133
+ end
134
+ end
135
+
136
+ context 'real-world example' do
137
+
138
+ let(:message) do
139
+ '[1427956600] CURRENT SERVICE STATE: prod-virtual-ESz06;check_vmfs_prod-PvDC2;CRITICAL;HARD;3;CRITICAL - /vmfs/volumes/prod-vsRoot - total: 8191.75 Gb - used: 7859.84 Gb (95%)- free: 331.90 Gb (5%)'
140
+ end
141
+
142
+ it 'matches' do
143
+ if ecs_compatibility?
144
+ expect(grok).to include(
145
+ "host" => { "hostname" => "prod-virtual-ESz06" },
146
+ "service" => { "name" => "check_vmfs_prod-PvDC2", "state" => 'CRITICAL' },
147
+ "nagios" => { "log" => {
148
+ "type" => "CURRENT SERVICE STATE",
149
+ "state_type" => "HARD",
150
+ "attempt" => 3
151
+ }},
152
+ "message" => [message, "CRITICAL - /vmfs/volumes/prod-vsRoot - total: 8191.75 Gb - used: 7859.84 Gb (95%)- free: 331.90 Gb (5%)"]
153
+ )
154
+ else
155
+ expect(grok).to include(
156
+ "nagios_type"=>"CURRENT SERVICE STATE",
157
+ "nagios_state"=>"CRITICAL",
158
+ "nagios_statetype"=>"HARD",
159
+ "nagios_hostname"=>"prod-virtual-ESz06",
160
+ "nagios_statecode"=>"3", # NOTE: "incorrect" - corresponds to current_attempt (according to Nagios' source)
161
+ "nagios_message"=>"CRITICAL - /vmfs/volumes/prod-vsRoot - total: 8191.75 Gb - used: 7859.84 Gb (95%)- free: 331.90 Gb (5%)"
162
+ )
163
+ end
164
+ end
80
165
 
166
+ end
81
167
  end
82
168
 
83
- describe "NAGIOSLOGLINE - TIMEPERIOD TRANSITION" do
169
+ describe_pattern "NAGIOSLOGLINE - TIMEPERIOD TRANSITION", [ 'legacy', 'ecs-v1' ] do
84
170
 
85
- let(:value) { "[1427925600] TIMEPERIOD TRANSITION: 24X7;1;1" }
86
- let(:grok) { grok_match(subject, value) }
171
+ let(:message) { "[1427925600] TIMEPERIOD TRANSITION: 24X7;-1;1" }
87
172
 
88
- it "a pattern pass the grok expression" do
89
- expect(grok).to pass
90
- end
91
-
92
- it "matches a simple message" do
93
- expect(subject).to match(value)
173
+ it "matches the message" do
174
+ expect(pattern).to match(message)
94
175
  end
95
176
 
96
177
  it "generates the nagios_type field" do
97
- expect(grok).to include("nagios_type" => "TIMEPERIOD TRANSITION")
178
+ if ecs_compatibility?
179
+ expect(grok).to include("nagios" => hash_including("log" => hash_including("type" => 'TIMEPERIOD TRANSITION')))
180
+ else
181
+ expect(grok).to include("nagios_type" => "TIMEPERIOD TRANSITION")
182
+ end
98
183
  end
99
184
 
100
185
  it "generates the nagios_epoch field" do
101
- expect(grok).to include("nagios_epoch" => "1427925600")
186
+ expect(grok).to include("nagios_epoch" => "1427925600") unless ecs_compatibility?
102
187
  end
103
188
 
104
- it "generates the nagios_esrvice field" do
105
- expect(grok).to include("nagios_service" => "24X7")
189
+ it "generates the service field" do
190
+ if ecs_compatibility?
191
+ expect(grok).to include("service" => hash_including("name" => '24X7'))
192
+ else
193
+ expect(grok).to include("nagios_service" => "24X7")
194
+ end
195
+ end
196
+
197
+ it "generates the period from/to fields" do
198
+ if ecs_compatibility?
199
+ expect(grok).to include("nagios" => hash_including("log" => hash_including("period_from" => -1, "period_to" => 1)))
200
+ else
201
+ expect(grok).to include("nagios_unknown1" => "-1", "nagios_unknown2" => "1")
202
+ end
106
203
  end
107
204
 
108
205
  # Regression test for but fixed in Nagios patterns #30
109
206
  it "doesn't end in a semi-colon" do
110
- expect(grok['message']).to_not end_with(";")
207
+ message = grok['message']
208
+ message = message.last if message.is_a?(Array)
209
+ expect(message).to_not end_with(";")
111
210
  end
112
211
 
113
212
  end
114
213
 
115
- describe "NAGIOSLOGLINE - SERVICE ALERT" do
214
+ describe_pattern "NAGIOSLOGLINE - SERVICE ALERT", [ 'legacy', 'ecs-v1' ] do
116
215
 
117
- let(:value) { "[1427925689] SERVICE ALERT: varnish;Varnish Backend Connections;CRITICAL;SOFT;1;Current value: 154.0, warn threshold: 10.0, crit threshold: 20.0" }
118
- let(:grok) { grok_match(subject, value) }
216
+ let(:message) { "[1427925689] SERVICE ALERT: varnish;Varnish Backend Connections;CRITICAL;SOFT;1;Current value: 154.0, warn threshold: 10.0, crit threshold: 20.0" }
119
217
 
120
218
  it "a pattern pass the grok expression" do
121
219
  expect(grok).to pass
122
220
  end
123
221
 
124
222
  it "matches a simple message" do
125
- expect(subject).to match(value)
223
+ expect(pattern).to match(message)
126
224
  end
127
225
 
128
226
  it "generates the nagios_type field" do
129
- expect(grok).to include("nagios_type" => "SERVICE ALERT")
227
+ if ecs_compatibility?
228
+ expect(grok).to include("nagios" => hash_including("log" => hash_including("type" => 'SERVICE ALERT')))
229
+ else
230
+ expect(grok).to include("nagios_type" => "SERVICE ALERT")
231
+ end
130
232
  end
131
233
 
132
234
  it "generates the nagios_epoch field" do
133
- expect(grok).to include("nagios_epoch" => "1427925689")
235
+ if ecs_compatibility?
236
+ expect(grok).to include("timestamp" => "1427925689")
237
+ else
238
+ expect(grok).to include("nagios_epoch" => "1427925689")
239
+ end
134
240
  end
135
241
 
136
- it "generates the nagios_hostname field" do
137
- expect(grok).to include("nagios_hostname" => "varnish")
242
+ it "generates the hostname field" do
243
+ if ecs_compatibility?
244
+ expect(grok).to include("host" => { "hostname" => "varnish" })
245
+ else
246
+ expect(grok).to include("nagios_hostname" => "varnish")
247
+ end
138
248
  end
139
249
 
140
- it "generates the nagios_service field" do
141
- expect(grok).to include("nagios_service" => "Varnish Backend Connections")
250
+ it "generates the service field" do
251
+ if ecs_compatibility?
252
+ expect(grok).to include("service" => hash_including("name" => 'Varnish Backend Connections'))
253
+ else
254
+ expect(grok).to include("nagios_service" => "Varnish Backend Connections")
255
+ end
142
256
  end
143
257
 
144
258
  it "generates the nagios_state field" do
145
- expect(grok).to include("nagios_state" => "CRITICAL")
259
+ if ecs_compatibility?
260
+ expect(grok).to include("service" => hash_including("state" => "CRITICAL"))
261
+ else
262
+ expect(grok).to include("nagios_state" => "CRITICAL")
263
+ end
146
264
  end
147
265
 
148
266
  it "generates the nagios_statelevel field" do
149
- expect(grok).to include("nagios_statelevel" => "SOFT")
267
+ if ecs_compatibility?
268
+ expect(grok).to include("nagios" => hash_including("log" => hash_including("state_type" => "SOFT")))
269
+ else
270
+ expect(grok).to include("nagios_statelevel" => "SOFT")
271
+ end
272
+ end
273
+
274
+ it "generates the nagios_attempt field" do
275
+ if ecs_compatibility?
276
+ pending "TODO: are we hitting a grok bug here ?!?"
277
+ # [nagios][log][attempt]:int is clearly there (changing to :float gets this passing)
278
+ # ... but in this particular case we still get the raw "1" string back
279
+ expect(grok).to include("nagios" => hash_including("log" => hash_including("attempt" => 1)))
280
+ else
281
+ expect(grok).to include("nagios_attempt" => "1")
282
+ end
150
283
  end
151
284
 
152
285
  it "generates the nagios_message field" do
153
- expect(grok).to include("nagios_message" => "Current value: 154.0, warn threshold: 10.0, crit threshold: 20.0")
286
+ if ecs_compatibility?
287
+ expect(grok['message'].last).to eql "Current value: 154.0, warn threshold: 10.0, crit threshold: 20.0"
288
+ else
289
+ expect(grok).to include("nagios_message" => "Current value: 154.0, warn threshold: 10.0, crit threshold: 20.0")
290
+ end
154
291
  end
155
292
 
156
293
  end
157
294
 
158
- describe "NAGIOSLOGLINE - SERVICE NOTIFICATION" do
295
+ describe_pattern "NAGIOSLOGLINE - SERVICE NOTIFICATION", [ 'legacy', 'ecs-v1' ] do
159
296
 
160
- let(:value) { "[1427950229] SERVICE NOTIFICATION: nagiosadmin;varnish;Varnish Backend Connections;CRITICAL;notify-service-by-email;Current value: 337.0, warn threshold: 10.0, crit threshold: 20.0" }
161
- let(:grok) { grok_match(subject, value) }
297
+ let(:message) { "[1427950229] SERVICE NOTIFICATION: nagiosadmin;varnish;Varnish Backend Connections;CRITICAL;notify-service-by-email;Current value: 337.0, warn threshold: 10.0, crit threshold: 20.0" }
162
298
 
163
299
  it "a pattern pass the grok expression" do
164
300
  expect(grok).to pass
165
301
  end
166
302
 
167
303
  it "matches a simple message" do
168
- expect(subject).to match(value)
304
+ expect(pattern).to match(message)
169
305
  end
170
306
 
171
307
  it "generates the nagios_type field" do
172
- expect(grok).to include("nagios_type" => "SERVICE NOTIFICATION")
308
+ if ecs_compatibility?
309
+ expect(grok).to include("nagios" => hash_including("log" => hash_including("type" => 'SERVICE NOTIFICATION')))
310
+ else
311
+ expect(grok).to include("nagios_type" => "SERVICE NOTIFICATION")
312
+ end
173
313
  end
174
314
 
175
315
  it "generates the nagios_epoch field" do
176
- expect(grok).to include("nagios_epoch" => "1427950229")
316
+ if ecs_compatibility?
317
+ expect(grok).to include("timestamp" => "1427950229")
318
+ else
319
+ expect(grok).to include("nagios_epoch" => "1427950229")
320
+ end
177
321
  end
178
322
 
179
323
  it "generates the nagios_notifyname field" do
180
- expect(grok).to include("nagios_notifyname" => "nagiosadmin")
324
+ if ecs_compatibility?
325
+ expect(grok).to include("user" => { "name" => "nagiosadmin" }) # Nagios contact's contact_name
326
+ else
327
+ expect(grok).to include("nagios_notifyname" => "nagiosadmin")
328
+ end
181
329
  end
182
330
 
183
- it "generates the nagios_hostname field" do
184
- expect(grok).to include("nagios_hostname" => "varnish")
331
+ it "generates the hostname field" do
332
+ if ecs_compatibility?
333
+ expect(grok).to include("host" => { "hostname" => "varnish" })
334
+ else
335
+ expect(grok).to include("nagios_hostname" => "varnish")
336
+ end
185
337
  end
186
338
 
187
- it "generates the nagios_service field" do
188
- expect(grok).to include("nagios_service" => "Varnish Backend Connections")
339
+ it "generates the service field" do
340
+ if ecs_compatibility?
341
+ expect(grok).to include("service" => hash_including("name" => 'Varnish Backend Connections'))
342
+ else
343
+ expect(grok).to include("nagios_service" => "Varnish Backend Connections")
344
+ end
189
345
  end
190
346
 
191
347
  it "generates the nagios_state field" do
192
- expect(grok).to include("nagios_state" => "CRITICAL")
348
+ if ecs_compatibility?
349
+ expect(grok).to include("service" => hash_including("state" => "CRITICAL"))
350
+ else
351
+ expect(grok).to include("nagios_state" => "CRITICAL")
352
+ end
193
353
  end
194
354
 
195
355
  it "generates the nagios_contact field" do
196
- expect(grok).to include("nagios_contact" => "notify-service-by-email")
356
+ if ecs_compatibility?
357
+ expect(grok).to include("nagios" => hash_including("log" => hash_including("notification_command" => "notify-service-by-email")))
358
+ else
359
+ expect(grok).to include("nagios_contact" => "notify-service-by-email")
360
+ end
197
361
  end
198
362
 
199
363
  it "generates the nagios_message field" do
200
- expect(grok).to include("nagios_message" => "Current value: 337.0, warn threshold: 10.0, crit threshold: 20.0")
364
+ if ecs_compatibility?
365
+ expect(grok['message'].last).to eql "Current value: 337.0, warn threshold: 10.0, crit threshold: 20.0"
366
+ else
367
+ expect(grok).to include("nagios_message" => "Current value: 337.0, warn threshold: 10.0, crit threshold: 20.0")
368
+ end
201
369
  end
202
370
 
203
371
  end
204
372
 
205
373
 
206
- describe "NAGIOSLOGLINE - HOST NOTIFICATION" do
374
+ describe_pattern "NAGIOSLOGLINE - HOST NOTIFICATION", [ 'legacy', 'ecs-v1' ] do
207
375
 
208
- let(:value) { "[1429878690] HOST NOTIFICATION: nagiosadmin;nagioshost;DOWN;notify-host-by-email;CRITICAL - Socket timeout after 10 seconds" }
209
- let(:grok) { grok_match(subject, value) }
210
-
211
- it "a pattern pass the grok expression" do
212
- expect(grok).to pass
213
- end
376
+ let(:message) { "[1429878690] HOST NOTIFICATION: nagiosadmin;127.0.0.1;DOWN;host-notify-by-email;CRITICAL - Socket timeout after 10 seconds" }
214
377
 
215
378
  it "matches a simple message" do
216
- expect(subject).to match(value)
379
+ expect(pattern).to match(message)
217
380
  end
218
381
 
219
382
  it "generates the nagios_type field" do
220
- expect(grok).to include("nagios_type" => "HOST NOTIFICATION")
383
+ if ecs_compatibility?
384
+ expect(grok).to include("nagios" => hash_including("log" => hash_including("type" => "HOST NOTIFICATION")))
385
+ else
386
+ expect(grok).to include("nagios_type" => "HOST NOTIFICATION")
387
+ end
221
388
  end
222
389
 
223
390
  it "generates the nagios_epoch field" do
224
- expect(grok).to include("nagios_epoch" => "1429878690")
391
+ expect(grok).to include("nagios_epoch" => "1429878690") unless ecs_compatibility?
225
392
  end
226
393
 
227
394
  it "generates the nagios_notifyname field" do
228
- expect(grok).to include("nagios_notifyname" => "nagiosadmin")
395
+ if ecs_compatibility?
396
+ expect(grok).to include("user" => { "name" => "nagiosadmin" }) # Nagios contact's contact_name
397
+ else
398
+ expect(grok).to include("nagios_notifyname" => "nagiosadmin")
399
+ end
229
400
  end
230
401
 
231
402
  it "generates the nagios_hostname field" do
232
- expect(grok).to include("nagios_hostname" => "nagioshost")
403
+ if ecs_compatibility?
404
+ expect(grok).to include("host" => { "hostname" => "127.0.0.1" })
405
+ else
406
+ expect(grok).to include("nagios_hostname" => "127.0.0.1")
407
+ end
233
408
  end
234
409
 
235
410
  it "generates the nagios_contact field" do
236
- expect(grok).to include("nagios_contact" => "notify-host-by-email")
411
+ if ecs_compatibility?
412
+ expect(grok).to include("nagios" => hash_including("log" => hash_including("notification_command" => "host-notify-by-email")))
413
+ else
414
+ expect(grok).to include("nagios_contact" => "host-notify-by-email")
415
+ end
237
416
  end
238
417
 
239
418
  it "generates the nagios_message field" do
240
- expect(grok).to include("nagios_message" => "CRITICAL - Socket timeout after 10 seconds")
419
+ if ecs_compatibility?
420
+ expect(grok['message'].last).to eql "CRITICAL - Socket timeout after 10 seconds"
421
+ else
422
+ expect(grok).to include("nagios_message" => "CRITICAL - Socket timeout after 10 seconds")
423
+ end
241
424
  end
242
425
 
243
426
  end
427
+
428
+ describe_pattern "NAGIOSLOGLINE - SCHEDULE_HOST_DOWNTIME", [ 'legacy', 'ecs-v1' ] do
429
+
430
+ let(:message) { "[1334609999] EXTERNAL COMMAND: SCHEDULE_HOST_DOWNTIME;sputnik;1334665800;1334553600;1;0;120;nagiosadmin;test;" }
431
+
432
+ it "matches" do
433
+ if ecs_compatibility?
434
+ expect(grok).to include(
435
+ "host" => { "hostname" => "sputnik" },
436
+ "nagios" => { "log" => {
437
+ "type" => "EXTERNAL COMMAND",
438
+ "command" => "SCHEDULE_HOST_DOWNTIME",
439
+ "start_time" => "1334665800",
440
+ "end_time" => "1334553600",
441
+ "fixed" => '1',
442
+ "trigger_id" => '0',
443
+ "duration" => 120,
444
+
445
+ }},
446
+ "user" => { "name" => 'nagiosadmin' },
447
+ "message" => message
448
+ )
449
+ else
450
+ expect(grok).to include(
451
+ "nagios_epoch"=>"1334609999",
452
+ "nagios_type"=>"EXTERNAL COMMAND",
453
+ "nagios_command"=>"SCHEDULE_HOST_DOWNTIME",
454
+ "nagios_hostname"=>"sputnik",
455
+ "nagios_duration"=>"120",
456
+ "nagios_fixed"=>"1",
457
+ "nagios_trigger_id"=>"0",
458
+ "nagios_start_time"=>"1334665800",
459
+ "nagios_end_time"=>"1334553600",
460
+ "author"=>"nagiosadmin"
461
+ )
462
+ end
463
+ end
464
+ end
@@ -0,0 +1,123 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+ require "logstash/patterns/core"
4
+
5
+ describe_pattern "NETSCREENSESSIONLOG", ['legacy', 'ecs-v1'] do
6
+
7
+ context "traffic denied (Juniper)" do
8
+
9
+ let(:message) do
10
+ 'Jun 2 14:53:31 sample-host isg1000-A2: NetScreen device_id=0000011001000011 [Root]system-notification-00257(traffic): ' +
11
+ 'start_time="2015-11-11 10:02:10" duration=0 policy_id=244 service=https proto=6 src zone=Untrust dst zone=Trust ' +
12
+ 'action=Permit sent=0 rcvd=0 src=74.168.138.252 dst=72.72.72.72 src_port=1732 dst_port=443 ' +
13
+ 'src-xlated ip=1.255.20.1 port=22041 dst-xlated ip=1.244.136.50 port=443 session_id=488451 reason=Creation'
14
+ end
15
+
16
+ it 'matches' do
17
+ if ecs_compatibility?
18
+ expect(subject).to include("timestamp" => "Jun 2 14:53:31")
19
+ expect(subject).to include("netscreen"=>{
20
+ "session"=>{"id"=>"488451", "start_time"=>"2015-11-11 10:02:10", "duration"=>0, "type"=>"traffic", "reason"=>"Creation"},
21
+ "policy_id"=>"244", "service"=>"https", "protocol_number"=>6, "device_id"=>"0000011001000011"
22
+ })
23
+ expect(subject).to include("event"=>{"code"=>"00257", "action"=>"Permit"})
24
+ # expect(subject).to include("network"=>{"protocol"=>"https"})
25
+ expect(subject).to include("source"=>{"bytes"=>0, "nat"=>{"port"=>22041, "ip"=>"1.255.20.1"}, "port"=>1732, "address"=>"74.168.138.252"})
26
+ expect(subject).to include("destination"=>{"bytes"=>0, "nat"=>{"port"=>443, "ip"=>"1.244.136.50"}, "port"=>443, "address"=>"72.72.72.72"})
27
+ expect(subject).to include("observer"=>{
28
+ "ingress"=>{"zone"=>"Untrust"}, "hostname"=>"sample-host", "name"=>"isg1000-A2", "product"=>"NetScreen",
29
+ "egress"=>{"zone"=>"Trust"}
30
+ })
31
+ else
32
+ expect(subject).to include("date" => "Jun 2 14:53:31")
33
+ expect(subject).to include(
34
+ "device"=>"sample-host",
35
+ "device_id"=>"0000011001000011",
36
+ "start_time"=>"\"2015-11-11 10:02:10\"",
37
+ "duration"=>"0",
38
+ "policy_id"=>"244",
39
+ "service"=>"https",
40
+ "proto"=>"6",
41
+ "src_zone"=>"Untrust", "dst_zone"=>"Trust",
42
+ "action"=>"Permit",
43
+ "sent"=>"0", "rcvd"=>"0",
44
+ "src_ip"=>"74.168.138.252", "dst_ip"=>"72.72.72.72",
45
+ "src_port"=>"1732", "dst_port"=>"443",
46
+ "src_xlated_ip"=>"1.255.20.1", "src_xlated_port"=>"22041",
47
+ "dst_xlated_ip"=>"1.244.136.50", "dst_xlated_port"=>"443",
48
+ "session_id"=>"488451", "reason"=>"Creation",
49
+ )
50
+ end
51
+ end
52
+
53
+ end
54
+
55
+ context "traffic denied (without port/xlated/session_id/reason suffix)" do
56
+
57
+ let(:message) do
58
+ 'Mar 18 17:56:52 192.168.56.11 lowly_lizard: NetScreen device_id=netscreen2 [Root]system-notification-00257(traffic): ' +
59
+ 'start_time="2009-03-18 16:07:06" duration=0 policy_id=320001 service=msrpc Endpoint Mapper(tcp) proto=6 ' +
60
+ 'src zone=Null dst zone=self action=Deny sent=0 rcvd=16384 src=21.10.90.125 dst=23.16.1.1'
61
+ end
62
+
63
+ it 'matches in ECS mode' do
64
+ if ecs_compatibility?
65
+ expect(subject).to include("timestamp" => "Mar 18 17:56:52")
66
+ expect(subject).to include("netscreen"=>{
67
+ "device_id"=>"netscreen2",
68
+ "policy_id"=>"320001",
69
+ "service"=>"msrpc Endpoint Mapper(tcp)",
70
+ "protocol_number"=>6,
71
+ "session"=>{"start_time"=>"2009-03-18 16:07:06", "type"=>"traffic", "duration"=>0}
72
+ })
73
+ expect(subject).to include("source"=>{"address"=>"21.10.90.125", "bytes"=>0})
74
+ expect(subject).to include("destination"=>{"address"=>"23.16.1.1", "bytes"=>16384})
75
+ else
76
+ expect(grok['tags']).to include('_grokparsefailure')
77
+ end
78
+ end
79
+ end
80
+
81
+ context "'standard' traffic denied" do
82
+
83
+ let(:message) do
84
+ 'Jun 2 14:53:31 fire00 aka1: NetScreen device_id=aka1 [Root]system-notification-00257(traffic): start_time="2006-06-02 14:53:30" ' +
85
+ 'duration=0 policy_id=120 service=udp/port:17210 proto=17 src zone=Trust dst zone=DMZ action=Deny sent=0 rcvd=0 ' +
86
+ 'src=192.168.2.2 dst=1.2.3.4 src_port=53 dst_port=17210'
87
+ end
88
+
89
+ it 'matches (in ECS mode)' do
90
+ if ecs_compatibility?
91
+ expect(subject).to include("event"=>{"action"=>"Deny", "code"=>"00257"})
92
+ else
93
+ expect(grok['tags']).to include('_grokparsefailure')
94
+ expect(subject).to_not include("date" => "Jun 2 14:53:31")
95
+ end
96
+ end
97
+
98
+ context "(with session id)" do
99
+
100
+ let(:message) do
101
+ super() + ' session_id=0 reason=Traffic Denied'
102
+ end
103
+
104
+ it 'matches (in ECS mode)' do
105
+ if ecs_compatibility?
106
+ expect(subject).to include("netscreen"=>hash_including("device_id"=>"aka1", "service"=>"udp/port:17210",
107
+ "session"=>hash_including("reason"=>"Traffic Denied")))
108
+ expect(subject).to include("observer"=>{
109
+ "ingress"=>{"zone"=>"Trust"},
110
+ "egress"=>{"zone"=>"DMZ"}, "hostname"=>"fire00", "name"=>"aka1",
111
+ "product"=>"NetScreen"
112
+ })
113
+ else
114
+ expect(grok['tags']).to include('_grokparsefailure')
115
+ expect(subject).to_not include("date" => "Jun 2 14:53:31")
116
+ end
117
+ end
118
+
119
+ end
120
+
121
+ end
122
+
123
+ end