logstash-core-event 2.3.4.snapshot1-java → 2.4.0-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 +5 -2
- data/lib/logstash/util/accessors.rb +8 -1
- data/spec/logstash/event_old_api_spec.rb +662 -0
- data/spec/logstash/event_spec.rb +113 -85
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 87174698a9f117a5101ba641f916e2f3c95f6794
|
4
|
+
data.tar.gz: ca91fe3530014e44259bf9498c0a37d4d379a104
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a58b3ff4a45e9103ddd1672a2c178ef8037e5a0ee042f2ff63eeb50b034d800bcb04d6bfc94dbd25c6110aa6f6c6a6f68162684340e0d5c46d44d1b86003d537
|
7
|
+
data.tar.gz: b15c1bb7577313e03a9e5d7730444fc29a538a600dc65060a700fb20742d6cc8201aff98968e1fc84b5fc6a65bd030dce9c2b9bd24d5b351037e9b9596a0cdf0
|
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 get(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 set(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,6 +137,9 @@ class LogStash::Event
|
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
140
|
+
alias_method :[], :get
|
141
|
+
alias_method :[]=, :set
|
142
|
+
|
140
143
|
def to_json(*args)
|
141
144
|
# ignore arguments to respect accepted to_json method signature
|
142
145
|
LogStash::Json.dump(@data)
|
@@ -95,7 +95,14 @@ 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
|
-
@lut
|
98
|
+
# flush the @lut to prevent stale cached fieldref which may point to an old target
|
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)
|
99
106
|
end
|
100
107
|
|
101
108
|
# find the target container object in store for this field reference
|
@@ -0,0 +1,662 @@
|
|
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
|
+
|
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.set("@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.get("foo")).to be_nil
|
16
|
+
expect(subject.set("foo", "bar")).to eq("bar")
|
17
|
+
expect(subject.get("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.get("foo")).to be_nil
|
22
|
+
expect(subject.set("foo", "bar")).to eq("bar")
|
23
|
+
expect(subject.get("foo")).to eq("bar")
|
24
24
|
|
25
|
-
expect(subject
|
26
|
-
expect(subject
|
25
|
+
expect(subject.set("foo", "baz")).to eq("baz")
|
26
|
+
expect(subject.get("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.get("[foo][bar]")).to be_nil
|
31
|
+
expect(subject.set("[foo][bar]", "baz")).to eq("baz")
|
32
|
+
expect(subject.get("[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.get("[foo][bar]")).to be_nil
|
37
|
+
expect(subject.set("[foo][bar]", "baz")).to eq("baz")
|
38
|
+
expect(subject.get("[foo][bar]")).to eq("baz")
|
39
39
|
|
40
|
-
expect(subject
|
41
|
-
expect(subject
|
40
|
+
expect(subject.set("[foo][bar]", "zab")).to eq("zab")
|
41
|
+
expect(subject.get("[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.set("@metadata", { "action" => "index" })
|
46
|
+
expect(subject.get("[@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.set("[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.set("[foo]", ["bar", "baz"])
|
56
56
|
|
57
|
-
expect(subject
|
58
|
-
expect(subject
|
57
|
+
expect(subject.set("[foo][0]", nil)).to eq(nil)
|
58
|
+
expect(subject.get("[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.set("[foo]", [])
|
63
63
|
|
64
|
-
expect(subject
|
65
|
-
expect(subject
|
64
|
+
expect(subject.set("[foo][0]", nil)).to eq(nil)
|
65
|
+
expect(subject.get("[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.set("[foo]", [])
|
70
70
|
|
71
|
-
expect(subject
|
72
|
-
expect(subject
|
71
|
+
expect(subject.set("[foo][1]", nil)).to eq(nil)
|
72
|
+
expect(subject.get("[foo]")).to eq([nil, nil])
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
@@ -79,7 +79,7 @@ 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.get("reference_test")).not_to eq(data)
|
83
83
|
end
|
84
84
|
|
85
85
|
# TODO: This was a bug and should only be true in the context of 2.3.X
|
@@ -88,7 +88,7 @@ describe LogStash::Event do
|
|
88
88
|
data = 1
|
89
89
|
event = LogStash::Event.new({ "reference" => data })
|
90
90
|
LogStash::Util::Decorators.add_fields({"reference_test" => "%{reference}"}, event, "dummy-plugin")
|
91
|
-
expect(event
|
91
|
+
expect(event.get("reference_test")).to eq(1)
|
92
92
|
end
|
93
93
|
|
94
94
|
# TODO: This was a bug and should only be true in the context of 2.3.X
|
@@ -97,7 +97,7 @@ describe LogStash::Event do
|
|
97
97
|
data = 1.999
|
98
98
|
event = LogStash::Event.new({ "reference" => data })
|
99
99
|
LogStash::Util::Decorators.add_fields({"reference_test" => "%{reference}"}, event, "dummy-plugin")
|
100
|
-
expect(event
|
100
|
+
expect(event.get("reference_test")).to eq(1.999)
|
101
101
|
end
|
102
102
|
|
103
103
|
# TODO: This was a bug and should only be true in the context of 2.3.X
|
@@ -106,7 +106,7 @@ describe LogStash::Event do
|
|
106
106
|
data = true
|
107
107
|
event = LogStash::Event.new({ "reference" => data })
|
108
108
|
LogStash::Util::Decorators.add_fields({"reference_test" => "%{reference}"}, event, "dummy-plugin")
|
109
|
-
expect(event
|
109
|
+
expect(event.get("reference_test")).to be_kind_of(TrueClass)
|
110
110
|
end
|
111
111
|
|
112
112
|
# TODO: This was a bug and should only be true in the context of 2.3.X
|
@@ -115,7 +115,7 @@ describe LogStash::Event do
|
|
115
115
|
data = false
|
116
116
|
event = LogStash::Event.new({ "reference" => data })
|
117
117
|
LogStash::Util::Decorators.add_fields({"reference_test" => "%{reference}"}, event, "dummy-plugin")
|
118
|
-
expect(event
|
118
|
+
expect(event.get("reference_test")).to be_kind_of(FalseClass)
|
119
119
|
end
|
120
120
|
|
121
121
|
it "should report a unix timestamp for %{+%s}" do
|
@@ -152,7 +152,7 @@ describe LogStash::Event do
|
|
152
152
|
|
153
153
|
it "should report fields with %{field} syntax" do
|
154
154
|
expect(subject.sprintf("%{type}")).to eq("sprintf")
|
155
|
-
expect(subject.sprintf("%{message}")).to eq(subject
|
155
|
+
expect(subject.sprintf("%{message}")).to eq(subject.get("message"))
|
156
156
|
end
|
157
157
|
|
158
158
|
it "should print deep fields" do
|
@@ -181,35 +181,35 @@ describe LogStash::Event do
|
|
181
181
|
end
|
182
182
|
|
183
183
|
it "should render nil array values as leading empty string" do
|
184
|
-
expect(subject
|
184
|
+
expect(subject.set("foo", [nil, "baz"])).to eq([nil, "baz"])
|
185
185
|
|
186
|
-
expect(subject
|
187
|
-
expect(subject
|
186
|
+
expect(subject.get("[foo][0]")).to be_nil
|
187
|
+
expect(subject.get("[foo][1]")).to eq("baz")
|
188
188
|
|
189
189
|
expect(subject.sprintf("%{[foo]}")).to eq(",baz")
|
190
190
|
end
|
191
191
|
|
192
192
|
it "should render nil array values as middle empty string" do
|
193
|
-
expect(subject
|
193
|
+
expect(subject.set("foo", ["bar", nil, "baz"])).to eq(["bar", nil, "baz"])
|
194
194
|
|
195
|
-
expect(subject
|
196
|
-
expect(subject
|
197
|
-
expect(subject
|
195
|
+
expect(subject.get("[foo][0]")).to eq("bar")
|
196
|
+
expect(subject.get("[foo][1]")).to be_nil
|
197
|
+
expect(subject.get("[foo][2]")).to eq("baz")
|
198
198
|
|
199
199
|
expect(subject.sprintf("%{[foo]}")).to eq("bar,,baz")
|
200
200
|
end
|
201
201
|
|
202
202
|
it "should render nil array values as trailing empty string" do
|
203
|
-
expect(subject
|
203
|
+
expect(subject.set("foo", ["bar", nil])).to eq(["bar", nil])
|
204
204
|
|
205
|
-
expect(subject
|
206
|
-
expect(subject
|
205
|
+
expect(subject.get("[foo][0]")).to eq("bar")
|
206
|
+
expect(subject.get("[foo][1]")).to be_nil
|
207
207
|
|
208
208
|
expect(subject.sprintf("%{[foo]}")).to eq("bar,")
|
209
209
|
end
|
210
210
|
|
211
211
|
it "should render deep arrays with nil value" do
|
212
|
-
subject
|
212
|
+
subject.set("[foo]", [[12, nil], 56])
|
213
213
|
expect(subject.sprintf("%{[foo]}")).to eq("12,,56")
|
214
214
|
end
|
215
215
|
|
@@ -226,18 +226,18 @@ describe LogStash::Event do
|
|
226
226
|
|
227
227
|
context "#[]" do
|
228
228
|
it "should fetch data" do
|
229
|
-
expect(subject
|
229
|
+
expect(subject.get("type")).to eq("sprintf")
|
230
230
|
end
|
231
231
|
it "should fetch fields" do
|
232
|
-
expect(subject
|
233
|
-
expect(subject
|
232
|
+
expect(subject.get("a")).to eq("b")
|
233
|
+
expect(subject.get('c')['d']).to eq("f")
|
234
234
|
end
|
235
235
|
it "should fetch deep fields" do
|
236
|
-
expect(subject
|
237
|
-
expect(subject
|
238
|
-
expect(subject
|
239
|
-
expect(subject
|
240
|
-
expect(subject
|
236
|
+
expect(subject.get("[j][k1]")).to eq("v")
|
237
|
+
expect(subject.get("[c][d]")).to eq("f")
|
238
|
+
expect(subject.get('[f][g][h]')).to eq("i")
|
239
|
+
expect(subject.get('[j][k3][4]')).to eq("m")
|
240
|
+
expect(subject.get('[j][5]')).to eq(7)
|
241
241
|
|
242
242
|
end
|
243
243
|
|
@@ -245,7 +245,7 @@ describe LogStash::Event do
|
|
245
245
|
count = 1000000
|
246
246
|
2.times do
|
247
247
|
start = Time.now
|
248
|
-
count.times { subject
|
248
|
+
count.times { subject.get("[j][k1]") }
|
249
249
|
duration = Time.now - start
|
250
250
|
puts "event #[] rate: #{"%02.0f/sec" % (count / duration)}, elapsed: #{duration}s"
|
251
251
|
end
|
@@ -291,11 +291,11 @@ describe LogStash::Event do
|
|
291
291
|
)
|
292
292
|
subject.overwrite(new_event)
|
293
293
|
|
294
|
-
expect(subject
|
295
|
-
expect(subject
|
294
|
+
expect(subject.get("message")).to eq("foo bar")
|
295
|
+
expect(subject.get("type")).to eq("new")
|
296
296
|
|
297
297
|
["tags", "source", "a", "c", "f", "j"].each do |field|
|
298
|
-
expect(subject
|
298
|
+
expect(subject.get(field)).to be_nil
|
299
299
|
end
|
300
300
|
end
|
301
301
|
end
|
@@ -303,7 +303,7 @@ describe LogStash::Event do
|
|
303
303
|
context "#append" do
|
304
304
|
it "should append strings to an array" do
|
305
305
|
subject.append(LogStash::Event.new("message" => "another thing"))
|
306
|
-
expect(subject
|
306
|
+
expect(subject.get("message")).to eq([ "hello world", "another thing" ])
|
307
307
|
end
|
308
308
|
|
309
309
|
it "should concatenate tags" do
|
@@ -311,54 +311,54 @@ describe LogStash::Event do
|
|
311
311
|
# added to_a for when array is a Java Collection when produced from json input
|
312
312
|
# TODO: we have to find a better way to handle this in tests. maybe override
|
313
313
|
# rspec eq or == to do an explicit to_a when comparing arrays?
|
314
|
-
expect(subject
|
314
|
+
expect(subject.get("tags").to_a).to eq([ "tag1", "tag2" ])
|
315
315
|
end
|
316
316
|
|
317
317
|
context "when event field is nil" do
|
318
318
|
it "should add single value as string" do
|
319
319
|
subject.append(LogStash::Event.new({"field1" => "append1"}))
|
320
|
-
expect(subject
|
320
|
+
expect(subject.get("field1")).to eq("append1")
|
321
321
|
end
|
322
322
|
it "should add multi values as array" do
|
323
323
|
subject.append(LogStash::Event.new({"field1" => [ "append1","append2" ]}))
|
324
|
-
expect(subject
|
324
|
+
expect(subject.get("field1")).to eq([ "append1","append2" ])
|
325
325
|
end
|
326
326
|
end
|
327
327
|
|
328
328
|
context "when event field is a string" do
|
329
|
-
before { subject
|
329
|
+
before { subject.set("field1", "original1") }
|
330
330
|
|
331
331
|
it "should append string to values, if different from current" do
|
332
332
|
subject.append(LogStash::Event.new({"field1" => "append1"}))
|
333
|
-
expect(subject
|
333
|
+
expect(subject.get("field1")).to eq([ "original1", "append1" ])
|
334
334
|
end
|
335
335
|
it "should not change value, if appended value is equal current" do
|
336
336
|
subject.append(LogStash::Event.new({"field1" => "original1"}))
|
337
|
-
expect(subject
|
337
|
+
expect(subject.get("field1")).to eq("original1")
|
338
338
|
end
|
339
339
|
it "should concatenate values in an array" do
|
340
340
|
subject.append(LogStash::Event.new({"field1" => [ "append1" ]}))
|
341
|
-
expect(subject
|
341
|
+
expect(subject.get("field1")).to eq([ "original1", "append1" ])
|
342
342
|
end
|
343
343
|
it "should join array, removing duplicates" do
|
344
344
|
subject.append(LogStash::Event.new({"field1" => [ "append1","original1" ]}))
|
345
|
-
expect(subject
|
345
|
+
expect(subject.get("field1")).to eq([ "original1", "append1" ])
|
346
346
|
end
|
347
347
|
end
|
348
348
|
context "when event field is an array" do
|
349
|
-
before { subject
|
349
|
+
before { subject.set("field1", [ "original1", "original2" ] )}
|
350
350
|
|
351
351
|
it "should append string values to array, if not present in array" do
|
352
352
|
subject.append(LogStash::Event.new({"field1" => "append1"}))
|
353
|
-
expect(subject
|
353
|
+
expect(subject.get("field1")).to eq([ "original1", "original2", "append1" ])
|
354
354
|
end
|
355
355
|
it "should not append string values, if the array already contains it" do
|
356
356
|
subject.append(LogStash::Event.new({"field1" => "original1"}))
|
357
|
-
expect(subject
|
357
|
+
expect(subject.get("field1")).to eq([ "original1", "original2" ])
|
358
358
|
end
|
359
359
|
it "should join array, removing duplicates" do
|
360
360
|
subject.append(LogStash::Event.new({"field1" => [ "append1","original1" ]}))
|
361
|
-
expect(subject
|
361
|
+
expect(subject.get("field1")).to eq([ "original1", "original2", "append1" ])
|
362
362
|
end
|
363
363
|
end
|
364
364
|
|
@@ -370,7 +370,7 @@ describe LogStash::Event do
|
|
370
370
|
|
371
371
|
data = { "@timestamp" => "2013-12-21T07:25:06.605Z" }
|
372
372
|
event = LogStash::Event.new(data)
|
373
|
-
expect(event
|
373
|
+
expect(event.get("@timestamp")).to be_a(LogStash::Timestamp)
|
374
374
|
|
375
375
|
duration = 0
|
376
376
|
[warmup, count].each do |i|
|
@@ -439,13 +439,13 @@ describe LogStash::Event do
|
|
439
439
|
it "should tag for invalid value" do
|
440
440
|
event = LogStash::Event.new("@timestamp" => "foo")
|
441
441
|
expect(event.timestamp.to_i).to be_within(1).of Time.now.to_i
|
442
|
-
expect(event
|
443
|
-
expect(event
|
442
|
+
expect(event.get("tags")).to eq([LogStash::Event::TIMESTAMP_FAILURE_TAG])
|
443
|
+
expect(event.get(LogStash::Event::TIMESTAMP_FAILURE_FIELD)).to eq("foo")
|
444
444
|
|
445
445
|
event = LogStash::Event.new("@timestamp" => 666)
|
446
446
|
expect(event.timestamp.to_i).to be_within(1).of Time.now.to_i
|
447
|
-
expect(event
|
448
|
-
expect(event
|
447
|
+
expect(event.get("tags")).to eq([LogStash::Event::TIMESTAMP_FAILURE_TAG])
|
448
|
+
expect(event.get(LogStash::Event::TIMESTAMP_FAILURE_FIELD)).to eq(666)
|
449
449
|
end
|
450
450
|
|
451
451
|
it "should warn for invalid value" do
|
@@ -460,8 +460,8 @@ describe LogStash::Event do
|
|
460
460
|
it "should tag for invalid string format" do
|
461
461
|
event = LogStash::Event.new("@timestamp" => "foo")
|
462
462
|
expect(event.timestamp.to_i).to be_within(1).of Time.now.to_i
|
463
|
-
expect(event
|
464
|
-
expect(event
|
463
|
+
expect(event.get("tags")).to eq([LogStash::Event::TIMESTAMP_FAILURE_TAG])
|
464
|
+
expect(event.get(LogStash::Event::TIMESTAMP_FAILURE_FIELD)).to eq("foo")
|
465
465
|
end
|
466
466
|
|
467
467
|
it "should warn for invalid string format" do
|
@@ -506,7 +506,7 @@ describe LogStash::Event do
|
|
506
506
|
end
|
507
507
|
|
508
508
|
it "should still allow normal field access" do
|
509
|
-
expect(subject
|
509
|
+
expect(subject.get("hello")).to eq("world")
|
510
510
|
end
|
511
511
|
end
|
512
512
|
|
@@ -519,15 +519,15 @@ describe LogStash::Event do
|
|
519
519
|
expect(fieldref).to start_with("[@metadata]")
|
520
520
|
|
521
521
|
# Set it.
|
522
|
-
subject
|
522
|
+
subject.set(fieldref, value)
|
523
523
|
end
|
524
524
|
|
525
525
|
it "should still allow normal field access" do
|
526
|
-
expect(subject
|
526
|
+
expect(subject.get("normal")).to eq("normal")
|
527
527
|
end
|
528
528
|
|
529
529
|
it "should allow getting" do
|
530
|
-
expect(subject
|
530
|
+
expect(subject.get(fieldref)).to eq(value)
|
531
531
|
end
|
532
532
|
|
533
533
|
it "should be hidden from .to_json" do
|
@@ -550,10 +550,10 @@ describe LogStash::Event do
|
|
550
550
|
context "with no metadata" do
|
551
551
|
subject { LogStash::Event.new("foo" => "bar") }
|
552
552
|
it "should have no metadata" do
|
553
|
-
expect(subject
|
553
|
+
expect(subject.get("@metadata")).to be_empty
|
554
554
|
end
|
555
555
|
it "should still allow normal field access" do
|
556
|
-
expect(subject
|
556
|
+
expect(subject.get("foo")).to eq("bar")
|
557
557
|
end
|
558
558
|
|
559
559
|
it "should not include the @metadata key" do
|
@@ -627,7 +627,35 @@ describe LogStash::Event do
|
|
627
627
|
end
|
628
628
|
|
629
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
|
630
|
+
expect(event1.to_s).to eq("#{timestamp.to_iso8601} #{event1.get("host")} #{event1.get("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.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)
|
631
659
|
end
|
632
660
|
end
|
633
661
|
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: 2.
|
4
|
+
version: 2.4.0
|
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-08-30 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,6 +25,7 @@ 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
|
28
29
|
- spec/logstash/event_spec.rb
|
29
30
|
- spec/logstash/timestamp_spec.rb
|
30
31
|
- spec/logstash/util/accessors_spec.rb
|
@@ -43,9 +44,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
43
44
|
version: '0'
|
44
45
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
46
|
requirements:
|
46
|
-
- - "
|
47
|
+
- - ">="
|
47
48
|
- !ruby/object:Gem::Version
|
48
|
-
version:
|
49
|
+
version: '0'
|
49
50
|
requirements: []
|
50
51
|
rubyforge_project:
|
51
52
|
rubygems_version: 2.4.8
|
@@ -53,6 +54,7 @@ signing_key:
|
|
53
54
|
specification_version: 4
|
54
55
|
summary: logstash-core-event - The core event component of logstash
|
55
56
|
test_files:
|
57
|
+
- spec/logstash/event_old_api_spec.rb
|
56
58
|
- spec/logstash/event_spec.rb
|
57
59
|
- spec/logstash/timestamp_spec.rb
|
58
60
|
- spec/logstash/util/accessors_spec.rb
|