logstash-core 6.0.1-java → 6.1.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/gemspec_jars.rb +1 -1
- data/lib/logstash-core/logstash-core.jar +0 -0
- data/lib/logstash-core/logstash-core.rb +14 -2
- data/lib/logstash-core_jars.rb +4 -2
- data/lib/logstash/agent.rb +8 -2
- data/lib/logstash/api/modules/node.rb +11 -5
- data/lib/logstash/api/modules/stats.rb +13 -7
- data/lib/logstash/compiler.rb +6 -10
- data/lib/logstash/compiler/lscl.rb +10 -1
- data/lib/logstash/compiler/lscl/helpers.rb +3 -1
- data/lib/logstash/config/mixin.rb +2 -2
- data/lib/logstash/environment.rb +1 -6
- data/lib/logstash/errors.rb +1 -1
- data/lib/logstash/event.rb +0 -2
- data/lib/logstash/filter_delegator.rb +1 -2
- data/lib/logstash/instrument/metric_type/counter.rb +1 -1
- data/lib/logstash/instrument/metric_type/gauge.rb +1 -1
- data/lib/logstash/instrument/wrapped_write_client.rb +1 -1
- data/lib/logstash/java_filter_delegator.rb +79 -0
- data/lib/logstash/java_pipeline.rb +690 -0
- data/lib/logstash/json.rb +4 -29
- data/lib/logstash/output_delegator.rb +3 -2
- data/lib/logstash/patches/bugfix_jruby_2558.rb +1 -1
- data/lib/logstash/pipeline.rb +32 -89
- data/lib/logstash/pipeline_action/create.rb +8 -2
- data/lib/logstash/pipeline_action/reload.rb +6 -1
- data/lib/logstash/pipeline_reporter.rb +2 -1
- data/lib/logstash/pipeline_settings.rb +1 -0
- data/lib/logstash/plugins/plugin_factory.rb +100 -0
- data/lib/logstash/plugins/registry.rb +18 -7
- data/lib/logstash/queue_factory.rb +3 -1
- data/lib/logstash/runner.rb +13 -56
- data/lib/logstash/settings.rb +2 -2
- data/lib/logstash/timestamp.rb +0 -1
- data/lib/logstash/util.rb +13 -21
- data/lib/logstash/util/java_version.rb +0 -1
- data/lib/logstash/util/settings_helper.rb +79 -0
- data/lib/logstash/util/{environment_variables.rb → substitution_variables.rb} +10 -8
- data/lib/logstash/util/wrapped_acked_queue.rb +17 -108
- data/lib/logstash/util/wrapped_synchronous_queue.rb +38 -178
- data/locales/en.yml +2 -0
- data/spec/conditionals_spec.rb +235 -80
- data/spec/logstash/api/modules/node_spec.rb +11 -0
- data/spec/logstash/compiler/compiler_spec.rb +28 -2
- data/spec/logstash/environment_spec.rb +0 -5
- data/spec/logstash/event_spec.rb +7 -2
- data/spec/logstash/filter_delegator_spec.rb +1 -1
- data/spec/logstash/filters/base_spec.rb +30 -28
- data/spec/logstash/instrument/wrapped_write_client_spec.rb +2 -2
- data/spec/logstash/java_filter_delegator_spec.rb +176 -0
- data/spec/logstash/java_pipeline_spec.rb +933 -0
- data/spec/logstash/json_spec.rb +27 -45
- data/spec/logstash/plugins/registry_spec.rb +7 -0
- data/spec/logstash/queue_factory_spec.rb +5 -2
- data/spec/logstash/settings_spec.rb +1 -1
- data/spec/logstash/util/java_version_spec.rb +1 -3
- data/spec/logstash/util/wrapped_synchronous_queue_spec.rb +27 -24
- data/spec/logstash/webserver_spec.rb +3 -6
- data/spec/support/helpers.rb +5 -0
- data/spec/support/pipeline/pipeline_helpers.rb +97 -0
- data/versions-gem-copy.yml +5 -2
- metadata +14 -5
- data/lib/logstash/patches/rubygems.rb +0 -38
@@ -2,33 +2,22 @@
|
|
2
2
|
|
3
3
|
module LogStash; module Util
|
4
4
|
class WrappedSynchronousQueue
|
5
|
-
java_import java.util.concurrent.
|
5
|
+
java_import java.util.concurrent.ArrayBlockingQueue
|
6
6
|
java_import java.util.concurrent.TimeUnit
|
7
|
+
java_import org.logstash.common.LsQueueUtils
|
7
8
|
|
8
|
-
def initialize
|
9
|
-
@queue =
|
9
|
+
def initialize (size)
|
10
|
+
@queue = ArrayBlockingQueue.new(size)
|
10
11
|
end
|
11
12
|
|
12
|
-
|
13
|
-
# it will block until the object can be added to the queue.
|
14
|
-
#
|
15
|
-
# @param [Object] Object to add to the queue
|
16
|
-
def push(obj)
|
17
|
-
@queue.put(obj)
|
18
|
-
end
|
19
|
-
alias_method(:<<, :push)
|
20
|
-
|
21
|
-
# Block for X millis
|
22
|
-
def poll(millis)
|
23
|
-
@queue.poll(millis, TimeUnit::MILLISECONDS)
|
24
|
-
end
|
13
|
+
attr_reader :queue
|
25
14
|
|
26
15
|
def write_client
|
27
|
-
WriteClient.new(
|
16
|
+
WriteClient.new(@queue)
|
28
17
|
end
|
29
18
|
|
30
19
|
def read_client
|
31
|
-
ReadClient.new(
|
20
|
+
ReadClient.new(@queue)
|
32
21
|
end
|
33
22
|
|
34
23
|
def close
|
@@ -42,15 +31,14 @@ module LogStash; module Util
|
|
42
31
|
|
43
32
|
def initialize(queue, batch_size = 125, wait_for = 250)
|
44
33
|
@queue = queue
|
45
|
-
@mutex = Mutex.new
|
46
34
|
# Note that @inflight_batches as a central mechanism for tracking inflight
|
47
35
|
# batches will fail if we have multiple read clients in the pipeline.
|
48
|
-
@inflight_batches =
|
36
|
+
@inflight_batches = Concurrent::Map.new
|
49
37
|
|
50
38
|
# allow the worker thread to report the execution time of the filter + output
|
51
|
-
@inflight_clocks =
|
39
|
+
@inflight_clocks = Concurrent::Map.new
|
52
40
|
@batch_size = batch_size
|
53
|
-
@wait_for = wait_for
|
41
|
+
@wait_for = TimeUnit::NANOSECONDS.convert(wait_for, TimeUnit::MILLISECONDS)
|
54
42
|
end
|
55
43
|
|
56
44
|
def close
|
@@ -58,12 +46,12 @@ module LogStash; module Util
|
|
58
46
|
end
|
59
47
|
|
60
48
|
def empty?
|
61
|
-
|
49
|
+
@queue.isEmpty
|
62
50
|
end
|
63
51
|
|
64
52
|
def set_batch_dimensions(batch_size, wait_for)
|
65
53
|
@batch_size = batch_size
|
66
|
-
@wait_for = wait_for
|
54
|
+
@wait_for = TimeUnit::NANOSECONDS.convert(wait_for, TimeUnit::MILLISECONDS)
|
67
55
|
end
|
68
56
|
|
69
57
|
def set_events_metric(metric)
|
@@ -89,185 +77,84 @@ module LogStash; module Util
|
|
89
77
|
end
|
90
78
|
|
91
79
|
def inflight_batches
|
92
|
-
@
|
93
|
-
begin
|
94
|
-
yield(@inflight_batches)
|
95
|
-
ensure
|
96
|
-
@mutex.unlock
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def current_inflight_batch
|
101
|
-
@inflight_batches.fetch(Thread.current, [])
|
80
|
+
yield(@inflight_batches)
|
102
81
|
end
|
103
82
|
|
104
83
|
# create a new empty batch
|
105
84
|
# @return [ReadBatch] a new empty read batch
|
106
85
|
def new_batch
|
107
|
-
ReadBatch.new(@queue,
|
86
|
+
ReadBatch.new(@queue, 0, 0)
|
108
87
|
end
|
109
88
|
|
110
89
|
def read_batch
|
111
|
-
batch =
|
112
|
-
@mutex.lock
|
113
|
-
begin
|
114
|
-
batch.read_next
|
115
|
-
ensure
|
116
|
-
@mutex.unlock
|
117
|
-
end
|
90
|
+
batch = ReadBatch.new(@queue, @batch_size, @wait_for)
|
118
91
|
start_metrics(batch)
|
119
92
|
batch
|
120
93
|
end
|
121
94
|
|
122
95
|
def start_metrics(batch)
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
set_current_thread_inflight_batch(batch)
|
127
|
-
start_clock
|
128
|
-
ensure
|
129
|
-
@mutex.unlock
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
def set_current_thread_inflight_batch(batch)
|
134
|
-
@inflight_batches[Thread.current] = batch
|
96
|
+
thread = Thread.current
|
97
|
+
@inflight_batches[thread] = batch
|
98
|
+
@inflight_clocks[thread] = java.lang.System.nano_time
|
135
99
|
end
|
136
100
|
|
137
101
|
def close_batch(batch)
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
stop_clock(batch)
|
143
|
-
ensure
|
144
|
-
@mutex.unlock
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
def start_clock
|
149
|
-
@inflight_clocks[Thread.current] = java.lang.System.nano_time
|
150
|
-
end
|
151
|
-
|
152
|
-
def stop_clock(batch)
|
153
|
-
unless @inflight_clocks[Thread.current].nil?
|
102
|
+
thread = Thread.current
|
103
|
+
@inflight_batches.delete(thread)
|
104
|
+
start_time = @inflight_clocks.get_and_set(thread, nil)
|
105
|
+
unless start_time.nil?
|
154
106
|
if batch.size > 0
|
155
107
|
# only stop (which also records) the metrics if the batch is non-empty.
|
156
108
|
# start_clock is now called at empty batch creation and an empty batch could
|
157
109
|
# stay empty all the way down to the close_batch call.
|
158
|
-
time_taken = (java.lang.System.nano_time -
|
110
|
+
time_taken = (java.lang.System.nano_time - start_time) / 1_000_000
|
159
111
|
@event_metric_time.increment(time_taken)
|
160
112
|
@pipeline_metric_time.increment(time_taken)
|
161
113
|
end
|
162
|
-
@inflight_clocks.delete(Thread.current)
|
163
114
|
end
|
164
115
|
end
|
165
116
|
|
166
|
-
def add_filtered_metrics(
|
167
|
-
@event_metric_filtered.increment(
|
168
|
-
@pipeline_metric_filtered.increment(
|
117
|
+
def add_filtered_metrics(filtered_size)
|
118
|
+
@event_metric_filtered.increment(filtered_size)
|
119
|
+
@pipeline_metric_filtered.increment(filtered_size)
|
169
120
|
end
|
170
121
|
|
171
|
-
def add_output_metrics(
|
172
|
-
@event_metric_out.increment(
|
173
|
-
@pipeline_metric_out.increment(
|
122
|
+
def add_output_metrics(filtered_size)
|
123
|
+
@event_metric_out.increment(filtered_size)
|
124
|
+
@pipeline_metric_out.increment(filtered_size)
|
174
125
|
end
|
175
126
|
end
|
176
127
|
|
177
128
|
class ReadBatch
|
178
129
|
def initialize(queue, size, wait)
|
179
|
-
@queue = queue
|
180
|
-
@size = size
|
181
|
-
@wait = wait
|
182
|
-
|
183
|
-
@originals = Hash.new
|
184
|
-
|
185
130
|
# TODO: disabled for https://github.com/elastic/logstash/issues/6055 - will have to properly refactor
|
186
131
|
# @cancelled = Hash.new
|
187
132
|
|
188
|
-
@
|
189
|
-
@iterating_temp = Hash.new
|
190
|
-
@iterating = false # Atomic Boolean maybe? Although batches are not shared across threads
|
191
|
-
@acked_batch = nil
|
192
|
-
end
|
193
|
-
|
194
|
-
def read_next
|
195
|
-
@size.times do |t|
|
196
|
-
event = @queue.poll(@wait)
|
197
|
-
return if event.nil? # queue poll timed out
|
198
|
-
|
199
|
-
@originals[event] = true
|
200
|
-
end
|
133
|
+
@originals = LsQueueUtils.drain(queue, size, wait)
|
201
134
|
end
|
202
135
|
|
203
136
|
def merge(event)
|
204
|
-
return if event.nil?
|
205
|
-
|
206
|
-
# @iterating_temp is merged after the iteration
|
207
|
-
if iterating?
|
208
|
-
@iterating_temp[event] = true
|
209
|
-
else
|
210
|
-
# the periodic flush could generate events outside of an each iteration
|
211
|
-
@generated[event] = true
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
def cancel(event)
|
216
|
-
# TODO: disabled for https://github.com/elastic/logstash/issues/6055 - will have to properly refactor
|
217
|
-
raise("cancel is unsupported")
|
218
|
-
# @cancelled[event] = true
|
137
|
+
return if event.nil?
|
138
|
+
@originals.add(event)
|
219
139
|
end
|
220
140
|
|
221
141
|
def to_a
|
222
142
|
events = []
|
223
|
-
each {|e| events << e}
|
143
|
+
@originals.each {|e| events << e unless e.cancelled?}
|
224
144
|
events
|
225
145
|
end
|
226
146
|
|
227
147
|
def each(&blk)
|
228
|
-
# take care not to cause @originals or @generated to change during iteration
|
229
|
-
@iterating = true
|
230
|
-
|
231
148
|
# below the checks for @cancelled.include?(e) have been replaced by e.cancelled?
|
232
149
|
# TODO: for https://github.com/elastic/logstash/issues/6055 = will have to properly refactor
|
233
|
-
@originals.each
|
234
|
-
blk.call(e) unless e.cancelled?
|
235
|
-
end
|
236
|
-
@generated.each do |e, _|
|
237
|
-
blk.call(e) unless e.cancelled?
|
238
|
-
end
|
239
|
-
@iterating = false
|
240
|
-
update_generated
|
241
|
-
end
|
242
|
-
|
243
|
-
def size
|
244
|
-
filtered_size
|
245
|
-
end
|
246
|
-
|
247
|
-
def starting_size
|
248
|
-
@originals.size
|
150
|
+
@originals.each {|e| blk.call(e) unless e.cancelled?}
|
249
151
|
end
|
250
152
|
|
251
153
|
def filtered_size
|
252
|
-
@originals.size
|
253
|
-
end
|
254
|
-
|
255
|
-
def cancelled_size
|
256
|
-
# TODO: disabled for https://github.com/elastic/logstash/issues/6055 = will have to properly refactor
|
257
|
-
raise("cancelled_size is unsupported ")
|
258
|
-
# @cancelled.size
|
259
|
-
end
|
260
|
-
|
261
|
-
private
|
262
|
-
|
263
|
-
def iterating?
|
264
|
-
@iterating
|
154
|
+
@originals.size
|
265
155
|
end
|
266
156
|
|
267
|
-
|
268
|
-
@generated.update(@iterating_temp)
|
269
|
-
@iterating_temp.clear
|
270
|
-
end
|
157
|
+
alias_method(:size, :filtered_size)
|
271
158
|
end
|
272
159
|
|
273
160
|
class WriteClient
|
@@ -275,40 +162,13 @@ module LogStash; module Util
|
|
275
162
|
@queue = queue
|
276
163
|
end
|
277
164
|
|
278
|
-
def get_new_batch
|
279
|
-
WriteBatch.new
|
280
|
-
end
|
281
|
-
|
282
165
|
def push(event)
|
283
|
-
@queue.
|
166
|
+
@queue.put(event)
|
284
167
|
end
|
285
168
|
alias_method(:<<, :push)
|
286
169
|
|
287
170
|
def push_batch(batch)
|
288
|
-
|
289
|
-
push(event)
|
290
|
-
end
|
291
|
-
end
|
292
|
-
end
|
293
|
-
|
294
|
-
class WriteBatch
|
295
|
-
def initialize
|
296
|
-
@events = []
|
297
|
-
end
|
298
|
-
|
299
|
-
def size
|
300
|
-
@events.size
|
301
|
-
end
|
302
|
-
|
303
|
-
def push(event)
|
304
|
-
@events.push(event)
|
305
|
-
end
|
306
|
-
alias_method(:<<, :push)
|
307
|
-
|
308
|
-
def each(&blk)
|
309
|
-
@events.each do |e|
|
310
|
-
blk.call(e)
|
311
|
-
end
|
171
|
+
LsQueueUtils.addAll(@queue, batch)
|
312
172
|
end
|
313
173
|
end
|
314
174
|
end
|
data/locales/en.yml
CHANGED
@@ -264,6 +264,8 @@ en:
|
|
264
264
|
http_port: Web API http port
|
265
265
|
pipeline-workers: |+
|
266
266
|
Sets the number of pipeline workers to run.
|
267
|
+
experimental-java-execution: |+
|
268
|
+
(Experimental) Use new Java execution engine.
|
267
269
|
pipeline-batch-size: |+
|
268
270
|
Size of batches the pipeline is to work in.
|
269
271
|
pipeline-batch-delay: |+
|
data/spec/conditionals_spec.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'spec_helper'
|
3
|
+
require 'support/pipeline/pipeline_helpers'
|
3
4
|
|
4
5
|
module ConditionalFanciness
|
6
|
+
include PipelineHelpers
|
5
7
|
def description
|
6
8
|
return self.metadata[:description]
|
7
9
|
end
|
@@ -76,21 +78,21 @@ describe "conditionals in filter" do
|
|
76
78
|
}
|
77
79
|
CONFIG
|
78
80
|
|
79
|
-
|
81
|
+
sample_one({"foo" => "bar"}) do
|
80
82
|
expect(subject.get("always")).to eq("awesome")
|
81
83
|
expect(subject.get("hello")).to eq("world")
|
82
84
|
expect(subject.get("fancy")).to be_nil
|
83
85
|
expect(subject.get("free")).to be_nil
|
84
86
|
end
|
85
87
|
|
86
|
-
|
88
|
+
sample_one({"notfoo" => "bar"}) do
|
87
89
|
expect(subject.get("always")).to eq("awesome")
|
88
90
|
expect(subject.get("hello")).to be_nil
|
89
91
|
expect(subject.get("fancy")).to be_nil
|
90
92
|
expect(subject.get("free")).to eq("hugs")
|
91
93
|
end
|
92
94
|
|
93
|
-
|
95
|
+
sample_one({"bar" => "baz"}) do
|
94
96
|
expect(subject.get("always")).to eq("awesome")
|
95
97
|
expect(subject.get("hello")).to be_nil
|
96
98
|
expect(subject.get("fancy")).to eq("pants")
|
@@ -114,28 +116,28 @@ describe "conditionals in filter" do
|
|
114
116
|
}
|
115
117
|
CONFIG
|
116
118
|
|
117
|
-
|
119
|
+
sample_one("foo" => "bar", "nest" => 124) do
|
118
120
|
expect(subject.get("always")).to be_nil
|
119
121
|
expect(subject.get("hello")).to be_nil
|
120
122
|
expect(subject.get("fancy")).to be_nil
|
121
123
|
expect(subject.get("free")).to be_nil
|
122
124
|
end
|
123
125
|
|
124
|
-
|
126
|
+
sample_one("foo" => "bar", "nest" => 123) do
|
125
127
|
expect(subject.get("always")).to eq("awesome")
|
126
128
|
expect(subject.get("hello")).to eq("world")
|
127
129
|
expect(subject.get("fancy")).to be_nil
|
128
130
|
expect(subject.get("free")).to be_nil
|
129
131
|
end
|
130
132
|
|
131
|
-
|
133
|
+
sample_one("notfoo" => "bar", "nest" => 123) do
|
132
134
|
expect(subject.get("always")).to eq("awesome")
|
133
135
|
expect(subject.get("hello")).to be_nil
|
134
136
|
expect(subject.get("fancy")).to be_nil
|
135
137
|
expect(subject.get("free")).to eq("hugs")
|
136
138
|
end
|
137
139
|
|
138
|
-
|
140
|
+
sample_one("bar" => "baz", "nest" => 123) do
|
139
141
|
expect(subject.get("always")).to eq("awesome")
|
140
142
|
expect(subject.get("hello")).to be_nil
|
141
143
|
expect(subject.get("fancy")).to eq("pants")
|
@@ -152,7 +154,7 @@ describe "conditionals in filter" do
|
|
152
154
|
}
|
153
155
|
CONFIG
|
154
156
|
|
155
|
-
|
157
|
+
sample_one("foo" => 123, "bar" => 123) do
|
156
158
|
expect(subject.get("tags") ).to include("woot")
|
157
159
|
end
|
158
160
|
end
|
@@ -181,7 +183,7 @@ describe "conditionals in filter" do
|
|
181
183
|
}
|
182
184
|
CONFIG
|
183
185
|
|
184
|
-
|
186
|
+
sample_one("foo" => "foo", "foobar" => "foobar", "greeting" => "hello world") do
|
185
187
|
expect(subject.get("tags")).to include("field in field")
|
186
188
|
expect(subject.get("tags")).to include("field in string")
|
187
189
|
expect(subject.get("tags")).to include("string in field")
|
@@ -203,7 +205,7 @@ describe "conditionals in filter" do
|
|
203
205
|
}
|
204
206
|
CONFIG
|
205
207
|
|
206
|
-
|
208
|
+
sample_one("foo" => "foo", "somelist" => [ "one", "two" ], "foobar" => "foobar", "greeting" => "hello world", "tags" => [ "fancypantsy" ]) do
|
207
209
|
# verify the original exists
|
208
210
|
expect(subject.get("tags")).to include("fancypantsy")
|
209
211
|
|
@@ -218,94 +220,156 @@ describe "conditionals in filter" do
|
|
218
220
|
|
219
221
|
describe "operators" do
|
220
222
|
conditional "[message] == 'sample'" do
|
221
|
-
|
222
|
-
|
223
|
+
sample_one("sample") { expect(subject.get("tags") ).to include("success") }
|
224
|
+
sample_one("different") { expect(subject.get("tags") ).to include("failure") }
|
225
|
+
end
|
226
|
+
|
227
|
+
conditional "'sample' == [message]" do
|
228
|
+
sample_one("sample") {expect(subject.get("tags")).to include("success")}
|
229
|
+
sample_one("different") {expect(subject.get("tags")).to include("failure")}
|
230
|
+
end
|
231
|
+
|
232
|
+
conditional "'value' == 'value'" do
|
233
|
+
sample_one("sample") {expect(subject.get("tags")).to include("success")}
|
234
|
+
end
|
235
|
+
|
236
|
+
conditional "'value' == 'other'" do
|
237
|
+
sample_one("sample") {expect(subject.get("tags")).to include("failure")}
|
223
238
|
end
|
224
239
|
|
225
240
|
conditional "[message] != 'sample'" do
|
226
|
-
|
227
|
-
|
241
|
+
sample_one("sample") { expect(subject.get("tags") ).to include("failure") }
|
242
|
+
sample_one("different") { expect(subject.get("tags") ).to include("success") }
|
228
243
|
end
|
229
244
|
|
230
245
|
conditional "[message] < 'sample'" do
|
231
|
-
|
232
|
-
|
246
|
+
sample_one("apple") { expect(subject.get("tags") ).to include("success") }
|
247
|
+
sample_one("zebra") { expect(subject.get("tags") ).to include("failure") }
|
233
248
|
end
|
234
249
|
|
235
250
|
conditional "[message] > 'sample'" do
|
236
|
-
|
237
|
-
|
251
|
+
sample_one("zebra") { expect(subject.get("tags") ).to include("success") }
|
252
|
+
sample_one("apple") { expect(subject.get("tags") ).to include("failure") }
|
238
253
|
end
|
239
254
|
|
240
255
|
conditional "[message] <= 'sample'" do
|
241
|
-
|
242
|
-
|
243
|
-
|
256
|
+
sample_one("apple") { expect(subject.get("tags") ).to include("success") }
|
257
|
+
sample_one("zebra") { expect(subject.get("tags") ).to include("failure") }
|
258
|
+
sample_one("sample") { expect(subject.get("tags") ).to include("success") }
|
244
259
|
end
|
245
260
|
|
246
261
|
conditional "[message] >= 'sample'" do
|
247
|
-
|
248
|
-
|
249
|
-
|
262
|
+
sample_one("zebra") { expect(subject.get("tags") ).to include("success") }
|
263
|
+
sample_one("sample") { expect(subject.get("tags") ).to include("success") }
|
264
|
+
sample_one("apple") { expect(subject.get("tags") ).to include("failure") }
|
265
|
+
end
|
266
|
+
|
267
|
+
conditional "[message] == 5" do
|
268
|
+
sample_one("message" => 5) {expect(subject.get("tags")).to include("success")}
|
269
|
+
sample_one("message" => 3) {expect(subject.get("tags")).to include("failure")}
|
270
|
+
end
|
271
|
+
|
272
|
+
conditional "5 == [message]" do
|
273
|
+
sample_one("message" => 5) {expect(subject.get("tags")).to include("success")}
|
274
|
+
sample_one("message" => 3) {expect(subject.get("tags")).to include("failure")}
|
275
|
+
end
|
276
|
+
|
277
|
+
conditional "7 == 7" do
|
278
|
+
sample_one("message" => 7) {expect(subject.get("tags")).to include("success")}
|
279
|
+
sample_one("message" => 3) {expect(subject.get("tags")).to include("success")}
|
280
|
+
end
|
281
|
+
|
282
|
+
conditional "5 == 7" do
|
283
|
+
sample_one("message" => 3) {expect(subject.get("tags")).to include("failure")}
|
284
|
+
sample_one("message" => 2) {expect(subject.get("tags")).to include("failure")}
|
285
|
+
end
|
286
|
+
|
287
|
+
conditional "[message] != 5" do
|
288
|
+
sample_one("message" => 5) {expect(subject.get("tags")).to include("failure")}
|
289
|
+
sample_one("message" => 3) {expect(subject.get("tags")).to include("success")}
|
290
|
+
end
|
291
|
+
|
292
|
+
conditional "[message] < 5" do
|
293
|
+
sample_one("message" => 3) {expect(subject.get("tags")).to include("success")}
|
294
|
+
sample_one("message" => 5) {expect(subject.get("tags")).to include("failure")}
|
295
|
+
sample_one("message" => 9) {expect(subject.get("tags")).to include("failure")}
|
296
|
+
end
|
297
|
+
|
298
|
+
conditional "[message] > 5" do
|
299
|
+
sample_one("message" => 9) {expect(subject.get("tags")).to include("success")}
|
300
|
+
sample_one("message" => 5) {expect(subject.get("tags")).to include("failure")}
|
301
|
+
sample_one("message" => 4) {expect(subject.get("tags")).to include("failure")}
|
302
|
+
end
|
303
|
+
|
304
|
+
conditional "[message] <= 5" do
|
305
|
+
sample_one("message" => 9) {expect(subject.get("tags")).to include("failure")}
|
306
|
+
sample_one("message" => 5) {expect(subject.get("tags")).to include("success")}
|
307
|
+
sample_one("message" => 3) {expect(subject.get("tags")).to include("success")}
|
308
|
+
end
|
309
|
+
|
310
|
+
conditional "[message] >= 5" do
|
311
|
+
sample_one("message" => 5) {expect(subject.get("tags")).to include("success")}
|
312
|
+
sample_one("message" => 7) {expect(subject.get("tags")).to include("success")}
|
313
|
+
sample_one("message" => 3) {expect(subject.get("tags")).to include("failure")}
|
250
314
|
end
|
251
315
|
|
252
316
|
conditional "[message] =~ /sample/" do
|
253
|
-
|
254
|
-
|
255
|
-
|
317
|
+
sample_one("apple") { expect(subject.get("tags") ).to include("failure") }
|
318
|
+
sample_one("sample") { expect(subject.get("tags") ).to include("success") }
|
319
|
+
sample_one("some sample") { expect(subject.get("tags") ).to include("success") }
|
256
320
|
end
|
257
321
|
|
258
322
|
conditional "[message] !~ /sample/" do
|
259
|
-
|
260
|
-
|
261
|
-
|
323
|
+
sample_one("apple") { expect(subject.get("tags")).to include("success") }
|
324
|
+
sample_one("sample") { expect(subject.get("tags")).to include("failure") }
|
325
|
+
sample_one("some sample") { expect(subject.get("tags")).to include("failure") }
|
262
326
|
end
|
263
327
|
|
264
328
|
end
|
265
329
|
|
266
330
|
describe "negated expressions" do
|
267
331
|
conditional "!([message] == 'sample')" do
|
268
|
-
|
269
|
-
|
332
|
+
sample_one("sample") { expect(subject.get("tags")).not_to include("success") }
|
333
|
+
sample_one("different") { expect(subject.get("tags")).not_to include("failure") }
|
270
334
|
end
|
271
335
|
|
272
336
|
conditional "!([message] != 'sample')" do
|
273
|
-
|
274
|
-
|
337
|
+
sample_one("sample") { expect(subject.get("tags")).not_to include("failure") }
|
338
|
+
sample_one("different") { expect(subject.get("tags")).not_to include("success") }
|
275
339
|
end
|
276
340
|
|
277
341
|
conditional "!([message] < 'sample')" do
|
278
|
-
|
279
|
-
|
342
|
+
sample_one("apple") { expect(subject.get("tags")).not_to include("success") }
|
343
|
+
sample_one("zebra") { expect(subject.get("tags")).not_to include("failure") }
|
280
344
|
end
|
281
345
|
|
282
346
|
conditional "!([message] > 'sample')" do
|
283
|
-
|
284
|
-
|
347
|
+
sample_one("zebra") { expect(subject.get("tags")).not_to include("success") }
|
348
|
+
sample_one("apple") { expect(subject.get("tags")).not_to include("failure") }
|
285
349
|
end
|
286
350
|
|
287
351
|
conditional "!([message] <= 'sample')" do
|
288
|
-
|
289
|
-
|
290
|
-
|
352
|
+
sample_one("apple") { expect(subject.get("tags")).not_to include("success") }
|
353
|
+
sample_one("zebra") { expect(subject.get("tags")).not_to include("failure") }
|
354
|
+
sample_one("sample") { expect(subject.get("tags")).not_to include("success")}
|
291
355
|
end
|
292
356
|
|
293
357
|
conditional "!([message] >= 'sample')" do
|
294
|
-
|
295
|
-
|
296
|
-
|
358
|
+
sample_one("zebra") { expect(subject.get("tags")).not_to include("success") }
|
359
|
+
sample_one("sample") { expect(subject.get("tags")).not_to include("success") }
|
360
|
+
sample_one("apple") { expect(subject.get("tags")).not_to include("failure") }
|
297
361
|
end
|
298
362
|
|
299
363
|
conditional "!([message] =~ /sample/)" do
|
300
|
-
|
301
|
-
|
302
|
-
|
364
|
+
sample_one("apple") { expect(subject.get("tags")).not_to include("failure") }
|
365
|
+
sample_one("sample") { expect(subject.get("tags")).not_to include("success") }
|
366
|
+
sample_one("some sample") { expect(subject.get("tags")).not_to include("success") }
|
303
367
|
end
|
304
368
|
|
305
369
|
conditional "!([message] !~ /sample/)" do
|
306
|
-
|
307
|
-
|
308
|
-
|
370
|
+
sample_one("apple") { expect(subject.get("tags")).not_to include("success") }
|
371
|
+
sample_one("sample") { expect(subject.get("tags")).not_to include("failure") }
|
372
|
+
sample_one("some sample") { expect(subject.get("tags")).not_to include("failure") }
|
309
373
|
end
|
310
374
|
|
311
375
|
end
|
@@ -313,66 +377,96 @@ describe "conditionals in filter" do
|
|
313
377
|
describe "value as an expression" do
|
314
378
|
# testing that a field has a value should be true.
|
315
379
|
conditional "[message]" do
|
316
|
-
|
317
|
-
|
318
|
-
|
380
|
+
sample_one("apple") { expect(subject.get("tags")).to include("success") }
|
381
|
+
sample_one("sample") { expect(subject.get("tags")).to include("success") }
|
382
|
+
sample_one("some sample") { expect(subject.get("tags")).to include("success") }
|
319
383
|
end
|
320
384
|
|
321
385
|
# testing that a missing field has a value should be false.
|
322
386
|
conditional "[missing]" do
|
323
|
-
|
324
|
-
|
325
|
-
|
387
|
+
sample_one("apple") { expect(subject.get("tags")).to include("failure") }
|
388
|
+
sample_one("sample") { expect(subject.get("tags")).to include("failure") }
|
389
|
+
sample_one("some sample") { expect(subject.get("tags")).to include("failure") }
|
326
390
|
end
|
327
391
|
end
|
328
392
|
|
329
393
|
describe "logic operators" do
|
330
394
|
describe "and" do
|
331
395
|
conditional "[message] and [message]" do
|
332
|
-
|
396
|
+
sample_one("whatever") { expect(subject.get("tags")).to include("success") }
|
333
397
|
end
|
334
398
|
conditional "[message] and ![message]" do
|
335
|
-
|
399
|
+
sample_one("whatever") { expect(subject.get("tags")).to include("failure") }
|
336
400
|
end
|
337
401
|
conditional "![message] and [message]" do
|
338
|
-
|
402
|
+
sample_one("whatever") { expect(subject.get("tags")).to include("failure") }
|
339
403
|
end
|
340
404
|
conditional "![message] and ![message]" do
|
341
|
-
|
405
|
+
sample_one("whatever") { expect(subject.get("tags")).to include("failure") }
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
describe "nand" do
|
410
|
+
conditional "[message] nand [message]" do
|
411
|
+
sample_one("whatever") { expect(subject.get("tags")).to include("failure") }
|
412
|
+
end
|
413
|
+
conditional "[message] nand ![message]" do
|
414
|
+
sample_one("whatever") { expect(subject.get("tags")).to include("success") }
|
415
|
+
end
|
416
|
+
conditional "![message] nand [message]" do
|
417
|
+
sample_one("whatever") { expect(subject.get("tags")).to include("success") }
|
418
|
+
end
|
419
|
+
conditional "![message] nand ![message]" do
|
420
|
+
sample_one("whatever") { expect(subject.get("tags")).to include("success") }
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
describe "xor" do
|
425
|
+
conditional "[message] xor [message]" do
|
426
|
+
sample_one("whatever") { expect(subject.get("tags")).to include("failure") }
|
427
|
+
end
|
428
|
+
conditional "[message] xor ![message]" do
|
429
|
+
sample_one("whatever") { expect(subject.get("tags")).to include("success") }
|
430
|
+
end
|
431
|
+
conditional "![message] xor [message]" do
|
432
|
+
sample_one("whatever") { expect(subject.get("tags")).to include("success") }
|
433
|
+
end
|
434
|
+
conditional "![message] xor ![message]" do
|
435
|
+
sample_one("whatever") { expect(subject.get("tags")).to include("failure") }
|
342
436
|
end
|
343
437
|
end
|
344
438
|
|
345
439
|
describe "or" do
|
346
440
|
conditional "[message] or [message]" do
|
347
|
-
|
441
|
+
sample_one("whatever") { expect(subject.get("tags")).to include("success") }
|
348
442
|
end
|
349
443
|
conditional "[message] or ![message]" do
|
350
|
-
|
444
|
+
sample_one("whatever") { expect(subject.get("tags")).to include("success") }
|
351
445
|
end
|
352
446
|
conditional "![message] or [message]" do
|
353
|
-
|
447
|
+
sample_one("whatever") { expect(subject.get("tags")).to include("success") }
|
354
448
|
end
|
355
449
|
conditional "![message] or ![message]" do
|
356
|
-
|
450
|
+
sample_one("whatever") { expect(subject.get("tags")).to include("failure") }
|
357
451
|
end
|
358
452
|
end
|
359
453
|
end
|
360
454
|
|
361
455
|
describe "field references" do
|
362
456
|
conditional "[field with space]" do
|
363
|
-
|
457
|
+
sample_one("field with space" => "hurray") do
|
364
458
|
expect(subject.get("tags")).to include("success")
|
365
459
|
end
|
366
460
|
end
|
367
461
|
|
368
462
|
conditional "[field with space] == 'hurray'" do
|
369
|
-
|
463
|
+
sample_one("field with space" => "hurray") do
|
370
464
|
expect(subject.get("tags")).to include("success")
|
371
465
|
end
|
372
466
|
end
|
373
467
|
|
374
468
|
conditional "[nested field][reference with][some spaces] == 'hurray'" do
|
375
|
-
|
469
|
+
sample_one({"nested field" => { "reference with" => { "some spaces" => "hurray" } } }) do
|
376
470
|
expect(subject.get("tags")).to include("success")
|
377
471
|
end
|
378
472
|
end
|
@@ -394,15 +488,16 @@ describe "conditionals in filter" do
|
|
394
488
|
}
|
395
489
|
CONFIG
|
396
490
|
|
397
|
-
|
491
|
+
sample_one({"type" => "original"}) do
|
398
492
|
expect(subject).to be_an(Array)
|
399
493
|
expect(subject.length).to eq(2)
|
494
|
+
subject.sort! {|a, b| a.get("type") <=> b.get("type")}
|
400
495
|
|
401
|
-
expect(subject[
|
402
|
-
expect(subject[
|
403
|
-
expect(subject[
|
496
|
+
expect(subject[1].get("type")).to eq("original")
|
497
|
+
expect(subject[1].get("cond1")).to eq("true")
|
498
|
+
expect(subject[1].get("cond2")).to eq(nil)
|
404
499
|
|
405
|
-
expect(subject[
|
500
|
+
expect(subject[0].get("type")).to eq("clone")
|
406
501
|
# expect(subject[1].get("cond1")).to eq(nil)
|
407
502
|
# expect(subject[1].get("cond2")).to eq("true")
|
408
503
|
end
|
@@ -424,18 +519,78 @@ describe "conditionals in filter" do
|
|
424
519
|
}
|
425
520
|
CONFIG
|
426
521
|
|
427
|
-
|
428
|
-
|
429
|
-
|
522
|
+
sample_one({"type" => "original"}) do
|
523
|
+
expect(subject.length).to eq(3)
|
524
|
+
subject.sort! {|a, b| a.get("type") <=> b.get("type")}
|
525
|
+
|
526
|
+
expect(subject[0].get("type")).to eq("clone1")
|
527
|
+
expect(subject[0].get("cond1")).to eq("true")
|
430
528
|
expect(subject[0].get("cond2")).to eq(nil)
|
431
529
|
|
432
|
-
expect(subject[1].get("type")).to eq("
|
433
|
-
expect(subject[1].get("cond1")).to eq(
|
434
|
-
expect(subject[1].get("cond2")).to eq(
|
530
|
+
expect(subject[1].get("type")).to eq("clone2")
|
531
|
+
expect(subject[1].get("cond1")).to eq(nil)
|
532
|
+
expect(subject[1].get("cond2")).to eq("true")
|
435
533
|
|
436
|
-
expect(subject[2].get("type")).to eq("
|
534
|
+
expect(subject[2].get("type")).to eq("original")
|
437
535
|
expect(subject[2].get("cond1")).to eq(nil)
|
438
|
-
expect(subject[2].get("cond2")).to eq(
|
536
|
+
expect(subject[2].get("cond2")).to eq(nil)
|
537
|
+
end
|
538
|
+
end
|
539
|
+
|
540
|
+
describe "complex case" do
|
541
|
+
config <<-CONFIG
|
542
|
+
filter {
|
543
|
+
if ("foo" in [tags]) {
|
544
|
+
mutate { id => addbar add_tag => bar }
|
545
|
+
|
546
|
+
if ("bar" in [tags]) {
|
547
|
+
mutate { id => addbaz add_tag => baz }
|
548
|
+
}
|
549
|
+
|
550
|
+
if ("baz" in [tags]) {
|
551
|
+
mutate { id => addbot add_tag => bot }
|
552
|
+
|
553
|
+
if ("bot" in [tags]) {
|
554
|
+
mutate { id => addbonk add_tag => bonk }
|
555
|
+
}
|
556
|
+
}
|
557
|
+
}
|
558
|
+
|
559
|
+
if ("bot" in [tags]) {
|
560
|
+
mutate { id => addwat add_tag => wat }
|
561
|
+
}
|
562
|
+
|
563
|
+
mutate { id => addprev add_tag => prev }
|
564
|
+
|
565
|
+
mutate { id => addfinal add_tag => final }
|
566
|
+
|
567
|
+
}
|
568
|
+
CONFIG
|
569
|
+
|
570
|
+
sample_one("tags" => ["bot"]) do
|
571
|
+
tags = subject.get("tags")
|
572
|
+
expect(tags[0]).to eq("bot")
|
573
|
+
expect(tags[1]).to eq("wat")
|
574
|
+
expect(tags[2]).to eq("prev")
|
575
|
+
expect(tags[3]).to eq("final")
|
576
|
+
end
|
577
|
+
|
578
|
+
sample_one("tags" => ["foo"]) do
|
579
|
+
tags = subject.get("tags")
|
580
|
+
expect(tags[0]).to eq("foo")
|
581
|
+
expect(tags[1]).to eq("bar")
|
582
|
+
expect(tags[2]).to eq("baz")
|
583
|
+
expect(tags[3]).to eq("bot")
|
584
|
+
expect(tags[4]).to eq("bonk")
|
585
|
+
expect(tags[5]).to eq("wat")
|
586
|
+
expect(tags[6]).to eq("prev")
|
587
|
+
expect(tags[7]).to eq("final")
|
588
|
+
end
|
589
|
+
|
590
|
+
sample_one("type" => "original") do
|
591
|
+
tags = subject.get("tags")
|
592
|
+
expect(tags[0]).to eq("prev")
|
593
|
+
expect(tags[1]).to eq("final")
|
439
594
|
end
|
440
595
|
end
|
441
596
|
end
|