logstash-core-event 2.4.1-java → 5.0.0.alpha1-java
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 +4 -4
- data/lib/logstash-core-event/version.rb +1 -1
- data/lib/logstash/event.rb +2 -5
- data/lib/logstash/string_interpolation.rb +2 -8
- data/lib/logstash/timestamp.rb +1 -7
- data/lib/logstash/util/accessors.rb +1 -8
- data/logstash-core-event.gemspec +1 -1
- data/spec/logstash/event_spec.rb +84 -140
- metadata +4 -6
- data/spec/logstash/event_old_api_spec.rb +0 -662
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1657c518f042a78ddbfcef66ec47f9ede82251a
|
4
|
+
data.tar.gz: a09cd95fe9f34ff2be9db7c3257011f291f22d43
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab09ee15f5438e6b6dbbfe7674a2c1992d99a188c2fde7385fdc0fbd89099f9320747e49c09ef6de6c0ea5d228c8bea929ced2fe0d2cc43f3c18919bcff29be8
|
7
|
+
data.tar.gz: e291fc3fde667587e91d8d64c1ad4e9c9908834a2b880428be82bb4b4896c9cd9f13d74f79b941c0064ed1174700119deef1d5f2f35bcea0d5d72471bc18cdaa
|
data/lib/logstash/event.rb
CHANGED
@@ -113,7 +113,7 @@ class LogStash::Event
|
|
113
113
|
@data[TIMESTAMP] = val
|
114
114
|
end
|
115
115
|
|
116
|
-
def
|
116
|
+
def [](fieldref)
|
117
117
|
if fieldref.start_with?(METADATA_BRACKETS)
|
118
118
|
@metadata_accessors.get(fieldref[METADATA_BRACKETS.length .. -1])
|
119
119
|
elsif fieldref == METADATA
|
@@ -123,7 +123,7 @@ class LogStash::Event
|
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
126
|
-
def
|
126
|
+
def []=(fieldref, value)
|
127
127
|
if fieldref == TIMESTAMP && !value.is_a?(LogStash::Timestamp)
|
128
128
|
raise TypeError, "The field '@timestamp' must be a (LogStash::Timestamp, not a #{value.class} (#{value})"
|
129
129
|
end
|
@@ -137,9 +137,6 @@ class LogStash::Event
|
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
140
|
-
alias_method :[], :get
|
141
|
-
alias_method :[]=, :set
|
142
|
-
|
143
140
|
def to_json(*args)
|
144
141
|
# ignore arguments to respect accepted to_json method signature
|
145
142
|
LogStash::Json.dump(@data)
|
@@ -124,15 +124,9 @@ module LogStash
|
|
124
124
|
value.join(",")
|
125
125
|
when Hash
|
126
126
|
LogStash::Json.dump(value)
|
127
|
-
when Numeric
|
128
|
-
value
|
129
|
-
when TrueClass
|
130
|
-
value
|
131
|
-
when FalseClass
|
132
|
-
value
|
133
127
|
else
|
134
|
-
#
|
135
|
-
#
|
128
|
+
# Make sure we dont work on the refence of the value
|
129
|
+
# The Java Event implementation was always returning a string.
|
136
130
|
"#{value}"
|
137
131
|
end
|
138
132
|
end
|
data/lib/logstash/timestamp.rb
CHANGED
@@ -24,13 +24,7 @@ module LogStash
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def self.at(*args)
|
27
|
-
|
28
|
-
if epoch.is_a?(BigDecimal)
|
29
|
-
# bug in JRuby prevents correcly parsing a BigDecimal fractional part, see https://github.com/elastic/logstash/issues/4565
|
30
|
-
Timestamp.new(::Time.at(epoch.to_i, epoch.frac.to_f * 1000000))
|
31
|
-
else
|
32
|
-
Timestamp.new(::Time.at(*args))
|
33
|
-
end
|
27
|
+
Timestamp.new(::Time.at(*args))
|
34
28
|
end
|
35
29
|
|
36
30
|
def self.parse(*args)
|
@@ -95,14 +95,7 @@ module LogStash::Util
|
|
95
95
|
# @param field_reference [String] the field referece
|
96
96
|
# @return [[Object, String]] the [target, key] tuple associated with this field reference
|
97
97
|
def lookup_or_create(field_reference)
|
98
|
-
|
99
|
-
# which was overwritten with a new value. for example, if "[a][b]" is cached and we
|
100
|
-
# set a new value for "[a]" then reading again "[a][b]" would point in a stale target.
|
101
|
-
# flushing the complete @lut is suboptimal, but a hierarchical lut would be required
|
102
|
-
# to be able to invalidate fieldrefs from a common root.
|
103
|
-
# see https://github.com/elastic/logstash/pull/5132
|
104
|
-
@lut.clear
|
105
|
-
@lut[field_reference] = find_or_create_target(field_reference)
|
98
|
+
@lut[field_reference] ||= find_or_create_target(field_reference)
|
106
99
|
end
|
107
100
|
|
108
101
|
# find the target container object in store for this field reference
|
data/logstash-core-event.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
16
16
|
gem.name = "logstash-core-event"
|
17
17
|
gem.require_paths = ["lib"]
|
18
|
-
gem.version = LOGSTASH_CORE_EVENT_VERSION
|
18
|
+
gem.version = LOGSTASH_CORE_EVENT_VERSION.gsub(/-/, '.')
|
19
19
|
|
20
20
|
if RUBY_PLATFORM == 'java'
|
21
21
|
gem.platform = RUBY_PLATFORM
|
data/spec/logstash/event_spec.rb
CHANGED
@@ -8,68 +8,68 @@ describe LogStash::Event do
|
|
8
8
|
shared_examples "all event tests" do
|
9
9
|
context "[]=" do
|
10
10
|
it "should raise an exception if you attempt to set @timestamp to a value type other than a Time object" do
|
11
|
-
expect{subject
|
11
|
+
expect{subject["@timestamp"] = "crash!"}.to raise_error(TypeError)
|
12
12
|
end
|
13
13
|
|
14
14
|
it "should assign simple fields" do
|
15
|
-
expect(subject
|
16
|
-
expect(subject
|
17
|
-
expect(subject
|
15
|
+
expect(subject["foo"]).to be_nil
|
16
|
+
expect(subject["foo"] = "bar").to eq("bar")
|
17
|
+
expect(subject["foo"]).to eq("bar")
|
18
18
|
end
|
19
19
|
|
20
20
|
it "should overwrite simple fields" do
|
21
|
-
expect(subject
|
22
|
-
expect(subject
|
23
|
-
expect(subject
|
21
|
+
expect(subject["foo"]).to be_nil
|
22
|
+
expect(subject["foo"] = "bar").to eq("bar")
|
23
|
+
expect(subject["foo"]).to eq("bar")
|
24
24
|
|
25
|
-
expect(subject
|
26
|
-
expect(subject
|
25
|
+
expect(subject["foo"] = "baz").to eq("baz")
|
26
|
+
expect(subject["foo"]).to eq("baz")
|
27
27
|
end
|
28
28
|
|
29
29
|
it "should assign deep fields" do
|
30
|
-
expect(subject
|
31
|
-
expect(subject
|
32
|
-
expect(subject
|
30
|
+
expect(subject["[foo][bar]"]).to be_nil
|
31
|
+
expect(subject["[foo][bar]"] = "baz").to eq("baz")
|
32
|
+
expect(subject["[foo][bar]"]).to eq("baz")
|
33
33
|
end
|
34
34
|
|
35
35
|
it "should overwrite deep fields" do
|
36
|
-
expect(subject
|
37
|
-
expect(subject
|
38
|
-
expect(subject
|
36
|
+
expect(subject["[foo][bar]"]).to be_nil
|
37
|
+
expect(subject["[foo][bar]"] = "baz").to eq("baz")
|
38
|
+
expect(subject["[foo][bar]"]).to eq("baz")
|
39
39
|
|
40
|
-
expect(subject
|
41
|
-
expect(subject
|
40
|
+
expect(subject["[foo][bar]"] = "zab").to eq("zab")
|
41
|
+
expect(subject["[foo][bar]"]).to eq("zab")
|
42
42
|
end
|
43
43
|
|
44
44
|
it "allow to set the @metadata key to a hash" do
|
45
|
-
subject
|
46
|
-
expect(subject
|
45
|
+
subject["@metadata"] = { "action" => "index" }
|
46
|
+
expect(subject["[@metadata][action]"]).to eq("index")
|
47
47
|
end
|
48
48
|
|
49
49
|
it "should add key when setting nil value" do
|
50
|
-
subject
|
50
|
+
subject["[baz]"] = nil
|
51
51
|
expect(subject.to_hash).to include("baz" => nil)
|
52
52
|
end
|
53
53
|
|
54
54
|
it "should set nil element within existing array value" do
|
55
|
-
subject
|
55
|
+
subject["[foo]"] = ["bar", "baz"]
|
56
56
|
|
57
|
-
expect(subject
|
58
|
-
expect(subject
|
57
|
+
expect(subject["[foo][0]"] = nil).to eq(nil)
|
58
|
+
expect(subject["[foo]"]).to eq([nil, "baz"])
|
59
59
|
end
|
60
60
|
|
61
61
|
it "should set nil in first element within empty array" do
|
62
|
-
subject
|
62
|
+
subject["[foo]"] = []
|
63
63
|
|
64
|
-
expect(subject
|
65
|
-
expect(subject
|
64
|
+
expect(subject["[foo][0]"] = nil).to eq(nil)
|
65
|
+
expect(subject["[foo]"]).to eq([nil])
|
66
66
|
end
|
67
67
|
|
68
68
|
it "should set nil in second element within empty array" do
|
69
|
-
subject
|
69
|
+
subject["[foo]"] = []
|
70
70
|
|
71
|
-
expect(subject
|
72
|
-
expect(subject
|
71
|
+
expect(subject["[foo][1]"] = nil).to eq(nil)
|
72
|
+
expect(subject["[foo]"]).to eq([nil, nil])
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
@@ -79,43 +79,15 @@ describe LogStash::Event do
|
|
79
79
|
event = LogStash::Event.new({ "reference" => data })
|
80
80
|
LogStash::Util::Decorators.add_fields({"reference_test" => "%{reference}"}, event, "dummy-plugin")
|
81
81
|
data.downcase!
|
82
|
-
expect(event
|
82
|
+
expect(event["reference_test"]).not_to eq(data)
|
83
83
|
end
|
84
84
|
|
85
|
-
|
86
|
-
# see https://github.com/elastic/logstash/issues/5114 for more details.
|
87
|
-
it "should return a Fixnum" do
|
85
|
+
it "should not return a Fixnum reference" do
|
88
86
|
data = 1
|
89
87
|
event = LogStash::Event.new({ "reference" => data })
|
90
88
|
LogStash::Util::Decorators.add_fields({"reference_test" => "%{reference}"}, event, "dummy-plugin")
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
# TODO: This was a bug and should only be true in the context of 2.3.X
|
95
|
-
# see https://github.com/elastic/logstash/issues/5114 for more details.
|
96
|
-
it "should return a Float" do
|
97
|
-
data = 1.999
|
98
|
-
event = LogStash::Event.new({ "reference" => data })
|
99
|
-
LogStash::Util::Decorators.add_fields({"reference_test" => "%{reference}"}, event, "dummy-plugin")
|
100
|
-
expect(event.get("reference_test")).to eq(1.999)
|
101
|
-
end
|
102
|
-
|
103
|
-
# TODO: This was a bug and should only be true in the context of 2.3.X
|
104
|
-
# see https://github.com/elastic/logstash/issues/5114 for more details.
|
105
|
-
it "should return true" do
|
106
|
-
data = true
|
107
|
-
event = LogStash::Event.new({ "reference" => data })
|
108
|
-
LogStash::Util::Decorators.add_fields({"reference_test" => "%{reference}"}, event, "dummy-plugin")
|
109
|
-
expect(event.get("reference_test")).to be_kind_of(TrueClass)
|
110
|
-
end
|
111
|
-
|
112
|
-
# TODO: This was a bug and should only be true in the context of 2.3.X
|
113
|
-
# see https://github.com/elastic/logstash/issues/5114 for more details.
|
114
|
-
it "should return false" do
|
115
|
-
data = false
|
116
|
-
event = LogStash::Event.new({ "reference" => data })
|
117
|
-
LogStash::Util::Decorators.add_fields({"reference_test" => "%{reference}"}, event, "dummy-plugin")
|
118
|
-
expect(event.get("reference_test")).to be_kind_of(FalseClass)
|
89
|
+
data += 41
|
90
|
+
expect(event["reference_test"]).to eq("1")
|
119
91
|
end
|
120
92
|
|
121
93
|
it "should report a unix timestamp for %{+%s}" do
|
@@ -152,7 +124,7 @@ describe LogStash::Event do
|
|
152
124
|
|
153
125
|
it "should report fields with %{field} syntax" do
|
154
126
|
expect(subject.sprintf("%{type}")).to eq("sprintf")
|
155
|
-
expect(subject.sprintf("%{message}")).to eq(subject
|
127
|
+
expect(subject.sprintf("%{message}")).to eq(subject["message"])
|
156
128
|
end
|
157
129
|
|
158
130
|
it "should print deep fields" do
|
@@ -181,35 +153,35 @@ describe LogStash::Event do
|
|
181
153
|
end
|
182
154
|
|
183
155
|
it "should render nil array values as leading empty string" do
|
184
|
-
expect(subject
|
156
|
+
expect(subject["foo"] = [nil, "baz"]).to eq([nil, "baz"])
|
185
157
|
|
186
|
-
expect(subject
|
187
|
-
expect(subject
|
158
|
+
expect(subject["[foo][0]"]).to be_nil
|
159
|
+
expect(subject["[foo][1]"]).to eq("baz")
|
188
160
|
|
189
161
|
expect(subject.sprintf("%{[foo]}")).to eq(",baz")
|
190
162
|
end
|
191
163
|
|
192
164
|
it "should render nil array values as middle empty string" do
|
193
|
-
expect(subject
|
165
|
+
expect(subject["foo"] = ["bar", nil, "baz"]).to eq(["bar", nil, "baz"])
|
194
166
|
|
195
|
-
expect(subject
|
196
|
-
expect(subject
|
197
|
-
expect(subject
|
167
|
+
expect(subject["[foo][0]"]).to eq("bar")
|
168
|
+
expect(subject["[foo][1]"]).to be_nil
|
169
|
+
expect(subject["[foo][2]"]).to eq("baz")
|
198
170
|
|
199
171
|
expect(subject.sprintf("%{[foo]}")).to eq("bar,,baz")
|
200
172
|
end
|
201
173
|
|
202
174
|
it "should render nil array values as trailing empty string" do
|
203
|
-
expect(subject
|
175
|
+
expect(subject["foo"] = ["bar", nil]).to eq(["bar", nil])
|
204
176
|
|
205
|
-
expect(subject
|
206
|
-
expect(subject
|
177
|
+
expect(subject["[foo][0]"]).to eq("bar")
|
178
|
+
expect(subject["[foo][1]"]).to be_nil
|
207
179
|
|
208
180
|
expect(subject.sprintf("%{[foo]}")).to eq("bar,")
|
209
181
|
end
|
210
182
|
|
211
183
|
it "should render deep arrays with nil value" do
|
212
|
-
subject
|
184
|
+
subject["[foo]"] = [[12, nil], 56]
|
213
185
|
expect(subject.sprintf("%{[foo]}")).to eq("12,,56")
|
214
186
|
end
|
215
187
|
|
@@ -226,18 +198,18 @@ describe LogStash::Event do
|
|
226
198
|
|
227
199
|
context "#[]" do
|
228
200
|
it "should fetch data" do
|
229
|
-
expect(subject
|
201
|
+
expect(subject["type"]).to eq("sprintf")
|
230
202
|
end
|
231
203
|
it "should fetch fields" do
|
232
|
-
expect(subject
|
233
|
-
expect(subject
|
204
|
+
expect(subject["a"]).to eq("b")
|
205
|
+
expect(subject['c']['d']).to eq("f")
|
234
206
|
end
|
235
207
|
it "should fetch deep fields" do
|
236
|
-
expect(subject
|
237
|
-
expect(subject
|
238
|
-
expect(subject
|
239
|
-
expect(subject
|
240
|
-
expect(subject
|
208
|
+
expect(subject["[j][k1]"]).to eq("v")
|
209
|
+
expect(subject["[c][d]"]).to eq("f")
|
210
|
+
expect(subject['[f][g][h]']).to eq("i")
|
211
|
+
expect(subject['[j][k3][4]']).to eq("m")
|
212
|
+
expect(subject['[j][5]']).to eq(7)
|
241
213
|
|
242
214
|
end
|
243
215
|
|
@@ -245,7 +217,7 @@ describe LogStash::Event do
|
|
245
217
|
count = 1000000
|
246
218
|
2.times do
|
247
219
|
start = Time.now
|
248
|
-
count.times { subject
|
220
|
+
count.times { subject["[j][k1]"] }
|
249
221
|
duration = Time.now - start
|
250
222
|
puts "event #[] rate: #{"%02.0f/sec" % (count / duration)}, elapsed: #{duration}s"
|
251
223
|
end
|
@@ -291,11 +263,11 @@ describe LogStash::Event do
|
|
291
263
|
)
|
292
264
|
subject.overwrite(new_event)
|
293
265
|
|
294
|
-
expect(subject
|
295
|
-
expect(subject
|
266
|
+
expect(subject["message"]).to eq("foo bar")
|
267
|
+
expect(subject["type"]).to eq("new")
|
296
268
|
|
297
269
|
["tags", "source", "a", "c", "f", "j"].each do |field|
|
298
|
-
expect(subject
|
270
|
+
expect(subject[field]).to be_nil
|
299
271
|
end
|
300
272
|
end
|
301
273
|
end
|
@@ -303,7 +275,7 @@ describe LogStash::Event do
|
|
303
275
|
context "#append" do
|
304
276
|
it "should append strings to an array" do
|
305
277
|
subject.append(LogStash::Event.new("message" => "another thing"))
|
306
|
-
expect(subject
|
278
|
+
expect(subject["message"]).to eq([ "hello world", "another thing" ])
|
307
279
|
end
|
308
280
|
|
309
281
|
it "should concatenate tags" do
|
@@ -311,54 +283,54 @@ describe LogStash::Event do
|
|
311
283
|
# added to_a for when array is a Java Collection when produced from json input
|
312
284
|
# TODO: we have to find a better way to handle this in tests. maybe override
|
313
285
|
# rspec eq or == to do an explicit to_a when comparing arrays?
|
314
|
-
expect(subject
|
286
|
+
expect(subject["tags"].to_a).to eq([ "tag1", "tag2" ])
|
315
287
|
end
|
316
288
|
|
317
289
|
context "when event field is nil" do
|
318
290
|
it "should add single value as string" do
|
319
291
|
subject.append(LogStash::Event.new({"field1" => "append1"}))
|
320
|
-
expect(subject
|
292
|
+
expect(subject[ "field1" ]).to eq("append1")
|
321
293
|
end
|
322
294
|
it "should add multi values as array" do
|
323
295
|
subject.append(LogStash::Event.new({"field1" => [ "append1","append2" ]}))
|
324
|
-
expect(subject
|
296
|
+
expect(subject[ "field1" ]).to eq([ "append1","append2" ])
|
325
297
|
end
|
326
298
|
end
|
327
299
|
|
328
300
|
context "when event field is a string" do
|
329
|
-
before { subject
|
301
|
+
before { subject[ "field1" ] = "original1" }
|
330
302
|
|
331
303
|
it "should append string to values, if different from current" do
|
332
304
|
subject.append(LogStash::Event.new({"field1" => "append1"}))
|
333
|
-
expect(subject
|
305
|
+
expect(subject[ "field1" ]).to eq([ "original1", "append1" ])
|
334
306
|
end
|
335
307
|
it "should not change value, if appended value is equal current" do
|
336
308
|
subject.append(LogStash::Event.new({"field1" => "original1"}))
|
337
|
-
expect(subject
|
309
|
+
expect(subject[ "field1" ]).to eq("original1")
|
338
310
|
end
|
339
311
|
it "should concatenate values in an array" do
|
340
312
|
subject.append(LogStash::Event.new({"field1" => [ "append1" ]}))
|
341
|
-
expect(subject
|
313
|
+
expect(subject[ "field1" ]).to eq([ "original1", "append1" ])
|
342
314
|
end
|
343
315
|
it "should join array, removing duplicates" do
|
344
316
|
subject.append(LogStash::Event.new({"field1" => [ "append1","original1" ]}))
|
345
|
-
expect(subject
|
317
|
+
expect(subject[ "field1" ]).to eq([ "original1", "append1" ])
|
346
318
|
end
|
347
319
|
end
|
348
320
|
context "when event field is an array" do
|
349
|
-
before { subject
|
321
|
+
before { subject[ "field1" ] = [ "original1", "original2" ] }
|
350
322
|
|
351
323
|
it "should append string values to array, if not present in array" do
|
352
324
|
subject.append(LogStash::Event.new({"field1" => "append1"}))
|
353
|
-
expect(subject
|
325
|
+
expect(subject[ "field1" ]).to eq([ "original1", "original2", "append1" ])
|
354
326
|
end
|
355
327
|
it "should not append string values, if the array already contains it" do
|
356
328
|
subject.append(LogStash::Event.new({"field1" => "original1"}))
|
357
|
-
expect(subject
|
329
|
+
expect(subject[ "field1" ]).to eq([ "original1", "original2" ])
|
358
330
|
end
|
359
331
|
it "should join array, removing duplicates" do
|
360
332
|
subject.append(LogStash::Event.new({"field1" => [ "append1","original1" ]}))
|
361
|
-
expect(subject
|
333
|
+
expect(subject[ "field1" ]).to eq([ "original1", "original2", "append1" ])
|
362
334
|
end
|
363
335
|
end
|
364
336
|
|
@@ -370,7 +342,7 @@ describe LogStash::Event do
|
|
370
342
|
|
371
343
|
data = { "@timestamp" => "2013-12-21T07:25:06.605Z" }
|
372
344
|
event = LogStash::Event.new(data)
|
373
|
-
expect(event
|
345
|
+
expect(event["@timestamp"]).to be_a(LogStash::Timestamp)
|
374
346
|
|
375
347
|
duration = 0
|
376
348
|
[warmup, count].each do |i|
|
@@ -439,13 +411,13 @@ describe LogStash::Event do
|
|
439
411
|
it "should tag for invalid value" do
|
440
412
|
event = LogStash::Event.new("@timestamp" => "foo")
|
441
413
|
expect(event.timestamp.to_i).to be_within(1).of Time.now.to_i
|
442
|
-
expect(event
|
443
|
-
expect(event
|
414
|
+
expect(event["tags"]).to eq([LogStash::Event::TIMESTAMP_FAILURE_TAG])
|
415
|
+
expect(event[LogStash::Event::TIMESTAMP_FAILURE_FIELD]).to eq("foo")
|
444
416
|
|
445
417
|
event = LogStash::Event.new("@timestamp" => 666)
|
446
418
|
expect(event.timestamp.to_i).to be_within(1).of Time.now.to_i
|
447
|
-
expect(event
|
448
|
-
expect(event
|
419
|
+
expect(event["tags"]).to eq([LogStash::Event::TIMESTAMP_FAILURE_TAG])
|
420
|
+
expect(event[LogStash::Event::TIMESTAMP_FAILURE_FIELD]).to eq(666)
|
449
421
|
end
|
450
422
|
|
451
423
|
it "should warn for invalid value" do
|
@@ -460,8 +432,8 @@ describe LogStash::Event do
|
|
460
432
|
it "should tag for invalid string format" do
|
461
433
|
event = LogStash::Event.new("@timestamp" => "foo")
|
462
434
|
expect(event.timestamp.to_i).to be_within(1).of Time.now.to_i
|
463
|
-
expect(event
|
464
|
-
expect(event
|
435
|
+
expect(event["tags"]).to eq([LogStash::Event::TIMESTAMP_FAILURE_TAG])
|
436
|
+
expect(event[LogStash::Event::TIMESTAMP_FAILURE_FIELD]).to eq("foo")
|
465
437
|
end
|
466
438
|
|
467
439
|
it "should warn for invalid string format" do
|
@@ -506,7 +478,7 @@ describe LogStash::Event do
|
|
506
478
|
end
|
507
479
|
|
508
480
|
it "should still allow normal field access" do
|
509
|
-
expect(subject
|
481
|
+
expect(subject["hello"]).to eq("world")
|
510
482
|
end
|
511
483
|
end
|
512
484
|
|
@@ -519,15 +491,15 @@ describe LogStash::Event do
|
|
519
491
|
expect(fieldref).to start_with("[@metadata]")
|
520
492
|
|
521
493
|
# Set it.
|
522
|
-
subject
|
494
|
+
subject[fieldref] = value
|
523
495
|
end
|
524
496
|
|
525
497
|
it "should still allow normal field access" do
|
526
|
-
expect(subject
|
498
|
+
expect(subject["normal"]).to eq("normal")
|
527
499
|
end
|
528
500
|
|
529
501
|
it "should allow getting" do
|
530
|
-
expect(subject
|
502
|
+
expect(subject[fieldref]).to eq(value)
|
531
503
|
end
|
532
504
|
|
533
505
|
it "should be hidden from .to_json" do
|
@@ -550,10 +522,10 @@ describe LogStash::Event do
|
|
550
522
|
context "with no metadata" do
|
551
523
|
subject { LogStash::Event.new("foo" => "bar") }
|
552
524
|
it "should have no metadata" do
|
553
|
-
expect(subject
|
525
|
+
expect(subject["@metadata"]).to be_empty
|
554
526
|
end
|
555
527
|
it "should still allow normal field access" do
|
556
|
-
expect(subject
|
528
|
+
expect(subject["foo"]).to eq("bar")
|
557
529
|
end
|
558
530
|
|
559
531
|
it "should not include the @metadata key" do
|
@@ -627,35 +599,7 @@ describe LogStash::Event do
|
|
627
599
|
end
|
628
600
|
|
629
601
|
it "return the string containing the timestamp, the host and the message" do
|
630
|
-
expect(event1.to_s).to eq("#{timestamp.to_iso8601} #{event1
|
631
|
-
end
|
632
|
-
end
|
633
|
-
|
634
|
-
describe "Event accessors" do
|
635
|
-
let(:event) { LogStash::Event.new({ "message" => "foo" }) }
|
636
|
-
|
637
|
-
it "should invalidate target caching" do
|
638
|
-
expect(event.get("[a][0]")).to be_nil
|
639
|
-
|
640
|
-
expect(event.set("[a][0]", 42)).to eq(42)
|
641
|
-
expect(event.get("[a][0]")).to eq(42)
|
642
|
-
expect(event.get("[a]")).to eq({"0" => 42})
|
643
|
-
|
644
|
-
expect(event.set("[a]", [42, 24])).to eq([42, 24])
|
645
|
-
expect(event.get("[a]")).to eq([42, 24])
|
646
|
-
|
647
|
-
expect(event.get("[a][0]")).to eq(42)
|
648
|
-
|
649
|
-
expect(event.set("[a]", [24, 42])).to eq([24, 42])
|
650
|
-
expect(event.get("[a][0]")).to eq(24)
|
651
|
-
|
652
|
-
expect(event.set("[a][0]", {"a "=> 99, "b" => 98})).to eq({"a "=> 99, "b" => 98})
|
653
|
-
expect(event.get("[a][0]")).to eq({"a "=> 99, "b" => 98})
|
654
|
-
|
655
|
-
expect(event.get("[a]")).to eq([{"a "=> 99, "b" => 98}, 42])
|
656
|
-
expect(event.get("[a][0]")).to eq({"a "=> 99, "b" => 98})
|
657
|
-
expect(event.get("[a][1]")).to eq(42)
|
658
|
-
expect(event.get("[a][0][b]")).to eq(98)
|
602
|
+
expect(event1.to_s).to eq("#{timestamp.to_iso8601} #{event1["host"]} #{event1["message"]}")
|
659
603
|
end
|
660
604
|
end
|
661
605
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-core-event
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0.alpha1
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-04-05 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: The core event component of logstash, the scalable log and event management tool
|
14
14
|
email:
|
@@ -25,7 +25,6 @@ files:
|
|
25
25
|
- lib/logstash/timestamp.rb
|
26
26
|
- lib/logstash/util/accessors.rb
|
27
27
|
- logstash-core-event.gemspec
|
28
|
-
- spec/logstash/event_old_api_spec.rb
|
29
28
|
- spec/logstash/event_spec.rb
|
30
29
|
- spec/logstash/timestamp_spec.rb
|
31
30
|
- spec/logstash/util/accessors_spec.rb
|
@@ -44,9 +43,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
44
43
|
version: '0'
|
45
44
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
45
|
requirements:
|
47
|
-
- - "
|
46
|
+
- - ">"
|
48
47
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
48
|
+
version: 1.3.1
|
50
49
|
requirements: []
|
51
50
|
rubyforge_project:
|
52
51
|
rubygems_version: 2.4.8
|
@@ -54,7 +53,6 @@ signing_key:
|
|
54
53
|
specification_version: 4
|
55
54
|
summary: logstash-core-event - The core event component of logstash
|
56
55
|
test_files:
|
57
|
-
- spec/logstash/event_old_api_spec.rb
|
58
56
|
- spec/logstash/event_spec.rb
|
59
57
|
- spec/logstash/timestamp_spec.rb
|
60
58
|
- spec/logstash/util/accessors_spec.rb
|
@@ -1,662 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require "spec_helper"
|
3
|
-
require "logstash/util/decorators"
|
4
|
-
require "json"
|
5
|
-
|
6
|
-
describe LogStash::Event do
|
7
|
-
|
8
|
-
shared_examples "all event tests" do
|
9
|
-
context "[]=" do
|
10
|
-
it "should raise an exception if you attempt to set @timestamp to a value type other than a Time object" do
|
11
|
-
expect{subject["@timestamp"] = "crash!"}.to raise_error(TypeError)
|
12
|
-
end
|
13
|
-
|
14
|
-
it "should assign simple fields" do
|
15
|
-
expect(subject["foo"]).to be_nil
|
16
|
-
expect(subject["foo"] = "bar").to eq("bar")
|
17
|
-
expect(subject["foo"]).to eq("bar")
|
18
|
-
end
|
19
|
-
|
20
|
-
it "should overwrite simple fields" do
|
21
|
-
expect(subject["foo"]).to be_nil
|
22
|
-
expect(subject["foo"] = "bar").to eq("bar")
|
23
|
-
expect(subject["foo"]).to eq("bar")
|
24
|
-
|
25
|
-
expect(subject["foo"] = "baz").to eq("baz")
|
26
|
-
expect(subject["foo"]).to eq("baz")
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should assign deep fields" do
|
30
|
-
expect(subject["[foo][bar]"]).to be_nil
|
31
|
-
expect(subject["[foo][bar]"] = "baz").to eq("baz")
|
32
|
-
expect(subject["[foo][bar]"]).to eq("baz")
|
33
|
-
end
|
34
|
-
|
35
|
-
it "should overwrite deep fields" do
|
36
|
-
expect(subject["[foo][bar]"]).to be_nil
|
37
|
-
expect(subject["[foo][bar]"] = "baz").to eq("baz")
|
38
|
-
expect(subject["[foo][bar]"]).to eq("baz")
|
39
|
-
|
40
|
-
expect(subject["[foo][bar]"] = "zab").to eq("zab")
|
41
|
-
expect(subject["[foo][bar]"]).to eq("zab")
|
42
|
-
end
|
43
|
-
|
44
|
-
it "allow to set the @metadata key to a hash" do
|
45
|
-
subject["@metadata"] = { "action" => "index" }
|
46
|
-
expect(subject["[@metadata][action]"]).to eq("index")
|
47
|
-
end
|
48
|
-
|
49
|
-
it "should add key when setting nil value" do
|
50
|
-
subject["[baz]"] = nil
|
51
|
-
expect(subject.to_hash).to include("baz" => nil)
|
52
|
-
end
|
53
|
-
|
54
|
-
it "should set nil element within existing array value" do
|
55
|
-
subject["[foo]"] = ["bar", "baz"]
|
56
|
-
|
57
|
-
expect(subject["[foo][0]"] = nil).to eq(nil)
|
58
|
-
expect(subject["[foo]"]).to eq([nil, "baz"])
|
59
|
-
end
|
60
|
-
|
61
|
-
it "should set nil in first element within empty array" do
|
62
|
-
subject["[foo]"] = []
|
63
|
-
|
64
|
-
expect(subject["[foo][0]"] = nil).to eq(nil)
|
65
|
-
expect(subject["[foo]"]).to eq([nil])
|
66
|
-
end
|
67
|
-
|
68
|
-
it "should set nil in second element within empty array" do
|
69
|
-
subject["[foo]"] = []
|
70
|
-
|
71
|
-
expect(subject["[foo][1]"] = nil).to eq(nil)
|
72
|
-
expect(subject["[foo]"]).to eq([nil, nil])
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
context "#sprintf" do
|
77
|
-
it "should not return a String reference" do
|
78
|
-
data = "NOT-A-REFERENCE"
|
79
|
-
event = LogStash::Event.new({ "reference" => data })
|
80
|
-
LogStash::Util::Decorators.add_fields({"reference_test" => "%{reference}"}, event, "dummy-plugin")
|
81
|
-
data.downcase!
|
82
|
-
expect(event["reference_test"]).not_to eq(data)
|
83
|
-
end
|
84
|
-
|
85
|
-
# TODO: This was a bug and should only be true in the context of 2.3.X
|
86
|
-
# see https://github.com/elastic/logstash/issues/5114 for more details.
|
87
|
-
it "should return a Fixnum" do
|
88
|
-
data = 1
|
89
|
-
event = LogStash::Event.new({ "reference" => data })
|
90
|
-
LogStash::Util::Decorators.add_fields({"reference_test" => "%{reference}"}, event, "dummy-plugin")
|
91
|
-
expect(event["reference_test"]).to eq(1)
|
92
|
-
end
|
93
|
-
|
94
|
-
# TODO: This was a bug and should only be true in the context of 2.3.X
|
95
|
-
# see https://github.com/elastic/logstash/issues/5114 for more details.
|
96
|
-
it "should return a Float" do
|
97
|
-
data = 1.999
|
98
|
-
event = LogStash::Event.new({ "reference" => data })
|
99
|
-
LogStash::Util::Decorators.add_fields({"reference_test" => "%{reference}"}, event, "dummy-plugin")
|
100
|
-
expect(event["reference_test"]).to eq(1.999)
|
101
|
-
end
|
102
|
-
|
103
|
-
# TODO: This was a bug and should only be true in the context of 2.3.X
|
104
|
-
# see https://github.com/elastic/logstash/issues/5114 for more details.
|
105
|
-
it "should return true" do
|
106
|
-
data = true
|
107
|
-
event = LogStash::Event.new({ "reference" => data })
|
108
|
-
LogStash::Util::Decorators.add_fields({"reference_test" => "%{reference}"}, event, "dummy-plugin")
|
109
|
-
expect(event["reference_test"]).to be_kind_of(TrueClass)
|
110
|
-
end
|
111
|
-
|
112
|
-
# TODO: This was a bug and should only be true in the context of 2.3.X
|
113
|
-
# see https://github.com/elastic/logstash/issues/5114 for more details.
|
114
|
-
it "should return false" do
|
115
|
-
data = false
|
116
|
-
event = LogStash::Event.new({ "reference" => data })
|
117
|
-
LogStash::Util::Decorators.add_fields({"reference_test" => "%{reference}"}, event, "dummy-plugin")
|
118
|
-
expect(event["reference_test"]).to be_kind_of(FalseClass)
|
119
|
-
end
|
120
|
-
|
121
|
-
it "should report a unix timestamp for %{+%s}" do
|
122
|
-
expect(subject.sprintf("%{+%s}")).to eq("1356998400")
|
123
|
-
end
|
124
|
-
|
125
|
-
it "should work if there is no fieldref in the string" do
|
126
|
-
expect(subject.sprintf("bonjour")).to eq("bonjour")
|
127
|
-
end
|
128
|
-
|
129
|
-
it "should raise error when formatting %{+%s} when @timestamp field is missing" do
|
130
|
-
str = "hello-%{+%s}"
|
131
|
-
subj = subject.clone
|
132
|
-
subj.remove("[@timestamp]")
|
133
|
-
expect{ subj.sprintf(str) }.to raise_error(LogStash::Error)
|
134
|
-
end
|
135
|
-
|
136
|
-
it "should report a time with %{+format} syntax", :if => RUBY_ENGINE == "jruby" do
|
137
|
-
expect(subject.sprintf("%{+YYYY}")).to eq("2013")
|
138
|
-
expect(subject.sprintf("%{+MM}")).to eq("01")
|
139
|
-
expect(subject.sprintf("%{+HH}")).to eq("00")
|
140
|
-
end
|
141
|
-
|
142
|
-
it "should support mixed string" do
|
143
|
-
expect(subject.sprintf("foo %{+YYYY-MM-dd} %{type}")).to eq("foo 2013-01-01 sprintf")
|
144
|
-
end
|
145
|
-
|
146
|
-
it "should raise error with %{+format} syntax when @timestamp field is missing", :if => RUBY_ENGINE == "jruby" do
|
147
|
-
str = "logstash-%{+YYYY}"
|
148
|
-
subj = subject.clone
|
149
|
-
subj.remove("[@timestamp]")
|
150
|
-
expect{ subj.sprintf(str) }.to raise_error(LogStash::Error)
|
151
|
-
end
|
152
|
-
|
153
|
-
it "should report fields with %{field} syntax" do
|
154
|
-
expect(subject.sprintf("%{type}")).to eq("sprintf")
|
155
|
-
expect(subject.sprintf("%{message}")).to eq(subject["message"])
|
156
|
-
end
|
157
|
-
|
158
|
-
it "should print deep fields" do
|
159
|
-
expect(subject.sprintf("%{[j][k1]}")).to eq("v")
|
160
|
-
expect(subject.sprintf("%{[j][k2][0]}")).to eq("w")
|
161
|
-
end
|
162
|
-
|
163
|
-
it "should be able to take a non-string for the format" do
|
164
|
-
expect(subject.sprintf(2)).to eq("2")
|
165
|
-
end
|
166
|
-
|
167
|
-
it "should allow to use the metadata when calling #sprintf" do
|
168
|
-
expect(subject.sprintf("super-%{[@metadata][fancy]}")).to eq("super-pants")
|
169
|
-
end
|
170
|
-
|
171
|
-
it "should allow to use nested hash from the metadata field" do
|
172
|
-
expect(subject.sprintf("%{[@metadata][have-to-go][deeper]}")).to eq("inception")
|
173
|
-
end
|
174
|
-
|
175
|
-
it "should return a json string if the key is a hash" do
|
176
|
-
expect(subject.sprintf("%{[j][k3]}")).to eq("{\"4\":\"m\"}")
|
177
|
-
end
|
178
|
-
|
179
|
-
it "should not strip last character" do
|
180
|
-
expect(subject.sprintf("%{type}%{message}|")).to eq("sprintfhello world|")
|
181
|
-
end
|
182
|
-
|
183
|
-
it "should render nil array values as leading empty string" do
|
184
|
-
expect(subject["foo"] = [nil, "baz"]).to eq([nil, "baz"])
|
185
|
-
|
186
|
-
expect(subject["[foo][0]"]).to be_nil
|
187
|
-
expect(subject["[foo][1]"]).to eq("baz")
|
188
|
-
|
189
|
-
expect(subject.sprintf("%{[foo]}")).to eq(",baz")
|
190
|
-
end
|
191
|
-
|
192
|
-
it "should render nil array values as middle empty string" do
|
193
|
-
expect(subject["foo"] = ["bar", nil, "baz"]).to eq(["bar", nil, "baz"])
|
194
|
-
|
195
|
-
expect(subject["[foo][0]"]).to eq("bar")
|
196
|
-
expect(subject["[foo][1]"]).to be_nil
|
197
|
-
expect(subject["[foo][2]"]).to eq("baz")
|
198
|
-
|
199
|
-
expect(subject.sprintf("%{[foo]}")).to eq("bar,,baz")
|
200
|
-
end
|
201
|
-
|
202
|
-
it "should render nil array values as trailing empty string" do
|
203
|
-
expect(subject["foo"] = ["bar", nil]).to eq(["bar", nil])
|
204
|
-
|
205
|
-
expect(subject["[foo][0]"]).to eq("bar")
|
206
|
-
expect(subject["[foo][1]"]).to be_nil
|
207
|
-
|
208
|
-
expect(subject.sprintf("%{[foo]}")).to eq("bar,")
|
209
|
-
end
|
210
|
-
|
211
|
-
it "should render deep arrays with nil value" do
|
212
|
-
subject["[foo]"] = [[12, nil], 56]
|
213
|
-
expect(subject.sprintf("%{[foo]}")).to eq("12,,56")
|
214
|
-
end
|
215
|
-
|
216
|
-
context "#encoding" do
|
217
|
-
it "should return known patterns as UTF-8" do
|
218
|
-
expect(subject.sprintf("%{message}").encoding).to eq(Encoding::UTF_8)
|
219
|
-
end
|
220
|
-
|
221
|
-
it "should return unknown patterns as UTF-8" do
|
222
|
-
expect(subject.sprintf("%{unkown_pattern}").encoding).to eq(Encoding::UTF_8)
|
223
|
-
end
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
|
-
context "#[]" do
|
228
|
-
it "should fetch data" do
|
229
|
-
expect(subject["type"]).to eq("sprintf")
|
230
|
-
end
|
231
|
-
it "should fetch fields" do
|
232
|
-
expect(subject["a"]).to eq("b")
|
233
|
-
expect(subject['c']['d']).to eq("f")
|
234
|
-
end
|
235
|
-
it "should fetch deep fields" do
|
236
|
-
expect(subject["[j][k1]"]).to eq("v")
|
237
|
-
expect(subject["[c][d]"]).to eq("f")
|
238
|
-
expect(subject['[f][g][h]']).to eq("i")
|
239
|
-
expect(subject['[j][k3][4]']).to eq("m")
|
240
|
-
expect(subject['[j][5]']).to eq(7)
|
241
|
-
|
242
|
-
end
|
243
|
-
|
244
|
-
it "should be fast?", :performance => true do
|
245
|
-
count = 1000000
|
246
|
-
2.times do
|
247
|
-
start = Time.now
|
248
|
-
count.times { subject["[j][k1]"] }
|
249
|
-
duration = Time.now - start
|
250
|
-
puts "event #[] rate: #{"%02.0f/sec" % (count / duration)}, elapsed: #{duration}s"
|
251
|
-
end
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
context "#include?" do
|
256
|
-
it "should include existing fields" do
|
257
|
-
expect(subject.include?("c")).to eq(true)
|
258
|
-
expect(subject.include?("[c][d]")).to eq(true)
|
259
|
-
expect(subject.include?("[j][k4][0][nested]")).to eq(true)
|
260
|
-
end
|
261
|
-
|
262
|
-
it "should include field with nil value" do
|
263
|
-
expect(subject.include?("nilfield")).to eq(true)
|
264
|
-
end
|
265
|
-
|
266
|
-
it "should include @metadata field" do
|
267
|
-
expect(subject.include?("@metadata")).to eq(true)
|
268
|
-
end
|
269
|
-
|
270
|
-
it "should include field within @metadata" do
|
271
|
-
expect(subject.include?("[@metadata][fancy]")).to eq(true)
|
272
|
-
end
|
273
|
-
|
274
|
-
it "should not include non-existing fields" do
|
275
|
-
expect(subject.include?("doesnotexist")).to eq(false)
|
276
|
-
expect(subject.include?("[j][doesnotexist]")).to eq(false)
|
277
|
-
expect(subject.include?("[tag][0][hello][yes]")).to eq(false)
|
278
|
-
end
|
279
|
-
|
280
|
-
it "should include within arrays" do
|
281
|
-
expect(subject.include?("[tags][0]")).to eq(true)
|
282
|
-
expect(subject.include?("[tags][1]")).to eq(false)
|
283
|
-
end
|
284
|
-
end
|
285
|
-
|
286
|
-
context "#overwrite" do
|
287
|
-
it "should swap data with new content" do
|
288
|
-
new_event = LogStash::Event.new(
|
289
|
-
"type" => "new",
|
290
|
-
"message" => "foo bar",
|
291
|
-
)
|
292
|
-
subject.overwrite(new_event)
|
293
|
-
|
294
|
-
expect(subject["message"]).to eq("foo bar")
|
295
|
-
expect(subject["type"]).to eq("new")
|
296
|
-
|
297
|
-
["tags", "source", "a", "c", "f", "j"].each do |field|
|
298
|
-
expect(subject[field]).to be_nil
|
299
|
-
end
|
300
|
-
end
|
301
|
-
end
|
302
|
-
|
303
|
-
context "#append" do
|
304
|
-
it "should append strings to an array" do
|
305
|
-
subject.append(LogStash::Event.new("message" => "another thing"))
|
306
|
-
expect(subject["message"]).to eq([ "hello world", "another thing" ])
|
307
|
-
end
|
308
|
-
|
309
|
-
it "should concatenate tags" do
|
310
|
-
subject.append(LogStash::Event.new("tags" => [ "tag2" ]))
|
311
|
-
# added to_a for when array is a Java Collection when produced from json input
|
312
|
-
# TODO: we have to find a better way to handle this in tests. maybe override
|
313
|
-
# rspec eq or == to do an explicit to_a when comparing arrays?
|
314
|
-
expect(subject["tags"].to_a).to eq([ "tag1", "tag2" ])
|
315
|
-
end
|
316
|
-
|
317
|
-
context "when event field is nil" do
|
318
|
-
it "should add single value as string" do
|
319
|
-
subject.append(LogStash::Event.new({"field1" => "append1"}))
|
320
|
-
expect(subject[ "field1" ]).to eq("append1")
|
321
|
-
end
|
322
|
-
it "should add multi values as array" do
|
323
|
-
subject.append(LogStash::Event.new({"field1" => [ "append1","append2" ]}))
|
324
|
-
expect(subject[ "field1" ]).to eq([ "append1","append2" ])
|
325
|
-
end
|
326
|
-
end
|
327
|
-
|
328
|
-
context "when event field is a string" do
|
329
|
-
before { subject[ "field1" ] = "original1" }
|
330
|
-
|
331
|
-
it "should append string to values, if different from current" do
|
332
|
-
subject.append(LogStash::Event.new({"field1" => "append1"}))
|
333
|
-
expect(subject[ "field1" ]).to eq([ "original1", "append1" ])
|
334
|
-
end
|
335
|
-
it "should not change value, if appended value is equal current" do
|
336
|
-
subject.append(LogStash::Event.new({"field1" => "original1"}))
|
337
|
-
expect(subject[ "field1" ]).to eq("original1")
|
338
|
-
end
|
339
|
-
it "should concatenate values in an array" do
|
340
|
-
subject.append(LogStash::Event.new({"field1" => [ "append1" ]}))
|
341
|
-
expect(subject[ "field1" ]).to eq([ "original1", "append1" ])
|
342
|
-
end
|
343
|
-
it "should join array, removing duplicates" do
|
344
|
-
subject.append(LogStash::Event.new({"field1" => [ "append1","original1" ]}))
|
345
|
-
expect(subject[ "field1" ]).to eq([ "original1", "append1" ])
|
346
|
-
end
|
347
|
-
end
|
348
|
-
context "when event field is an array" do
|
349
|
-
before { subject[ "field1" ] = [ "original1", "original2" ] }
|
350
|
-
|
351
|
-
it "should append string values to array, if not present in array" do
|
352
|
-
subject.append(LogStash::Event.new({"field1" => "append1"}))
|
353
|
-
expect(subject[ "field1" ]).to eq([ "original1", "original2", "append1" ])
|
354
|
-
end
|
355
|
-
it "should not append string values, if the array already contains it" do
|
356
|
-
subject.append(LogStash::Event.new({"field1" => "original1"}))
|
357
|
-
expect(subject[ "field1" ]).to eq([ "original1", "original2" ])
|
358
|
-
end
|
359
|
-
it "should join array, removing duplicates" do
|
360
|
-
subject.append(LogStash::Event.new({"field1" => [ "append1","original1" ]}))
|
361
|
-
expect(subject[ "field1" ]).to eq([ "original1", "original2", "append1" ])
|
362
|
-
end
|
363
|
-
end
|
364
|
-
|
365
|
-
end
|
366
|
-
|
367
|
-
it "timestamp parsing speed", :performance => true do
|
368
|
-
warmup = 10000
|
369
|
-
count = 1000000
|
370
|
-
|
371
|
-
data = { "@timestamp" => "2013-12-21T07:25:06.605Z" }
|
372
|
-
event = LogStash::Event.new(data)
|
373
|
-
expect(event["@timestamp"]).to be_a(LogStash::Timestamp)
|
374
|
-
|
375
|
-
duration = 0
|
376
|
-
[warmup, count].each do |i|
|
377
|
-
start = Time.now
|
378
|
-
i.times do
|
379
|
-
data = { "@timestamp" => "2013-12-21T07:25:06.605Z" }
|
380
|
-
LogStash::Event.new(data.clone)
|
381
|
-
end
|
382
|
-
duration = Time.now - start
|
383
|
-
end
|
384
|
-
puts "event @timestamp parse rate: #{"%02.0f/sec" % (count / duration)}, elapsed: #{duration}s"
|
385
|
-
end
|
386
|
-
|
387
|
-
context "acceptable @timestamp formats" do
|
388
|
-
subject { LogStash::Event.new }
|
389
|
-
|
390
|
-
formats = [
|
391
|
-
"YYYY-MM-dd'T'HH:mm:ss.SSSZ",
|
392
|
-
"YYYY-MM-dd'T'HH:mm:ss.SSSSSSZ",
|
393
|
-
"YYYY-MM-dd'T'HH:mm:ss.SSS",
|
394
|
-
"YYYY-MM-dd'T'HH:mm:ss",
|
395
|
-
"YYYY-MM-dd'T'HH:mm:ssZ",
|
396
|
-
]
|
397
|
-
formats.each do |format|
|
398
|
-
it "includes #{format}" do
|
399
|
-
time = subject.sprintf("%{+#{format}}")
|
400
|
-
begin
|
401
|
-
LogStash::Event.new("@timestamp" => time)
|
402
|
-
rescue => e
|
403
|
-
raise StandardError, "Time '#{time}' was rejected. #{e.class}: #{e.to_s}"
|
404
|
-
end
|
405
|
-
end
|
406
|
-
end
|
407
|
-
|
408
|
-
context "from LOGSTASH-1738" do
|
409
|
-
it "does not error" do
|
410
|
-
LogStash::Event.new("@timestamp" => "2013-12-29T23:12:52.371240+02:00")
|
411
|
-
end
|
412
|
-
end
|
413
|
-
|
414
|
-
context "from LOGSTASH-1732" do
|
415
|
-
it "does not error" do
|
416
|
-
LogStash::Event.new("@timestamp" => "2013-12-27T11:07:25+00:00")
|
417
|
-
end
|
418
|
-
end
|
419
|
-
end
|
420
|
-
|
421
|
-
context "timestamp initialization" do
|
422
|
-
let(:logger_mock) { double("logger") }
|
423
|
-
|
424
|
-
after(:each) do
|
425
|
-
LogStash::Event.logger = LogStash::Event::DEFAULT_LOGGER
|
426
|
-
end
|
427
|
-
|
428
|
-
it "should coerce timestamp" do
|
429
|
-
t = Time.iso8601("2014-06-12T00:12:17.114Z")
|
430
|
-
expect(LogStash::Event.new("@timestamp" => t).timestamp.to_i).to eq(t.to_i)
|
431
|
-
expect(LogStash::Event.new("@timestamp" => LogStash::Timestamp.new(t)).timestamp.to_i).to eq(t.to_i)
|
432
|
-
expect(LogStash::Event.new("@timestamp" => "2014-06-12T00:12:17.114Z").timestamp.to_i).to eq(t.to_i)
|
433
|
-
end
|
434
|
-
|
435
|
-
it "should assign current time when no timestamp" do
|
436
|
-
expect(LogStash::Event.new({}).timestamp.to_i).to be_within(1).of (Time.now.to_i)
|
437
|
-
end
|
438
|
-
|
439
|
-
it "should tag for invalid value" do
|
440
|
-
event = LogStash::Event.new("@timestamp" => "foo")
|
441
|
-
expect(event.timestamp.to_i).to be_within(1).of Time.now.to_i
|
442
|
-
expect(event["tags"]).to eq([LogStash::Event::TIMESTAMP_FAILURE_TAG])
|
443
|
-
expect(event[LogStash::Event::TIMESTAMP_FAILURE_FIELD]).to eq("foo")
|
444
|
-
|
445
|
-
event = LogStash::Event.new("@timestamp" => 666)
|
446
|
-
expect(event.timestamp.to_i).to be_within(1).of Time.now.to_i
|
447
|
-
expect(event["tags"]).to eq([LogStash::Event::TIMESTAMP_FAILURE_TAG])
|
448
|
-
expect(event[LogStash::Event::TIMESTAMP_FAILURE_FIELD]).to eq(666)
|
449
|
-
end
|
450
|
-
|
451
|
-
it "should warn for invalid value" do
|
452
|
-
LogStash::Event.logger = logger_mock
|
453
|
-
|
454
|
-
expect(logger_mock).to receive(:warn).twice
|
455
|
-
|
456
|
-
LogStash::Event.new("@timestamp" => :foo)
|
457
|
-
LogStash::Event.new("@timestamp" => 666)
|
458
|
-
end
|
459
|
-
|
460
|
-
it "should tag for invalid string format" do
|
461
|
-
event = LogStash::Event.new("@timestamp" => "foo")
|
462
|
-
expect(event.timestamp.to_i).to be_within(1).of Time.now.to_i
|
463
|
-
expect(event["tags"]).to eq([LogStash::Event::TIMESTAMP_FAILURE_TAG])
|
464
|
-
expect(event[LogStash::Event::TIMESTAMP_FAILURE_FIELD]).to eq("foo")
|
465
|
-
end
|
466
|
-
|
467
|
-
it "should warn for invalid string format" do
|
468
|
-
LogStash::Event.logger = logger_mock
|
469
|
-
|
470
|
-
expect(logger_mock).to receive(:warn)
|
471
|
-
LogStash::Event.new("@timestamp" => "foo")
|
472
|
-
end
|
473
|
-
end
|
474
|
-
|
475
|
-
context "to_json" do
|
476
|
-
it "should support to_json" do
|
477
|
-
new_event = LogStash::Event.new(
|
478
|
-
"@timestamp" => Time.iso8601("2014-09-23T19:26:15.832Z"),
|
479
|
-
"message" => "foo bar",
|
480
|
-
)
|
481
|
-
json = new_event.to_json
|
482
|
-
|
483
|
-
expect(JSON.parse(json)).to eq( JSON.parse("{\"@timestamp\":\"2014-09-23T19:26:15.832Z\",\"message\":\"foo bar\",\"@version\":\"1\"}"))
|
484
|
-
end
|
485
|
-
|
486
|
-
it "should support to_json and ignore arguments" do
|
487
|
-
new_event = LogStash::Event.new(
|
488
|
-
"@timestamp" => Time.iso8601("2014-09-23T19:26:15.832Z"),
|
489
|
-
"message" => "foo bar",
|
490
|
-
)
|
491
|
-
json = new_event.to_json(:foo => 1, :bar => "baz")
|
492
|
-
|
493
|
-
expect(JSON.parse(json)).to eq( JSON.parse("{\"@timestamp\":\"2014-09-23T19:26:15.832Z\",\"message\":\"foo bar\",\"@version\":\"1\"}"))
|
494
|
-
end
|
495
|
-
end
|
496
|
-
|
497
|
-
context "metadata" do
|
498
|
-
context "with existing metadata" do
|
499
|
-
subject { LogStash::Event.new("hello" => "world", "@metadata" => { "fancy" => "pants" }) }
|
500
|
-
|
501
|
-
it "should not include metadata in to_hash" do
|
502
|
-
expect(subject.to_hash.keys).not_to include("@metadata")
|
503
|
-
|
504
|
-
# 'hello', '@timestamp', and '@version'
|
505
|
-
expect(subject.to_hash.keys.count).to eq(3)
|
506
|
-
end
|
507
|
-
|
508
|
-
it "should still allow normal field access" do
|
509
|
-
expect(subject["hello"]).to eq("world")
|
510
|
-
end
|
511
|
-
end
|
512
|
-
|
513
|
-
context "with set metadata" do
|
514
|
-
let(:fieldref) { "[@metadata][foo][bar]" }
|
515
|
-
let(:value) { "bar" }
|
516
|
-
subject { LogStash::Event.new("normal" => "normal") }
|
517
|
-
before do
|
518
|
-
# Verify the test is configured correctly.
|
519
|
-
expect(fieldref).to start_with("[@metadata]")
|
520
|
-
|
521
|
-
# Set it.
|
522
|
-
subject[fieldref] = value
|
523
|
-
end
|
524
|
-
|
525
|
-
it "should still allow normal field access" do
|
526
|
-
expect(subject["normal"]).to eq("normal")
|
527
|
-
end
|
528
|
-
|
529
|
-
it "should allow getting" do
|
530
|
-
expect(subject[fieldref]).to eq(value)
|
531
|
-
end
|
532
|
-
|
533
|
-
it "should be hidden from .to_json" do
|
534
|
-
require "json"
|
535
|
-
obj = JSON.parse(subject.to_json)
|
536
|
-
expect(obj).not_to include("@metadata")
|
537
|
-
end
|
538
|
-
|
539
|
-
it "should be hidden from .to_hash" do
|
540
|
-
expect(subject.to_hash).not_to include("@metadata")
|
541
|
-
end
|
542
|
-
|
543
|
-
it "should be accessible through #to_hash_with_metadata" do
|
544
|
-
obj = subject.to_hash_with_metadata
|
545
|
-
expect(obj).to include("@metadata")
|
546
|
-
expect(obj["@metadata"]["foo"]["bar"]).to eq(value)
|
547
|
-
end
|
548
|
-
end
|
549
|
-
|
550
|
-
context "with no metadata" do
|
551
|
-
subject { LogStash::Event.new("foo" => "bar") }
|
552
|
-
it "should have no metadata" do
|
553
|
-
expect(subject["@metadata"]).to be_empty
|
554
|
-
end
|
555
|
-
it "should still allow normal field access" do
|
556
|
-
expect(subject["foo"]).to eq("bar")
|
557
|
-
end
|
558
|
-
|
559
|
-
it "should not include the @metadata key" do
|
560
|
-
expect(subject.to_hash_with_metadata).not_to include("@metadata")
|
561
|
-
end
|
562
|
-
end
|
563
|
-
end
|
564
|
-
|
565
|
-
context "signal events" do
|
566
|
-
it "should define the shutdown event" do
|
567
|
-
# the SHUTDOWN and FLUSH constants are part of the plugin API contract
|
568
|
-
# if they are changed, all plugins must be updated
|
569
|
-
expect(LogStash::SHUTDOWN).to be_a(LogStash::ShutdownEvent)
|
570
|
-
expect(LogStash::FLUSH).to be_a(LogStash::FlushEvent)
|
571
|
-
end
|
572
|
-
end
|
573
|
-
end
|
574
|
-
|
575
|
-
let(:event_hash) do
|
576
|
-
{
|
577
|
-
"@timestamp" => "2013-01-01T00:00:00.000Z",
|
578
|
-
"type" => "sprintf",
|
579
|
-
"message" => "hello world",
|
580
|
-
"tags" => [ "tag1" ],
|
581
|
-
"source" => "/home/foo",
|
582
|
-
"a" => "b",
|
583
|
-
"c" => {
|
584
|
-
"d" => "f",
|
585
|
-
"e" => {"f" => "g"}
|
586
|
-
},
|
587
|
-
"f" => { "g" => { "h" => "i" } },
|
588
|
-
"j" => {
|
589
|
-
"k1" => "v",
|
590
|
-
"k2" => [ "w", "x" ],
|
591
|
-
"k3" => {"4" => "m"},
|
592
|
-
"k4" => [ {"nested" => "cool"} ],
|
593
|
-
5 => 6,
|
594
|
-
"5" => 7
|
595
|
-
},
|
596
|
-
"nilfield" => nil,
|
597
|
-
"@metadata" => { "fancy" => "pants", "have-to-go" => { "deeper" => "inception" } }
|
598
|
-
}
|
599
|
-
end
|
600
|
-
|
601
|
-
describe "using normal hash input" do
|
602
|
-
it_behaves_like "all event tests" do
|
603
|
-
subject{LogStash::Event.new(event_hash)}
|
604
|
-
end
|
605
|
-
end
|
606
|
-
|
607
|
-
describe "using hash input from deserialized json" do
|
608
|
-
# this is to test the case when JrJackson deserialises Json and produces
|
609
|
-
# native Java Collections objects for efficiency
|
610
|
-
it_behaves_like "all event tests" do
|
611
|
-
subject{LogStash::Event.new(LogStash::Json.load(LogStash::Json.dump(event_hash)))}
|
612
|
-
end
|
613
|
-
end
|
614
|
-
|
615
|
-
|
616
|
-
describe "#to_s" do
|
617
|
-
let(:timestamp) { LogStash::Timestamp.new }
|
618
|
-
let(:event1) { LogStash::Event.new({ "@timestamp" => timestamp, "host" => "foo", "message" => "bar"}) }
|
619
|
-
let(:event2) { LogStash::Event.new({ "host" => "bar", "message" => "foo"}) }
|
620
|
-
|
621
|
-
it "should cache only one template" do
|
622
|
-
LogStash::StringInterpolation.clear_cache
|
623
|
-
expect {
|
624
|
-
event1.to_s
|
625
|
-
event2.to_s
|
626
|
-
}.to change { LogStash::StringInterpolation.cache_size }.by(1)
|
627
|
-
end
|
628
|
-
|
629
|
-
it "return the string containing the timestamp, the host and the message" do
|
630
|
-
expect(event1.to_s).to eq("#{timestamp.to_iso8601} #{event1["host"]} #{event1["message"]}")
|
631
|
-
end
|
632
|
-
end
|
633
|
-
|
634
|
-
describe "Event accessors" do
|
635
|
-
let(:event) { LogStash::Event.new({ "message" => "foo" }) }
|
636
|
-
|
637
|
-
it "should invalidate target caching" do
|
638
|
-
expect(event["[a][0]"]).to be_nil
|
639
|
-
|
640
|
-
expect(event["[a][0]"] = 42).to eq(42)
|
641
|
-
expect(event["[a][0]"]).to eq(42)
|
642
|
-
expect(event["[a]"]).to eq({"0" => 42})
|
643
|
-
|
644
|
-
expect(event["[a]"] = [42, 24]).to eq([42, 24])
|
645
|
-
expect(event["[a]"]).to eq([42, 24])
|
646
|
-
|
647
|
-
expect(event["[a][0]"]).to eq(42)
|
648
|
-
|
649
|
-
expect(event["[a]"] = [24, 42]).to eq([24, 42])
|
650
|
-
expect(event["[a][0]"]).to eq(24)
|
651
|
-
|
652
|
-
expect(event["[a][0]"] = {"a "=> 99, "b" => 98}).to eq({"a "=> 99, "b" => 98})
|
653
|
-
expect(event["[a][0]"]).to eq({"a "=> 99, "b" => 98})
|
654
|
-
|
655
|
-
expect(event["[a]"]).to eq([{"a "=> 99, "b" => 98}, 42])
|
656
|
-
expect(event["[a][0]"]).to eq({"a "=> 99, "b" => 98})
|
657
|
-
expect(event["[a][1]"]).to eq(42)
|
658
|
-
expect(event["[a][0][b]"]).to eq(98)
|
659
|
-
end
|
660
|
-
end
|
661
|
-
end
|
662
|
-
|