logstash-patterns-core 4.0.2 → 4.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +149 -8
  3. data/CONTRIBUTORS +1 -0
  4. data/Gemfile +11 -1
  5. data/LICENSE +199 -10
  6. data/README.md +12 -19
  7. data/lib/logstash/patterns/core.rb +11 -3
  8. data/logstash-patterns-core.gemspec +1 -1
  9. data/patterns/ecs-v1/aws +28 -0
  10. data/patterns/ecs-v1/bacula +53 -0
  11. data/patterns/ecs-v1/bind +13 -0
  12. data/patterns/ecs-v1/bro +30 -0
  13. data/patterns/ecs-v1/exim +26 -0
  14. data/patterns/ecs-v1/firewalls +111 -0
  15. data/patterns/ecs-v1/grok-patterns +95 -0
  16. data/patterns/ecs-v1/haproxy +40 -0
  17. data/patterns/ecs-v1/httpd +17 -0
  18. data/patterns/ecs-v1/java +34 -0
  19. data/patterns/ecs-v1/junos +13 -0
  20. data/patterns/ecs-v1/linux-syslog +16 -0
  21. data/patterns/ecs-v1/maven +1 -0
  22. data/patterns/ecs-v1/mcollective +4 -0
  23. data/patterns/ecs-v1/mongodb +7 -0
  24. data/patterns/ecs-v1/nagios +124 -0
  25. data/patterns/ecs-v1/postgresql +2 -0
  26. data/patterns/ecs-v1/rails +13 -0
  27. data/patterns/ecs-v1/redis +3 -0
  28. data/patterns/ecs-v1/ruby +2 -0
  29. data/patterns/ecs-v1/squid +6 -0
  30. data/patterns/ecs-v1/zeek +33 -0
  31. data/patterns/legacy/aws +14 -0
  32. data/patterns/{bacula → legacy/bacula} +5 -5
  33. data/patterns/legacy/bind +3 -0
  34. data/patterns/{bro → legacy/bro} +0 -0
  35. data/patterns/{exim → legacy/exim} +8 -2
  36. data/patterns/{firewalls → legacy/firewalls} +7 -2
  37. data/patterns/{grok-patterns → legacy/grok-patterns} +5 -13
  38. data/patterns/{haproxy → legacy/haproxy} +1 -1
  39. data/patterns/legacy/httpd +15 -0
  40. data/patterns/{java → legacy/java} +1 -4
  41. data/patterns/{junos → legacy/junos} +0 -0
  42. data/patterns/{linux-syslog → legacy/linux-syslog} +1 -1
  43. data/patterns/legacy/maven +1 -0
  44. data/patterns/{mcollective → legacy/mcollective} +0 -0
  45. data/patterns/{mcollective-patterns → legacy/mcollective-patterns} +0 -0
  46. data/patterns/{mongodb → legacy/mongodb} +0 -0
  47. data/patterns/{nagios → legacy/nagios} +1 -1
  48. data/patterns/{postgresql → legacy/postgresql} +0 -0
  49. data/patterns/{rails → legacy/rails} +0 -0
  50. data/patterns/legacy/redis +3 -0
  51. data/patterns/{ruby → legacy/ruby} +0 -0
  52. data/patterns/legacy/squid +4 -0
  53. data/spec/patterns/aws_spec.rb +395 -0
  54. data/spec/patterns/bacula_spec.rb +367 -0
  55. data/spec/patterns/bind_spec.rb +78 -0
  56. data/spec/patterns/bro_spec.rb +613 -0
  57. data/spec/patterns/core_spec.rb +271 -16
  58. data/spec/patterns/exim_spec.rb +201 -0
  59. data/spec/patterns/firewalls_spec.rb +683 -49
  60. data/spec/patterns/haproxy_spec.rb +253 -28
  61. data/spec/patterns/httpd_spec.rb +291 -10
  62. data/spec/patterns/java_spec.rb +375 -0
  63. data/spec/patterns/junos_spec.rb +101 -0
  64. data/spec/patterns/maven_spec.rb +61 -0
  65. data/spec/patterns/mcollective_spec.rb +35 -0
  66. data/spec/patterns/mongodb_spec.rb +170 -33
  67. data/spec/patterns/nagios_spec.rb +299 -78
  68. data/spec/patterns/netscreen_spec.rb +123 -0
  69. data/spec/patterns/rails3_spec.rb +87 -29
  70. data/spec/patterns/redis_spec.rb +207 -0
  71. data/spec/patterns/shorewall_spec.rb +85 -74
  72. data/spec/patterns/squid_spec.rb +139 -0
  73. data/spec/patterns/syslog_spec.rb +266 -8
  74. data/spec/spec_helper.rb +83 -5
  75. metadata +74 -26
  76. data/patterns/aws +0 -11
  77. data/patterns/redis +0 -3
  78. data/spec/patterns/bro.rb +0 -126
  79. data/spec/patterns/s3_spec.rb +0 -132
