logstash-patterns-core 4.1.0 → 4.3.1
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 +118 -0
- data/CONTRIBUTORS +1 -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} +5 -5
- data/patterns/{haproxy → legacy/haproxy} +1 -1
- data/patterns/{httpd → legacy/httpd} +3 -3
- 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 +78 -0
- data/spec/patterns/bro_spec.rb +613 -0
- data/spec/patterns/core_spec.rb +271 -6
- 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 +255 -77
- 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 +157 -121
- 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 -30
- 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
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
require "logstash/patterns/core"
|
4
|
+
|
5
|
+
describe_pattern "MCOLLECTIVE", ['legacy', 'ecs-v1'] do
|
6
|
+
|
7
|
+
let(:message) { "I, [2010-12-29T11:15:32.321744 #11479] INFO -- : mcollectived:33 The Marionette Collective 1.1.0 started logging at info level" }
|
8
|
+
|
9
|
+
it do
|
10
|
+
should include("timestamp" => "2010-12-29T11:15:32.321744")
|
11
|
+
end
|
12
|
+
|
13
|
+
it do
|
14
|
+
if ecs_compatibility?
|
15
|
+
should include("process" => { "pid" => 11479 })
|
16
|
+
else
|
17
|
+
should include("pid" => "11479")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it do
|
22
|
+
if ecs_compatibility?
|
23
|
+
should include("log" => hash_including("level" => "INFO"))
|
24
|
+
else
|
25
|
+
should include("event_level" => "INFO")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# NOTE: pattern seems unfinished - missing match of remaining message
|
30
|
+
it 'should have extracted message' do
|
31
|
+
# but did not :
|
32
|
+
expect( subject['message'] ).to eql message
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -2,83 +2,220 @@
|
|
2
2
|
require "spec_helper"
|
3
3
|
require "logstash/patterns/core"
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
let(:pattern) { "MONGO3_LOG" }
|
5
|
+
describe_pattern "MONGO3_LOG", ['legacy', 'ecs-v1'] do
|
8
6
|
|
9
7
|
context "parsing an standard/basic message" do
|
10
8
|
|
11
|
-
let(:
|
12
|
-
|
13
|
-
subject { grok_match(pattern, value) }
|
9
|
+
let(:message) { "2014-11-03T18:28:32.450-0500 I NETWORK [initandlisten] waiting for connections on port 27017" }
|
14
10
|
|
15
11
|
it { should include("timestamp" => "2014-11-03T18:28:32.450-0500") }
|
16
12
|
|
17
|
-
it
|
13
|
+
it do
|
14
|
+
if ecs_compatibility?
|
15
|
+
should include("log" => { 'level' => "I" })
|
16
|
+
else
|
17
|
+
should include("severity" => "I")
|
18
|
+
end
|
19
|
+
end
|
18
20
|
|
19
|
-
it
|
21
|
+
it do
|
22
|
+
if ecs_compatibility?
|
23
|
+
should include("mongodb" => hash_including("component" => "NETWORK"))
|
24
|
+
else
|
25
|
+
should include("component" => "NETWORK")
|
26
|
+
end
|
27
|
+
end
|
20
28
|
|
21
|
-
it
|
29
|
+
it do
|
30
|
+
if ecs_compatibility?
|
31
|
+
should include("mongodb" => hash_including("context" => "initandlisten"))
|
32
|
+
else
|
33
|
+
should include("context" => "initandlisten")
|
34
|
+
end
|
35
|
+
end
|
22
36
|
|
23
37
|
it "generates a message field" do
|
24
|
-
expect(subject["message"]).to
|
38
|
+
expect(subject["message"]).to eql [ message, "waiting for connections on port 27017" ]
|
25
39
|
end
|
26
40
|
end
|
27
41
|
|
28
42
|
context "parsing a message with a missing component" do
|
29
43
|
|
30
|
-
let(:
|
44
|
+
let(:message) { "2015-02-24T18:17:47.148+0000 F - [conn11] Got signal: 11 (Segmentation fault)." }
|
31
45
|
|
32
|
-
|
46
|
+
it 'matches' do
|
47
|
+
should include("timestamp" => "2015-02-24T18:17:47.148+0000")
|
33
48
|
|
34
|
-
|
49
|
+
if ecs_compatibility?
|
50
|
+
expect( grok_result['mongodb'].keys ).to_not include("component")
|
51
|
+
else
|
52
|
+
should include("component" => "-")
|
53
|
+
end
|
35
54
|
|
36
|
-
|
55
|
+
if ecs_compatibility?
|
56
|
+
should include("log" => { 'level' => "F" })
|
57
|
+
else
|
58
|
+
should include("severity" => "F")
|
59
|
+
end
|
37
60
|
|
38
|
-
|
39
|
-
|
40
|
-
|
61
|
+
if ecs_compatibility?
|
62
|
+
should include("mongodb" => hash_including("context" => "conn11"))
|
63
|
+
else
|
64
|
+
should include("context" => "conn11")
|
65
|
+
end
|
66
|
+
end
|
41
67
|
|
42
68
|
it "generates a message field" do
|
43
|
-
expect(subject["message"]).to
|
69
|
+
expect(subject["message"]).to eql [ message, "Got signal: 11 (Segmentation fault)." ]
|
44
70
|
end
|
45
71
|
end
|
46
72
|
|
47
73
|
context "parsing a message with a multiwords context" do
|
48
74
|
|
49
|
-
let(:
|
50
|
-
|
51
|
-
subject { grok_match(pattern, value) }
|
75
|
+
let(:message) { "2015-04-23T06:57:28.256+0200 I JOURNAL [journal writer] Journal writer thread started" }
|
52
76
|
|
53
|
-
it
|
77
|
+
it 'matches' do
|
78
|
+
should include("timestamp" => "2015-04-23T06:57:28.256+0200")
|
54
79
|
|
55
|
-
|
80
|
+
if ecs_compatibility?
|
81
|
+
should include("log" => { 'level' => "I" })
|
82
|
+
else
|
83
|
+
should include("severity" => "I")
|
84
|
+
end
|
56
85
|
|
57
|
-
|
86
|
+
if ecs_compatibility?
|
87
|
+
should include("mongodb" => hash_including("component" => "JOURNAL"))
|
88
|
+
else
|
89
|
+
should include("component" => "JOURNAL")
|
90
|
+
end
|
58
91
|
|
59
|
-
|
92
|
+
if ecs_compatibility?
|
93
|
+
should include("mongodb" => hash_including("context" => "journal writer"))
|
94
|
+
else
|
95
|
+
should include("context" => "journal writer")
|
96
|
+
end
|
97
|
+
end
|
60
98
|
|
61
99
|
it "generates a message field" do
|
62
100
|
expect(subject["message"]).to include("Journal writer thread started")
|
63
101
|
end
|
102
|
+
|
103
|
+
context '3.6 simple log line' do
|
104
|
+
|
105
|
+
let(:message) do
|
106
|
+
'2020-08-13T11:58:09.672+0200 I NETWORK [conn2] end connection 127.0.0.1:41258 (1 connection now open)'
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'matches' do
|
110
|
+
should include("timestamp" => "2020-08-13T11:58:09.672+0200")
|
111
|
+
|
112
|
+
if ecs_compatibility?
|
113
|
+
should include("mongodb" => hash_including("component" => "NETWORK"))
|
114
|
+
else
|
115
|
+
should include("component" => "NETWORK")
|
116
|
+
end
|
117
|
+
|
118
|
+
if ecs_compatibility?
|
119
|
+
should include("mongodb" => hash_including("context" => "conn2"))
|
120
|
+
else
|
121
|
+
should include("context" => "conn2")
|
122
|
+
end
|
123
|
+
|
124
|
+
expect(subject["message"]).to include("end connection 127.0.0.1:41258 (1 connection now open)")
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
context '3.6 long log line' do
|
130
|
+
|
131
|
+
let(:command) do
|
132
|
+
'command config.$cmd command: createIndexes { createIndexes: "system.sessions", ' +
|
133
|
+
'indexes: [ { key: { lastUse: 1 }, name: "lsidTTLIndex", expireAfterSeconds: 1800 } ], $db: "config" } ' +
|
134
|
+
'numYields:0 reslen:101 locks:{ Global: { acquireCount: { r: 2, w: 2 } }, Database: { acquireCount: { w: 2 } }, ' +
|
135
|
+
'Collection: { acquireCount: { w: 1 } } } protocol:op_msg 0ms'
|
136
|
+
end
|
137
|
+
|
138
|
+
let(:message) do
|
139
|
+
'2020-08-13T11:57:45.259+0200 I COMMAND [LogicalSessionCacheRefresh] ' + command
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'matches' do
|
143
|
+
should include("timestamp" => "2020-08-13T11:57:45.259+0200")
|
144
|
+
|
145
|
+
if ecs_compatibility?
|
146
|
+
should include("mongodb" => hash_including("component" => "COMMAND"))
|
147
|
+
else
|
148
|
+
should include("component" => "COMMAND")
|
149
|
+
end
|
150
|
+
|
151
|
+
if ecs_compatibility?
|
152
|
+
should include("mongodb" => hash_including("context" => "LogicalSessionCacheRefresh"))
|
153
|
+
else
|
154
|
+
should include("context" => "LogicalSessionCacheRefresh")
|
155
|
+
end
|
156
|
+
|
157
|
+
expect(subject["message"]).to eql [message, command]
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
64
162
|
end
|
65
163
|
|
66
164
|
context "parsing a message without context" do
|
67
165
|
|
68
|
-
let(:
|
69
|
-
|
70
|
-
subject { grok_match(pattern, value) }
|
166
|
+
let(:message) { "2015-04-23T07:00:13.864+0200 I CONTROL Ctrl-C signal" }
|
71
167
|
|
72
|
-
it
|
168
|
+
it 'matches' do
|
169
|
+
should include("timestamp" => "2015-04-23T07:00:13.864+0200")
|
73
170
|
|
74
|
-
|
171
|
+
if ecs_compatibility?
|
172
|
+
should include("log" => { 'level' => "I" })
|
173
|
+
else
|
174
|
+
should include("severity" => "I")
|
175
|
+
end
|
75
176
|
|
76
|
-
|
177
|
+
if ecs_compatibility?
|
178
|
+
should include("mongodb" => hash_including("component" => "CONTROL"))
|
179
|
+
else
|
180
|
+
should include("component" => "CONTROL")
|
181
|
+
end
|
77
182
|
|
78
|
-
|
183
|
+
if ecs_compatibility?
|
184
|
+
expect( grok_result['mongodb'].keys ).to_not include("context")
|
185
|
+
else
|
186
|
+
should_not have_key("context")
|
187
|
+
end
|
188
|
+
end
|
79
189
|
|
80
190
|
it "generates a message field" do
|
81
|
-
expect(subject["message"]).to
|
191
|
+
expect(subject["message"]).to eql [ message, "Ctrl-C signal" ]
|
82
192
|
end
|
83
193
|
end
|
84
194
|
end
|
195
|
+
|
196
|
+
describe_pattern "MONGO_SLOWQUERY", ['legacy', 'ecs-v1'] do
|
197
|
+
|
198
|
+
let(:message) do
|
199
|
+
"[conn11485496] query sample.User query: { clientId: 12345 } ntoreturn:0 ntoskip:0 nscanned:287011 keyUpdates:0 numYields: 2 locks(micros) r:4187700 nreturned:18 reslen:14019 2340ms"
|
200
|
+
end
|
201
|
+
|
202
|
+
it do
|
203
|
+
if ecs_compatibility?
|
204
|
+
should include("mongodb" => {
|
205
|
+
"database" => "sample", "collection" => "User",
|
206
|
+
"query" => { "original"=>"{ clientId: 12345 }" },
|
207
|
+
"profile" => {
|
208
|
+
"op" => "query",
|
209
|
+
"ntoreturn" => 0, "ntoskip" => 0, "nscanned" => 287011, "nreturned" => 18,
|
210
|
+
"duration" => 2340
|
211
|
+
}
|
212
|
+
})
|
213
|
+
else
|
214
|
+
should include("database" => "sample", "collection" => "User")
|
215
|
+
should include("ntoreturn" => '0', "ntoskip" => '0', "nscanned" => "287011", "nreturned" => "18")
|
216
|
+
should include("query" => "{ clientId: 12345 }")
|
217
|
+
should include("duration" => "2340")
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
@@ -2,242 +2,463 @@
|
|
2
2
|
require "spec_helper"
|
3
3
|
require "logstash/patterns/core"
|
4
4
|
|
5
|
-
|
5
|
+
describe_pattern "NAGIOSLOGLINE - CURRENT HOST STATE", [ 'legacy', 'ecs-v1' ] do
|
6
6
|
|
7
|
-
let(:
|
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(
|
14
|
+
expect(pattern).to match(message)
|
16
15
|
end
|
17
16
|
|
18
17
|
it "generates the nagios_epoch field" do
|
19
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
59
|
+
describe_pattern "NAGIOSLOGLINE - CURRENT SERVICE STATE", [ 'legacy', 'ecs-v1' ] do
|
41
60
|
|
42
|
-
let(:
|
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(
|
68
|
+
expect(pattern).to match(message)
|
51
69
|
end
|
52
70
|
|
53
71
|
it "generates the nagios_type field" do
|
54
|
-
|
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
|
-
|
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
|
-
|
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
|
66
|
-
|
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
|
70
|
-
|
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
|
-
|
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
|
-
|
79
|
-
|
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
|
-
|
169
|
+
describe_pattern "NAGIOSLOGLINE - TIMEPERIOD TRANSITION", [ 'legacy', 'ecs-v1' ] do
|
84
170
|
|
85
|
-
let(:
|
86
|
-
let(:grok) { grok_match(subject, value) }
|
171
|
+
let(:message) { "[1427925600] TIMEPERIOD TRANSITION: 24X7;-1;1" }
|
87
172
|
|
88
|
-
it "
|
89
|
-
expect(
|
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
|
-
|
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
|
105
|
-
|
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
|
-
|
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
|
-
|
214
|
+
describe_pattern "NAGIOSLOGLINE - SERVICE ALERT", [ 'legacy', 'ecs-v1' ] do
|
116
215
|
|
117
|
-
let(:
|
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(
|
223
|
+
expect(pattern).to match(message)
|
126
224
|
end
|
127
225
|
|
128
226
|
it "generates the nagios_type field" do
|
129
|
-
|
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
|
-
|
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
|
137
|
-
|
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
|
141
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
295
|
+
describe_pattern "NAGIOSLOGLINE - SERVICE NOTIFICATION", [ 'legacy', 'ecs-v1' ] do
|
159
296
|
|
160
|
-
let(:
|
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(
|
304
|
+
expect(pattern).to match(message)
|
169
305
|
end
|
170
306
|
|
171
307
|
it "generates the nagios_type field" do
|
172
|
-
|
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
|
-
|
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
|
-
|
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
|
184
|
-
|
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
|
188
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
374
|
+
describe_pattern "NAGIOSLOGLINE - HOST NOTIFICATION", [ 'legacy', 'ecs-v1' ] do
|
207
375
|
|
208
|
-
let(:
|
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(
|
379
|
+
expect(pattern).to match(message)
|
217
380
|
end
|
218
381
|
|
219
382
|
it "generates the nagios_type field" do
|
220
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|