logstash-core 1.5.0.beta2-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.
Potentially problematic release.
This version of logstash-core might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/lib/logstash-event.rb +2 -0
- data/lib/logstash.rb +4 -0
- data/lib/logstash/JRUBY-PR1448.rb +32 -0
- data/lib/logstash/agent.rb +355 -0
- data/lib/logstash/bundler.rb +124 -0
- data/lib/logstash/codecs/base.rb +50 -0
- data/lib/logstash/config/config_ast.rb +508 -0
- data/lib/logstash/config/file.rb +39 -0
- data/lib/logstash/config/grammar.rb +3503 -0
- data/lib/logstash/config/mixin.rb +495 -0
- data/lib/logstash/config/registry.rb +13 -0
- data/lib/logstash/environment.rb +168 -0
- data/lib/logstash/errors.rb +12 -0
- data/lib/logstash/event.rb +310 -0
- data/lib/logstash/filters/base.rb +239 -0
- data/lib/logstash/gemfile.rb +175 -0
- data/lib/logstash/inputs/base.rb +137 -0
- data/lib/logstash/inputs/threadable.rb +18 -0
- data/lib/logstash/java_integration.rb +41 -0
- data/lib/logstash/json.rb +53 -0
- data/lib/logstash/logging.rb +91 -0
- data/lib/logstash/multiqueue.rb +53 -0
- data/lib/logstash/namespace.rb +17 -0
- data/lib/logstash/outputs/base.rb +124 -0
- data/lib/logstash/patches.rb +3 -0
- data/lib/logstash/patches/bugfix_jruby_2558.rb +50 -0
- data/lib/logstash/patches/cabin.rb +34 -0
- data/lib/logstash/patches/profile_require_calls.rb +47 -0
- data/lib/logstash/pipeline.rb +305 -0
- data/lib/logstash/plugin.rb +177 -0
- data/lib/logstash/pluginmanager.rb +17 -0
- data/lib/logstash/pluginmanager/install.rb +112 -0
- data/lib/logstash/pluginmanager/list.rb +38 -0
- data/lib/logstash/pluginmanager/main.rb +22 -0
- data/lib/logstash/pluginmanager/maven_tools_patch.rb +12 -0
- data/lib/logstash/pluginmanager/uninstall.rb +49 -0
- data/lib/logstash/pluginmanager/update.rb +50 -0
- data/lib/logstash/pluginmanager/util.rb +88 -0
- data/lib/logstash/program.rb +15 -0
- data/lib/logstash/runner.rb +167 -0
- data/lib/logstash/sized_queue.rb +8 -0
- data/lib/logstash/threadwatchdog.rb +37 -0
- data/lib/logstash/timestamp.rb +97 -0
- data/lib/logstash/util.rb +152 -0
- data/lib/logstash/util/accessors.rb +88 -0
- data/lib/logstash/util/buftok.rb +139 -0
- data/lib/logstash/util/charset.rb +35 -0
- data/lib/logstash/util/fieldreference.rb +68 -0
- data/lib/logstash/util/filetools.rb +185 -0
- data/lib/logstash/util/password.rb +25 -0
- data/lib/logstash/util/plugin_version.rb +43 -0
- data/lib/logstash/util/prctl.rb +11 -0
- data/lib/logstash/util/require-helper.rb +18 -0
- data/lib/logstash/util/retryable.rb +39 -0
- data/lib/logstash/util/socket_peer.rb +7 -0
- data/lib/logstash/version.rb +6 -0
- data/locales/en.yml +176 -0
- metadata +427 -0
@@ -0,0 +1,50 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/namespace"
|
3
|
+
require "logstash/event"
|
4
|
+
require "logstash/plugin"
|
5
|
+
require "logstash/logging"
|
6
|
+
|
7
|
+
# This is the base class for logstash codecs.
|
8
|
+
module LogStash::Codecs; class Base < LogStash::Plugin
|
9
|
+
include LogStash::Config::Mixin
|
10
|
+
config_name "codec"
|
11
|
+
|
12
|
+
def initialize(params={})
|
13
|
+
super
|
14
|
+
config_init(params)
|
15
|
+
register if respond_to?(:register)
|
16
|
+
end
|
17
|
+
|
18
|
+
public
|
19
|
+
def decode(data)
|
20
|
+
raise "#{self.class}#decode must be overidden"
|
21
|
+
end # def decode
|
22
|
+
|
23
|
+
alias_method :<<, :decode
|
24
|
+
|
25
|
+
public
|
26
|
+
def encode(event)
|
27
|
+
raise "#{self.class}#encode must be overidden"
|
28
|
+
end # def encode
|
29
|
+
|
30
|
+
public
|
31
|
+
def teardown; end;
|
32
|
+
|
33
|
+
# @param block [Proc(event, data)] the callback proc passing the original event and the encoded event
|
34
|
+
public
|
35
|
+
def on_event(&block)
|
36
|
+
@on_event = block
|
37
|
+
end
|
38
|
+
|
39
|
+
public
|
40
|
+
def flush(&block)
|
41
|
+
# does nothing by default.
|
42
|
+
# if your codec needs a flush method (like you are spooling things)
|
43
|
+
# you must implement this.
|
44
|
+
end
|
45
|
+
|
46
|
+
public
|
47
|
+
def clone
|
48
|
+
return self.class.new(params)
|
49
|
+
end
|
50
|
+
end; end # class LogStash::Codecs::Base
|
@@ -0,0 +1,508 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'logstash/errors'
|
3
|
+
require "treetop"
|
4
|
+
class Treetop::Runtime::SyntaxNode
|
5
|
+
def compile
|
6
|
+
return "" if elements.nil?
|
7
|
+
return elements.collect(&:compile).reject(&:empty?).join("")
|
8
|
+
end
|
9
|
+
|
10
|
+
# Traverse the syntax tree recursively.
|
11
|
+
# The order should respect the order of the configuration file as it is read
|
12
|
+
# and written by humans (and the order in which it is parsed).
|
13
|
+
def recurse(e, depth=0, &block)
|
14
|
+
r = block.call(e, depth)
|
15
|
+
e.elements.each { |e| recurse(e, depth + 1, &block) } if r && e.elements
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def recursive_inject(results=[], &block)
|
20
|
+
if !elements.nil?
|
21
|
+
elements.each do |element|
|
22
|
+
if block.call(element)
|
23
|
+
results << element
|
24
|
+
else
|
25
|
+
element.recursive_inject(results, &block)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
return results
|
30
|
+
end
|
31
|
+
|
32
|
+
# When Treetop parses the configuration file
|
33
|
+
# it will generate a tree, the generated tree will contain
|
34
|
+
# a few `Empty` nodes to represent the actual space/tab or newline in the file.
|
35
|
+
# Some of theses node will point to our concrete class.
|
36
|
+
# To fetch a specific types of object we need to follow each branch
|
37
|
+
# and ignore the empty nodes.
|
38
|
+
def recursive_select(klass)
|
39
|
+
return recursive_inject { |e| e.is_a?(klass) }
|
40
|
+
end
|
41
|
+
|
42
|
+
def recursive_inject_parent(results=[], &block)
|
43
|
+
if !parent.nil?
|
44
|
+
if block.call(parent)
|
45
|
+
results << parent
|
46
|
+
else
|
47
|
+
parent.recursive_inject_parent(results, &block)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
return results
|
51
|
+
end
|
52
|
+
|
53
|
+
def recursive_select_parent(results=[], klass)
|
54
|
+
return recursive_inject_parent(results) { |e| e.is_a?(klass) }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
module LogStash; module Config; module AST
|
59
|
+
class Node < Treetop::Runtime::SyntaxNode; end
|
60
|
+
|
61
|
+
class Config < Node
|
62
|
+
def compile
|
63
|
+
code = []
|
64
|
+
|
65
|
+
code << <<-CODE
|
66
|
+
@inputs = []
|
67
|
+
@filters = []
|
68
|
+
@outputs = []
|
69
|
+
@periodic_flushers = []
|
70
|
+
@shutdown_flushers = []
|
71
|
+
CODE
|
72
|
+
|
73
|
+
sections = recursive_select(LogStash::Config::AST::PluginSection)
|
74
|
+
sections.each do |s|
|
75
|
+
code << s.compile_initializer
|
76
|
+
end
|
77
|
+
|
78
|
+
# start inputs
|
79
|
+
definitions = []
|
80
|
+
|
81
|
+
["filter", "output"].each do |type|
|
82
|
+
# defines @filter_func and @output_func
|
83
|
+
|
84
|
+
definitions << "@#{type}_func = lambda do |event, &block|"
|
85
|
+
definitions << " events = [event]"
|
86
|
+
definitions << " @logger.debug? && @logger.debug(\"#{type} received\", :event => event.to_hash)"
|
87
|
+
sections.select { |s| s.plugin_type.text_value == type }.each do |s|
|
88
|
+
definitions << s.compile.split("\n", -1).map { |e| " #{e}" }
|
89
|
+
end
|
90
|
+
|
91
|
+
if type == "filter"
|
92
|
+
definitions << " events.flatten.each{|e| block.call(e) }"
|
93
|
+
end
|
94
|
+
definitions << "end"
|
95
|
+
end
|
96
|
+
|
97
|
+
code += definitions.join("\n").split("\n", -1).collect { |l| " #{l}" }
|
98
|
+
return code.join("\n")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class Comment < Node; end
|
103
|
+
class Whitespace < Node; end
|
104
|
+
class PluginSection < Node
|
105
|
+
# Global plugin numbering for the janky instance variable naming we use
|
106
|
+
# like @filter_<name>_1
|
107
|
+
@@i = 0
|
108
|
+
|
109
|
+
# Generate ruby code to initialize all the plugins.
|
110
|
+
def compile_initializer
|
111
|
+
generate_variables
|
112
|
+
code = []
|
113
|
+
@variables.each do |plugin, name|
|
114
|
+
|
115
|
+
|
116
|
+
code << <<-CODE
|
117
|
+
#{name} = #{plugin.compile_initializer}
|
118
|
+
@#{plugin.plugin_type}s << #{name}
|
119
|
+
CODE
|
120
|
+
|
121
|
+
# The flush method for this filter.
|
122
|
+
if plugin.plugin_type == "filter"
|
123
|
+
|
124
|
+
code << <<-CODE
|
125
|
+
#{name}_flush = lambda do |options, &block|
|
126
|
+
@logger.debug? && @logger.debug(\"Flushing\", :plugin => #{name})
|
127
|
+
|
128
|
+
flushed_events = #{name}.flush(options)
|
129
|
+
|
130
|
+
return if flushed_events.nil? || flushed_events.empty?
|
131
|
+
|
132
|
+
flushed_events.each do |event|
|
133
|
+
@logger.debug? && @logger.debug(\"Flushing\", :plugin => #{name}, :event => event)
|
134
|
+
|
135
|
+
events = [event]
|
136
|
+
#{plugin.compile_starting_here.gsub(/^/, " ")}
|
137
|
+
|
138
|
+
block.call(event)
|
139
|
+
events.flatten.each{|e| block.call(e) if e != event}
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
if #{name}.respond_to?(:flush)
|
145
|
+
@periodic_flushers << #{name}_flush if #{name}.periodic_flush
|
146
|
+
@shutdown_flushers << #{name}_flush
|
147
|
+
end
|
148
|
+
CODE
|
149
|
+
|
150
|
+
end
|
151
|
+
end
|
152
|
+
return code.join("\n")
|
153
|
+
end
|
154
|
+
|
155
|
+
def variable(object)
|
156
|
+
generate_variables
|
157
|
+
return @variables[object]
|
158
|
+
end
|
159
|
+
|
160
|
+
def generate_variables
|
161
|
+
return if !@variables.nil?
|
162
|
+
@variables = {}
|
163
|
+
plugins = recursive_select(Plugin)
|
164
|
+
|
165
|
+
plugins.each do |plugin|
|
166
|
+
# Unique number for every plugin.
|
167
|
+
@@i += 1
|
168
|
+
# store things as ivars, like @filter_grok_3
|
169
|
+
var = "@#{plugin.plugin_type}_#{plugin.plugin_name}_#{@@i}"
|
170
|
+
@variables[plugin] = var
|
171
|
+
end
|
172
|
+
return @variables
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
class Plugins < Node; end
|
178
|
+
class Plugin < Node
|
179
|
+
def plugin_type
|
180
|
+
if recursive_select_parent(Plugin).any?
|
181
|
+
return "codec"
|
182
|
+
else
|
183
|
+
return recursive_select_parent(PluginSection).first.plugin_type.text_value
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def plugin_name
|
188
|
+
return name.text_value
|
189
|
+
end
|
190
|
+
|
191
|
+
def variable_name
|
192
|
+
return recursive_select_parent(PluginSection).first.variable(self)
|
193
|
+
end
|
194
|
+
|
195
|
+
def compile_initializer
|
196
|
+
# If any parent is a Plugin, this must be a codec.
|
197
|
+
|
198
|
+
if attributes.elements.nil?
|
199
|
+
return "plugin(#{plugin_type.inspect}, #{plugin_name.inspect})" << (plugin_type == "codec" ? "" : "\n")
|
200
|
+
else
|
201
|
+
settings = attributes.recursive_select(Attribute).collect(&:compile).reject(&:empty?)
|
202
|
+
|
203
|
+
attributes_code = "LogStash::Util.hash_merge_many(#{settings.map { |c| "{ #{c} }" }.join(", ")})"
|
204
|
+
return "plugin(#{plugin_type.inspect}, #{plugin_name.inspect}, #{attributes_code})" << (plugin_type == "codec" ? "" : "\n")
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def compile
|
209
|
+
case plugin_type
|
210
|
+
when "input"
|
211
|
+
return "start_input(#{variable_name})"
|
212
|
+
when "filter"
|
213
|
+
return <<-CODE
|
214
|
+
events = events.flat_map do |event|
|
215
|
+
next [] if event.cancelled?
|
216
|
+
|
217
|
+
new_events = []
|
218
|
+
#{variable_name}.filter(event){|new_event| new_events << new_event}
|
219
|
+
event.cancelled? ? new_events : new_events.unshift(event)
|
220
|
+
end
|
221
|
+
CODE
|
222
|
+
when "output"
|
223
|
+
return "#{variable_name}.handle(event)\n"
|
224
|
+
when "codec"
|
225
|
+
settings = attributes.recursive_select(Attribute).collect(&:compile).reject(&:empty?)
|
226
|
+
attributes_code = "LogStash::Util.hash_merge_many(#{settings.map { |c| "{ #{c} }" }.join(", ")})"
|
227
|
+
return "plugin(#{plugin_type.inspect}, #{plugin_name.inspect}, #{attributes_code})"
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def compile_starting_here
|
232
|
+
return unless plugin_type == "filter" # only filter supported.
|
233
|
+
|
234
|
+
expressions = [
|
235
|
+
LogStash::Config::AST::Branch,
|
236
|
+
LogStash::Config::AST::Plugin
|
237
|
+
]
|
238
|
+
code = []
|
239
|
+
|
240
|
+
# Find the branch we are in, if any (the 'if' statement, etc)
|
241
|
+
self_branch = recursive_select_parent(LogStash::Config::AST::BranchEntry).first
|
242
|
+
|
243
|
+
# Find any siblings to our branch so we can skip them later. For example,
|
244
|
+
# if we are in an 'else if' we want to skip any sibling 'else if' or
|
245
|
+
# 'else' blocks.
|
246
|
+
branch_siblings = []
|
247
|
+
if self_branch
|
248
|
+
branch_siblings = recursive_select_parent(LogStash::Config::AST::Branch).first \
|
249
|
+
.recursive_select(LogStash::Config::AST::BranchEntry) \
|
250
|
+
.reject { |b| b == self_branch }
|
251
|
+
end
|
252
|
+
|
253
|
+
#ast = recursive_select_parent(LogStash::Config::AST::PluginSection).first
|
254
|
+
ast = recursive_select_parent(LogStash::Config::AST::Config).first
|
255
|
+
|
256
|
+
found = false
|
257
|
+
recurse(ast) do |element, depth|
|
258
|
+
next false if element.is_a?(LogStash::Config::AST::PluginSection) && element.plugin_type.text_value != "filter"
|
259
|
+
if element == self
|
260
|
+
found = true
|
261
|
+
next false
|
262
|
+
end
|
263
|
+
if found && expressions.include?(element.class)
|
264
|
+
code << element.compile
|
265
|
+
next false
|
266
|
+
end
|
267
|
+
next false if branch_siblings.include?(element)
|
268
|
+
next true
|
269
|
+
end
|
270
|
+
|
271
|
+
return code.collect { |l| "#{l}\n" }.join("")
|
272
|
+
end # def compile_starting_here
|
273
|
+
end
|
274
|
+
|
275
|
+
class Name < Node
|
276
|
+
def compile
|
277
|
+
return text_value.inspect
|
278
|
+
end
|
279
|
+
end
|
280
|
+
class Attribute < Node
|
281
|
+
def compile
|
282
|
+
return %Q(#{name.compile} => #{value.compile})
|
283
|
+
end
|
284
|
+
end
|
285
|
+
class RValue < Node; end
|
286
|
+
class Value < RValue; end
|
287
|
+
|
288
|
+
module Unicode
|
289
|
+
def self.wrap(text)
|
290
|
+
return "(" + text.inspect + ".force_encoding(Encoding::UTF_8)" + ")"
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
class Bareword < Value
|
295
|
+
def compile
|
296
|
+
return Unicode.wrap(text_value)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
class String < Value
|
300
|
+
def compile
|
301
|
+
return Unicode.wrap(text_value[1...-1])
|
302
|
+
end
|
303
|
+
end
|
304
|
+
class RegExp < Value
|
305
|
+
def compile
|
306
|
+
return "Regexp.new(" + Unicode.wrap(text_value[1...-1]) + ")"
|
307
|
+
end
|
308
|
+
end
|
309
|
+
class Number < Value
|
310
|
+
def compile
|
311
|
+
return text_value
|
312
|
+
end
|
313
|
+
end
|
314
|
+
class Array < Value
|
315
|
+
def compile
|
316
|
+
return "[" << recursive_select(Value).collect(&:compile).reject(&:empty?).join(", ") << "]"
|
317
|
+
end
|
318
|
+
end
|
319
|
+
class Hash < Value
|
320
|
+
def validate!
|
321
|
+
duplicate_values = find_duplicate_keys
|
322
|
+
|
323
|
+
if duplicate_values.size > 0
|
324
|
+
raise ConfigurationError.new(
|
325
|
+
I18n.t("logstash.agent.configuration.invalid_plugin_settings_duplicate_keys",
|
326
|
+
:keys => duplicate_values.join(', '),
|
327
|
+
:line => input.line_of(interval.first),
|
328
|
+
:column => input.column_of(interval.first),
|
329
|
+
:byte => interval.first + 1,
|
330
|
+
:after => input[0..interval.first]
|
331
|
+
)
|
332
|
+
)
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
def find_duplicate_keys
|
337
|
+
values = recursive_select(HashEntry).collect { |hash_entry| hash_entry.name.text_value }
|
338
|
+
values.find_all { |v| values.count(v) > 1 }.uniq
|
339
|
+
end
|
340
|
+
|
341
|
+
def compile
|
342
|
+
validate!
|
343
|
+
return "{" << recursive_select(HashEntry).collect(&:compile).reject(&:empty?).join(", ") << "}"
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
class HashEntries < Node
|
348
|
+
end
|
349
|
+
|
350
|
+
class HashEntry < Node
|
351
|
+
def compile
|
352
|
+
return %Q(#{name.compile} => #{value.compile})
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
class BranchOrPlugin < Node; end
|
357
|
+
|
358
|
+
class Branch < Node
|
359
|
+
def compile
|
360
|
+
|
361
|
+
# this construct is non obvious. we need to loop through each event and apply the conditional.
|
362
|
+
# each branch of a conditional will contain a construct (a filter for example) that also loops through
|
363
|
+
# the events variable so we have to initialize it to [event] for the branch code.
|
364
|
+
# at the end, events is returned to handle the case where no branch match and no branch code is executed
|
365
|
+
# so we must make sure to return the current event.
|
366
|
+
|
367
|
+
return <<-CODE
|
368
|
+
events = events.flat_map do |event|
|
369
|
+
events = [event]
|
370
|
+
#{super}
|
371
|
+
end
|
372
|
+
events
|
373
|
+
end
|
374
|
+
CODE
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
class BranchEntry < Node; end
|
379
|
+
class If < BranchEntry
|
380
|
+
def compile
|
381
|
+
children = recursive_inject { |e| e.is_a?(Branch) || e.is_a?(Plugin) }
|
382
|
+
return "if #{condition.compile} # if #{condition.text_value}\n" \
|
383
|
+
<< children.collect(&:compile).map { |s| s.split("\n", -1).map { |l| " " + l }.join("\n") }.join("") << "\n"
|
384
|
+
end
|
385
|
+
end
|
386
|
+
class Elsif < BranchEntry
|
387
|
+
def compile
|
388
|
+
children = recursive_inject { |e| e.is_a?(Branch) || e.is_a?(Plugin) }
|
389
|
+
return "elsif #{condition.compile} # else if #{condition.text_value}\n" \
|
390
|
+
<< children.collect(&:compile).map { |s| s.split("\n", -1).map { |l| " " + l }.join("\n") }.join("") << "\n"
|
391
|
+
end
|
392
|
+
end
|
393
|
+
class Else < BranchEntry
|
394
|
+
def compile
|
395
|
+
children = recursive_inject { |e| e.is_a?(Branch) || e.is_a?(Plugin) }
|
396
|
+
return "else\n" \
|
397
|
+
<< children.collect(&:compile).map { |s| s.split("\n", -1).map { |l| " " + l }.join("\n") }.join("") << "\n"
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
class Condition < Node
|
402
|
+
def compile
|
403
|
+
return "(#{super})"
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
module Expression
|
408
|
+
def compile
|
409
|
+
return "(#{super})"
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
module NegativeExpression
|
414
|
+
def compile
|
415
|
+
return "!(#{super})"
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
module ComparisonExpression; end
|
420
|
+
|
421
|
+
module InExpression
|
422
|
+
def compile
|
423
|
+
item, list = recursive_select(LogStash::Config::AST::RValue)
|
424
|
+
return "(x = #{list.compile}; x.respond_to?(:include?) && x.include?(#{item.compile}))"
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
module NotInExpression
|
429
|
+
def compile
|
430
|
+
item, list = recursive_select(LogStash::Config::AST::RValue)
|
431
|
+
return "(x = #{list.compile}; !x.respond_to?(:include?) || !x.include?(#{item.compile}))"
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
class MethodCall < Node
|
436
|
+
def compile
|
437
|
+
arguments = recursive_inject { |e| [String, Number, Selector, Array, MethodCall].any? { |c| e.is_a?(c) } }
|
438
|
+
return "#{method.text_value}(" << arguments.collect(&:compile).join(", ") << ")"
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
class RegexpExpression < Node
|
443
|
+
def compile
|
444
|
+
operator = recursive_select(LogStash::Config::AST::RegExpOperator).first.text_value
|
445
|
+
item, regexp = recursive_select(LogStash::Config::AST::RValue)
|
446
|
+
# Compile strings to regexp's
|
447
|
+
if regexp.is_a?(LogStash::Config::AST::String)
|
448
|
+
regexp = "/#{regexp.text_value[1..-2]}/"
|
449
|
+
else
|
450
|
+
regexp = regexp.compile
|
451
|
+
end
|
452
|
+
return "(#{item.compile} #{operator} #{regexp})"
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
456
|
+
module ComparisonOperator
|
457
|
+
def compile
|
458
|
+
return " #{text_value} "
|
459
|
+
end
|
460
|
+
end
|
461
|
+
module RegExpOperator
|
462
|
+
def compile
|
463
|
+
return " #{text_value} "
|
464
|
+
end
|
465
|
+
end
|
466
|
+
module BooleanOperator
|
467
|
+
def compile
|
468
|
+
return " #{text_value} "
|
469
|
+
end
|
470
|
+
end
|
471
|
+
class Selector < RValue
|
472
|
+
def compile
|
473
|
+
return "event[#{text_value.inspect}]"
|
474
|
+
end
|
475
|
+
end
|
476
|
+
class SelectorElement < Node; end
|
477
|
+
end; end; end
|
478
|
+
|
479
|
+
|
480
|
+
# Monkeypatch Treetop::Runtime::SyntaxNode's inspect method to skip
|
481
|
+
# any Whitespace or SyntaxNodes with no children.
|
482
|
+
class Treetop::Runtime::SyntaxNode
|
483
|
+
def _inspect(indent="")
|
484
|
+
em = extension_modules
|
485
|
+
interesting_methods = methods-[em.last ? em.last.methods : nil]-self.class.instance_methods
|
486
|
+
im = interesting_methods.size > 0 ? " (#{interesting_methods.join(",")})" : ""
|
487
|
+
tv = text_value
|
488
|
+
tv = "...#{tv[-20..-1]}" if tv.size > 20
|
489
|
+
|
490
|
+
indent +
|
491
|
+
self.class.to_s.sub(/.*:/,'') +
|
492
|
+
em.map{|m| "+"+m.to_s.sub(/.*:/,'')}*"" +
|
493
|
+
" offset=#{interval.first}" +
|
494
|
+
", #{tv.inspect}" +
|
495
|
+
im +
|
496
|
+
(elements && elements.size > 0 ?
|
497
|
+
":" +
|
498
|
+
(elements.select { |e| !e.is_a?(LogStash::Config::AST::Whitespace) && e.elements && e.elements.size > 0 }||[]).map{|e|
|
499
|
+
begin
|
500
|
+
"\n"+e.inspect(indent+" ")
|
501
|
+
rescue # Defend against inspect not taking a parameter
|
502
|
+
"\n"+indent+" "+e.inspect
|
503
|
+
end
|
504
|
+
}.join("") :
|
505
|
+
""
|
506
|
+
)
|
507
|
+
end
|
508
|
+
end
|