@@ -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
@@ -2,55 +2,113 @@
2
2
  require "spec_helper"
3
3
  require "logstash/patterns/core"
4
4
 
5
- describe "RAILS" do
6
- let(:rails3_pattern) { "RAILS3" }
5
+ describe_pattern "RAILS3", ['legacy', 'ecs-v1'] do
7
6
 
8
- context "Parsing RAILS3 single-line log from raw log file" do
7
+ context "single-line log" do
9
8
 
10
- let(:value) { 'Started POST "/api/v3/internal/allowed" for 127.0.0.1 at 2015-08-05 11:37:01 +0200' }
11
-
12
- subject { grok_match(rails3_pattern, value) }
9
+ let(:message) { 'Started POST "/api/v3/internal/allowed" for 127.0.0.1 at 2015-08-05 11:37:01 +0200' }
13
10
 
14
11
  # Started
15
- it { should include("verb" => "POST" ) }
16
- it { should include("request" => "/api/v3/internal/allowed" ) }
12
+ it do
13
+ if ecs_compatibility?
14
+ should include("http" => hash_including("request" => { "method" => "POST" }))
15
+ else
16
+ should include("verb" => "POST")
17
+ end
18
+ end
19
+
20
+ it do
21
+ if ecs_compatibility?
22
+ else
23
+ should include("request" => "/api/v3/internal/allowed")
24
+ end
25
+ end
17
26
  # for
18
- it { should include("clientip" => "127.0.0.1" ) }
27
+ it do
28
+ if ecs_compatibility?
29
+ should include("source" => { "address" => "127.0.0.1" })
30
+ else
31
+ should include("clientip" => "127.0.0.1")
32
+ end
33
+ end
19
34
  # at
20
35
  it { should include("timestamp" => "2015-08-05 11:37:01 +0200" ) }
21
36
  end
22
37
 
23
- context "Parsing RAILS3 multi-line log from raw log file" do
38
+ context "multi-line log" do
24
39
 
