logstash-core 6.0.1-java → 6.1.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/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
|