25
- let(:value) { 'Started GET "/puppet/postfix/notes?target_id=162&target_type=issue&last_fetched_at=1438695732" for 127.0.0.1 at 2015-08-05 07:40:22 +0200
40
+ let(:message) { 'Started GET "/puppet/postfix/notes?target_id=162&target_type=issue&last_fetched_at=1438695732" for 127.0.0.1 at 2015-08-05 07:40:22 +0200
26
41
  Processing by Projects::NotesController#index as JSON
27
42
  Parameters: {"target_id"=>"162", "target_type"=>"issue", "last_fetched_at"=>"1438695732", "namespace_id"=>"puppet", "project_id"=>"postfix"}
28
- Completed 200 OK in 640ms (Views: 1.7ms | ActiveRecord: 91.0ms)' }
29
- subject { grok_match(rails3_pattern, value) }
43
+ Completed 200 OK in 640ms (Views: 1.7ms | ActiveRecord: 91.0ms)' }
30
44
 
31
45
  # started
32
- it { should include("verb" => "GET" ) }
33
- it { should include("request" => "/puppet/postfix/notes?target_id=162&target_type=issue&last_fetched_at=1438695732" ) }
46
+ it do
47
+ if ecs_compatibility?
48
+ should include("http" => hash_including("request" => { "method" => "GET" }))
49
+ else
50
+ should include("verb" => "GET")
51
+ end
52
+ end
53
+
54
+ it do
55
+ if ecs_compatibility?
56
+ should include("url" => {"original"=>"/puppet/postfix/notes?target_id=162&target_type=issue&last_fetched_at=1438695732"})
57
+ else
58
+ should include("request" => "/puppet/postfix/notes?target_id=162&target_type=issue&last_fetched_at=1438695732" )
59
+ end
60
+ end
34
61
  # for
35
- it { should include("clientip" => "127.0.0.1" ) }
62
+ it do
63
+ if ecs_compatibility?
64
+ should include("source" => { "address" => "127.0.0.1" })
65
+ else
66
+ should include("clientip" => "127.0.0.1")
67
+ end
68
+ end
36
69
  # at
37
- it { should include("timestamp" => "2015-08-05 07:40:22 +0200" ) }
70
+ it { should include("timestamp" => "2015-08-05 07:40:22 +0200") }
38
71
  # Processing by
39
- it { should include("controller" => "Projects::NotesController" ) }
40
- it { should include("action" => "index" ) }
72
+ it do
73
+ if ecs_compatibility?
74
+ should include("rails" => hash_including("controller" => { "class"=>"Projects::NotesController", "action"=>"index" }))
75
+ else
76
+ should include("controller" => "Projects::NotesController")
77
+ should include("action" => "index")
78
+ end
79
+ end
41
80
  # as
42
- it { should include("format" => "JSON" ) }
81
+ it do
82
+ if ecs_compatibility?
83
+ should include("rails" => hash_including("request" => hash_including("format" => 'JSON')))
84
+ else
85
+ should include("format" => "JSON" )
86
+ end
87
+ end
43
88
  # Parameters
44
- it { should include("params" => '"target_id"=>"162", "target_type"=>"issue", "last_fetched_at"=>"1438695732", "namespace_id"=>"puppet", "project_id"=>"postfix"' ) }
89
+ it do
90
+ params = '"target_id"=>"162", "target_type"=>"issue", "last_fetched_at"=>"1438695732", "namespace_id"=>"puppet", "project_id"=>"postfix"'
91
+ if ecs_compatibility?
92
+ should include("rails" => hash_including("request" => hash_including("params" => params)))
93
+ else
94
+ should include("params" => params)
95
+ end
96
+ end
45
97
  # Completed
46
- it { should include("response" => "200" ) }
98
+ it do
99
+ if ecs_compatibility?
100
+ should include("http" => hash_including("response" => { "status_code" => 200 }))
101
+ else
102
+ should include("response" => "200" )
103
+ end
104
+ end
47
105
  # in
48
- it { should include("totalms" => "640" ) }
49
- # (Views:
50
- it { should include("viewms" => "1.7" ) }
51
- # | ActiveRecord:
52
- it { should include("activerecordms" => "91.0" ) }
53
-
106
+ it do
107
+ if ecs_compatibility?
108
+ should include("rails" => hash_including("request" => hash_including("duration" => { "total" => 640.0, "view" => 1.7, "active_record" => 91.0 })))
109
+ else
110
+ should include("totalms" => "640", "viewms" => "1.7", "activerecordms" => "91.0")
111
+ end
112
+ end
54
113
  end
55
-
56
114
  end
@@ -0,0 +1,207 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+ require "logstash/patterns/core"
4
+
5
+ describe_pattern 'REDISTIMESTAMP', [ 'legacy', 'ecs-v1' ] do
6
+
7
+ let(:message) { '14 Nov 07:01:22.119'}
8
+
9
+ it "a pattern pass the grok expression" do
10
+ expect(grok_match(pattern, message)).to pass
11
+ end
12
+
13
+ end
14
+
15
+ describe_pattern 'REDISLOG', [ 'legacy', 'ecs-v1' ] do
16
+
17
+ let(:message) { "[4018] 14 Nov 07:01:22.119 * Background saving terminated with success" }
18
+
19
+ it "a pattern pass the grok expression" do
20
+ expect(grok).to pass
21
+ end
22
+
23
+ it "generates the pid field" do
24
+ if ecs_compatibility?
25
+ expect(grok).to include("process" => { 'pid' => 4018 })
26
+ else
27
+ expect(grok).to include("pid" => "4018")
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ describe_pattern 'REDISMONLOG', [ 'legacy', 'ecs-v1' ] do
34
+
35
+ context "simple command" do
36
+
37
+ let(:message) { "1470637867.953466 [0 195.168.1.1:52500] \"info\"" }
38
+
39
+ it "a pattern pass the grok expression" do
40
+ expect(grok).to pass
41
+ end
42
+
43
+ it "generates the timestamp field" do
44
+ expect(grok).to include("timestamp" => "1470637867.953466")
45
+ end
46
+
47
+ it "generates the database field" do
48
+ if ecs_compatibility?
49
+ expect(grok).to include("redis" => hash_including('database' => { 'id' => '0' }))
50
+ else
51
+ expect(grok).to include("database" => "0")
52
+ end
53
+ end
54
+
55
+ it "generates the client field" do
56
+ if ecs_compatibility?
57
+ expect(grok).to include("client" => hash_including('ip' => '195.168.1.1'))
58
+ else
59
+ expect(grok).to include("client" => "195.168.1.1")
60
+ end
61
+ end
62
+
63
+ it "generates the port field" do
64
+ if ecs_compatibility?
65
+ expect(grok).to include("client" => hash_including('port' => 52500))
66
+ else
67
+ expect(grok).to include("port" => "52500")
68
+ end
69
+ end
70
+
71
+ it "generates the command field" do
72
+ if ecs_compatibility?
73
+ expect(grok).to include("redis" => hash_including('command' => { 'name' => 'info' }))
74
+ else
75
+ expect(grok).to include("command" => "info")
76
+ end
77
+ end
78
+
79
+ end
80
+
81
+ context "one param command" do
82
+
83
+ let(:message) { "1339518083.107412 [0 127.0.0.1:60866] \"keys\" \"*\"" }
84
+
85
+ it "a pattern pass the grok expression" do
86
+ expect(grok).to pass
87
+ end
88
+
89
+ it "generates the timestamp field" do
90
+ expect(grok).to include("timestamp" => "1339518083.107412")
91
+ end
92
+
93
+ it "generates the database field" do
94
+ if ecs_compatibility?
95
+ expect(grok).to include("redis" => hash_including('database' => { 'id' => '0' }))
96
+ else
97
+ expect(grok).to include("database" => "0")
98
+ end
99
+ end
100
+
101
+ it "generates the client field" do
102
+ if ecs_compatibility?
103
+ expect(grok).to include("client" => hash_including('ip' => '127.0.0.1'))
104
+ else
105
+ expect(grok).to include("client" => "127.0.0.1")
106
+ end
107
+ end
108
+
109
+ it "generates the port field" do
110
+ if ecs_compatibility?
111
+ expect(grok).to include("client" => hash_including('port' => 60866))
112
+ else
113
+ expect(grok).to include("port" => "60866")
114
+ end
115
+ end
116
+
117
+ it "generates the command field" do
118
+ if ecs_compatibility?
119
+ expect(grok).to include("redis" => hash_including('command' => hash_including('name' => 'keys')))
120
+ else
121
+ expect(grok).to include("command" => "keys")
122
+ end
123
+ end
124
+
125
+ it "generates the params field" do
126
+ if ecs_compatibility?
127
+ expect(grok).to include("redis" => hash_including('command' => hash_including('args' => '"*"')))
128
+ else
129
+ expect(grok).to include("params" => "\"*\"")
130
+ end
131
+ end
132
+
133
+ end
134
+
135
+ end
136
+
137
+ describe_pattern "REDISMONLOG" do
138
+
139
+ context 'two param command' do
140
+
141
+ let(:message) { "1470637925.186681 [0 127.0.0.1:39404] \"rpush\" \"my:special:key\" \"{\\\"data\\\":\"cdr\\\",\\\"payload\\\":\\\"json\\\"}\"" }
142
+
143
+ it "a pattern pass the grok expression" do
144
+ expect(grok).to pass
145
+ end
146
+
147
+ it "generates the timestamp field" do
148
+ expect(grok).to include("timestamp" => "1470637925.186681")
149
+ end
150
+
151
+ it "generates the database field" do
152
+ expect(grok).to include("database" => "0")
153
+ end
154
+
155
+ it "generates the client field" do
156
+ expect(grok).to include("client" => "127.0.0.1")
157
+ end
158
+
159
+ it "generates the port field" do
160
+ expect(grok).to include("port" => "39404")
161
+ end
162
+
163
+ it "generates the command field" do
164
+ expect(grok).to include("command" => "rpush")
165
+ end
166
+
167
+ it "generates the params field" do
168
+ expect(grok).to include("params" => "\"my:special:key\" \"{\\\"data\\\":\"cdr\\\",\\\"payload\\\":\\\"json\\\"}\"")
169
+ end
170
+
171
+ end
172
+
173
+ context "variadic command" do
174
+
175
+ let(:message) { "1470637875.777457 [15 195.168.1.1:52500] \"intentionally\" \"broken\" \"variadic\" \"log\" \"entry\"" }
176
+
177
+ it "a pattern pass the grok expression" do
178
+ expect(grok).to pass
179
+ end
180
+
181
+ it "generates the timestamp field" do
182
+ expect(grok).to include("timestamp" => "1470637875.777457")
183
+ end
184
+
185
+ it "generates the database field" do
186
+ expect(grok).to include("database" => "15")
187
+ end
188
+
189
+ it "generates the client field" do
190
+ expect(grok).to include("client" => "195.168.1.1")
191
+ end
192
+
193
+ it "generates the port field" do
194
+ expect(grok).to include("port" => "52500")
195
+ end
196
+
197
+ it "generates the command field" do
198
+ expect(grok).to include("command" => "intentionally")
199
+ end
200
+
201
+ it "generates the params field" do
202
+ expect(grok).to include("params" => "\"broken\" \"variadic\" \"log\" \"entry\"")
203
+ end
204
+
205
+ end
206
+
207
+ end