logstash-core 5.6.16-java → 6.0.0.alpha1-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 +4 -7
- data/lib/logstash-core/logstash-core.jar +0 -0
- data/lib/logstash-core/version.rb +4 -8
- data/lib/logstash-core_jars.rb +12 -26
- data/lib/logstash/agent.rb +261 -246
- data/lib/logstash/api/commands/default_metadata.rb +1 -1
- data/lib/logstash/api/commands/hot_threads_reporter.rb +5 -11
- data/lib/logstash/api/commands/node.rb +3 -2
- data/lib/logstash/api/commands/stats.rb +3 -2
- data/lib/logstash/bootstrap_check/bad_java.rb +16 -0
- data/lib/logstash/bootstrap_check/bad_ruby.rb +12 -0
- data/lib/logstash/bootstrap_check/default_config.rb +17 -0
- data/lib/logstash/compiler.rb +38 -0
- data/lib/logstash/compiler/lscl.rb +566 -0
- data/lib/logstash/compiler/lscl/lscl_grammar.rb +3503 -0
- data/lib/logstash/compiler/treetop_monkeypatches.rb +92 -0
- data/lib/logstash/config/config_ast.rb +4 -82
- data/lib/logstash/config/mixin.rb +73 -41
- data/lib/logstash/config/pipeline_config.rb +48 -0
- data/lib/logstash/config/source/base.rb +16 -0
- data/lib/logstash/config/source/local.rb +215 -0
- data/lib/logstash/config/source_loader.rb +125 -0
- data/lib/logstash/converge_result.rb +103 -0
- data/lib/logstash/environment.rb +6 -19
- data/lib/logstash/errors.rb +2 -0
- data/lib/logstash/execution_context.rb +4 -7
- data/lib/logstash/filter_delegator.rb +6 -9
- data/lib/logstash/inputs/base.rb +0 -2
- data/lib/logstash/instrument/collector.rb +5 -7
- data/lib/logstash/instrument/metric_store.rb +12 -12
- data/lib/logstash/instrument/metric_type/mean.rb +0 -5
- data/lib/logstash/instrument/namespaced_metric.rb +0 -4
- data/lib/logstash/instrument/namespaced_null_metric.rb +0 -4
- data/lib/logstash/instrument/null_metric.rb +0 -10
- data/lib/logstash/instrument/periodic_poller/cgroup.rb +85 -168
- data/lib/logstash/instrument/periodic_poller/jvm.rb +5 -5
- data/lib/logstash/instrument/periodic_poller/pq.rb +3 -7
- data/lib/logstash/instrument/periodic_pollers.rb +1 -3
- data/lib/logstash/instrument/wrapped_write_client.rb +24 -33
- data/lib/logstash/logging/logger.rb +15 -47
- data/lib/logstash/namespace.rb +0 -1
- data/lib/logstash/output_delegator.rb +5 -7
- data/lib/logstash/outputs/base.rb +0 -2
- data/lib/logstash/pipeline.rb +159 -87
- data/lib/logstash/pipeline_action.rb +13 -0
- data/lib/logstash/pipeline_action/base.rb +29 -0
- data/lib/logstash/pipeline_action/create.rb +47 -0
- data/lib/logstash/pipeline_action/reload.rb +48 -0
- data/lib/logstash/pipeline_action/stop.rb +23 -0
- data/lib/logstash/plugin.rb +0 -1
- data/lib/logstash/plugins/hooks_registry.rb +6 -0
- data/lib/logstash/plugins/registry.rb +0 -1
- data/lib/logstash/program.rb +14 -0
- data/lib/logstash/queue_factory.rb +5 -1
- data/lib/logstash/runner.rb +58 -80
- data/lib/logstash/settings.rb +3 -27
- data/lib/logstash/state_resolver.rb +41 -0
- data/lib/logstash/util/java_version.rb +6 -0
- data/lib/logstash/util/safe_uri.rb +12 -148
- data/lib/logstash/util/thread_dump.rb +4 -7
- data/lib/logstash/util/wrapped_acked_queue.rb +36 -39
- data/lib/logstash/util/wrapped_synchronous_queue.rb +29 -39
- data/lib/logstash/version.rb +10 -8
- data/locales/en.yml +3 -54
- data/logstash-core.gemspec +8 -35
- data/spec/{logstash/api/modules → api/lib/api}/logging_spec.rb +10 -1
- data/spec/{logstash/api/modules → api/lib/api}/node_plugins_spec.rb +2 -1
- data/spec/{logstash/api/modules → api/lib/api}/node_spec.rb +3 -3
- data/spec/{logstash/api/modules → api/lib/api}/node_stats_spec.rb +3 -7
- data/spec/{logstash/api/modules → api/lib/api}/plugins_spec.rb +3 -4
- data/spec/{logstash/api/modules → api/lib/api}/root_spec.rb +2 -2
- data/spec/api/lib/api/support/resource_dsl_methods.rb +87 -0
- data/spec/{logstash/api/commands/stats_spec.rb → api/lib/commands/stats.rb} +2 -7
- data/spec/{logstash/api → api/lib}/errors_spec.rb +1 -1
- data/spec/{logstash/api → api/lib}/rack_app_spec.rb +0 -0
- data/spec/api/spec_helper.rb +106 -0
- data/spec/logstash/agent/converge_spec.rb +286 -0
- data/spec/logstash/agent/metrics_spec.rb +244 -0
- data/spec/logstash/agent_spec.rb +213 -225
- data/spec/logstash/compiler/compiler_spec.rb +584 -0
- data/spec/logstash/config/config_ast_spec.rb +8 -47
- data/spec/logstash/config/mixin_spec.rb +2 -42
- data/spec/logstash/config/pipeline_config_spec.rb +75 -0
- data/spec/logstash/config/source/local_spec.rb +395 -0
- data/spec/logstash/config/source_loader_spec.rb +122 -0
- data/spec/logstash/converge_result_spec.rb +179 -0
- data/spec/logstash/event_spec.rb +0 -66
- data/spec/logstash/execution_context_spec.rb +8 -12
- data/spec/logstash/filter_delegator_spec.rb +12 -24
- data/spec/logstash/inputs/base_spec.rb +7 -5
- data/spec/logstash/instrument/periodic_poller/cgroup_spec.rb +92 -225
- data/spec/logstash/instrument/periodic_poller/jvm_spec.rb +1 -1
- data/spec/logstash/instrument/periodic_poller/os_spec.rb +32 -29
- data/spec/logstash/instrument/wrapped_write_client_spec.rb +33 -33
- data/spec/logstash/legacy_ruby_event_spec.rb +13 -4
- data/spec/logstash/output_delegator_spec.rb +11 -20
- data/spec/logstash/outputs/base_spec.rb +7 -5
- data/spec/logstash/pipeline_action/create_spec.rb +83 -0
- data/spec/logstash/pipeline_action/reload_spec.rb +83 -0
- data/spec/logstash/pipeline_action/stop_spec.rb +37 -0
- data/spec/logstash/pipeline_pq_file_spec.rb +1 -1
- data/spec/logstash/pipeline_spec.rb +81 -137
- data/spec/logstash/plugin_spec.rb +2 -1
- data/spec/logstash/plugins/hooks_registry_spec.rb +6 -0
- data/spec/logstash/queue_factory_spec.rb +13 -1
- data/spec/logstash/runner_spec.rb +29 -140
- data/spec/logstash/settings/writable_directory_spec.rb +10 -13
- data/spec/logstash/settings_spec.rb +0 -91
- data/spec/logstash/state_resolver_spec.rb +156 -0
- data/spec/logstash/timestamp_spec.rb +2 -6
- data/spec/logstash/util/java_version_spec.rb +22 -0
- data/spec/logstash/util/safe_uri_spec.rb +0 -56
- data/spec/logstash/util/wrapped_synchronous_queue_spec.rb +22 -0
- data/spec/support/helpers.rb +9 -11
- data/spec/support/matchers.rb +96 -6
- data/spec/support/mocks_classes.rb +80 -0
- data/spec/support/shared_contexts.rb +2 -27
- metadata +100 -149
- data/lib/logstash/config/loader.rb +0 -107
- data/lib/logstash/config/modules_common.rb +0 -103
- data/lib/logstash/config/source/modules.rb +0 -55
- data/lib/logstash/config/string_escape.rb +0 -27
- data/lib/logstash/dependency_report.rb +0 -131
- data/lib/logstash/dependency_report_runner.rb +0 -17
- data/lib/logstash/elasticsearch_client.rb +0 -142
- data/lib/logstash/instrument/global_metrics.rb +0 -13
- data/lib/logstash/instrument/periodic_poller/dlq.rb +0 -24
- data/lib/logstash/modules/cli_parser.rb +0 -74
- data/lib/logstash/modules/elasticsearch_config.rb +0 -22
- data/lib/logstash/modules/elasticsearch_importer.rb +0 -37
- data/lib/logstash/modules/elasticsearch_resource.rb +0 -10
- data/lib/logstash/modules/file_reader.rb +0 -36
- data/lib/logstash/modules/kibana_base.rb +0 -24
- data/lib/logstash/modules/kibana_client.rb +0 -124
- data/lib/logstash/modules/kibana_config.rb +0 -105
- data/lib/logstash/modules/kibana_dashboards.rb +0 -36
- data/lib/logstash/modules/kibana_importer.rb +0 -17
- data/lib/logstash/modules/kibana_resource.rb +0 -10
- data/lib/logstash/modules/kibana_settings.rb +0 -40
- data/lib/logstash/modules/logstash_config.rb +0 -120
- data/lib/logstash/modules/resource_base.rb +0 -38
- data/lib/logstash/modules/scaffold.rb +0 -52
- data/lib/logstash/modules/settings_merger.rb +0 -23
- data/lib/logstash/modules/util.rb +0 -17
- data/lib/logstash/util/dead_letter_queue_manager.rb +0 -61
- data/lib/logstash/util/environment_variables.rb +0 -43
- data/spec/logstash/config/loader_spec.rb +0 -38
- data/spec/logstash/config/string_escape_spec.rb +0 -24
- data/spec/logstash/instrument/periodic_poller/dlq_spec.rb +0 -17
- data/spec/logstash/modules/logstash_config_spec.rb +0 -56
- data/spec/logstash/modules/scaffold_spec.rb +0 -234
- data/spec/logstash/pipeline_dlq_commit_spec.rb +0 -109
- data/spec/logstash/settings/splittable_string_array_spec.rb +0 -51
- data/spec/logstash/util/wrapped_acked_queue_spec.rb +0 -49
- data/versions-gem-copy.yml +0 -12
@@ -0,0 +1,92 @@
|
|
1
|
+
class Treetop::Runtime::SyntaxNode
|
2
|
+
def get_meta(key)
|
3
|
+
@ast_metadata ||= {}
|
4
|
+
return @ast_metadata[key] if @ast_metadata[key]
|
5
|
+
return self.parent.get_meta(key) if self.parent
|
6
|
+
nil
|
7
|
+
end
|
8
|
+
|
9
|
+
def set_meta(key, value)
|
10
|
+
@ast_metadata ||= {}
|
11
|
+
@ast_metadata[key] = value
|
12
|
+
end
|
13
|
+
def compile
|
14
|
+
return "" if elements.nil?
|
15
|
+
return elements.collect(&:compile).reject(&:empty?).join("")
|
16
|
+
end
|
17
|
+
|
18
|
+
# Traverse the syntax tree recursively.
|
19
|
+
# The order should respect the order of the configuration file as it is read
|
20
|
+
# and written by humans (and the order in which it is parsed).
|
21
|
+
def recurse(e, depth=0, &block)
|
22
|
+
r = block.call(e, depth)
|
23
|
+
e.elements.each { |e| recurse(e, depth + 1, &block) } if r && e.elements
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def recursive_inject(results=[], &block)
|
28
|
+
if !elements.nil?
|
29
|
+
elements.each do |element|
|
30
|
+
if block.call(element)
|
31
|
+
results << element
|
32
|
+
else
|
33
|
+
element.recursive_inject(results, &block)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
return results
|
38
|
+
end
|
39
|
+
|
40
|
+
# When Treetop parses the configuration file
|
41
|
+
# it will generate a tree, the generated tree will contain
|
42
|
+
# a few `Empty` nodes to represent the actual space/tab or newline in the file.
|
43
|
+
# Some of theses node will point to our concrete class.
|
44
|
+
# To fetch a specific types of object we need to follow each branch
|
45
|
+
# and ignore the empty nodes.
|
46
|
+
def recursive_select(*klasses)
|
47
|
+
return recursive_inject { |e| klasses.any? {|k| e.is_a?(k)} }
|
48
|
+
end
|
49
|
+
|
50
|
+
def recursive_inject_parent(results=[], &block)
|
51
|
+
if !parent.nil?
|
52
|
+
if block.call(parent)
|
53
|
+
results << parent
|
54
|
+
else
|
55
|
+
parent.recursive_inject_parent(results, &block)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
return results
|
59
|
+
end
|
60
|
+
|
61
|
+
def recursive_select_parent(results=[], klass)
|
62
|
+
return recursive_inject_parent(results) { |e| e.is_a?(klass) }
|
63
|
+
end
|
64
|
+
|
65
|
+
# Monkeypatch Treetop::Runtime::SyntaxNode's inspect method to skip
|
66
|
+
# any Whitespace or SyntaxNodes with no children.
|
67
|
+
def _inspect(indent="")
|
68
|
+
em = extension_modules
|
69
|
+
interesting_methods = methods-[em.last ? em.last.methods : nil]-self.class.instance_methods
|
70
|
+
im = interesting_methods.size > 0 ? " (#{interesting_methods.join(",")})" : ""
|
71
|
+
tv = text_value
|
72
|
+
tv = "...#{tv[-20..-1]}" if tv.size > 20
|
73
|
+
|
74
|
+
indent +
|
75
|
+
self.class.to_s.sub(/.*:/,'') +
|
76
|
+
em.map{|m| "+"+m.to_s.sub(/.*:/,'')}*"" +
|
77
|
+
" offset=#{interval.first}" +
|
78
|
+
", #{tv.inspect}" +
|
79
|
+
im +
|
80
|
+
(elements && elements.size > 0 ?
|
81
|
+
":" +
|
82
|
+
(elements.select { |e| !e.is_a?(LogStash::Config::AST::Whitespace) && e.elements && e.elements.size > 0 }||[]).map{|e|
|
83
|
+
begin
|
84
|
+
"\n"+e.inspect(indent+" ")
|
85
|
+
rescue # Defend against inspect not taking a parameter
|
86
|
+
"\n"+indent+" "+e.inspect
|
87
|
+
end
|
88
|
+
}.join("") :
|
89
|
+
""
|
90
|
+
)
|
91
|
+
end
|
92
|
+
end
|
@@ -1,78 +1,10 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'logstash/errors'
|
3
|
-
require "logstash/config/string_escape"
|
4
3
|
require "treetop"
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
def compile
|
9
|
-
return "" if elements.nil?
|
10
|
-
return elements.collect(&:compile).reject(&:empty?).join("")
|
11
|
-
end
|
12
|
-
|
13
|
-
def get_meta(key)
|
14
|
-
@ast_metadata ||= {}
|
15
|
-
return @ast_metadata[key] if @ast_metadata[key]
|
16
|
-
return self.parent.get_meta(key) if self.parent
|
17
|
-
nil
|
18
|
-
end
|
19
|
-
|
20
|
-
def set_meta(key, value)
|
21
|
-
@ast_metadata ||= {}
|
22
|
-
@ast_metadata[key] = value
|
23
|
-
end
|
24
|
-
|
25
|
-
# Traverse the syntax tree recursively.
|
26
|
-
# The order should respect the order of the configuration file as it is read
|
27
|
-
# and written by humans (and the order in which it is parsed).
|
28
|
-
def recurse(e, depth=0, &block)
|
29
|
-
r = block.call(e, depth)
|
30
|
-
e.elements.each { |e| recurse(e, depth + 1, &block) } if r && e.elements
|
31
|
-
nil
|
32
|
-
end
|
33
|
-
|
34
|
-
def recursive_inject(results=[], &block)
|
35
|
-
if !elements.nil?
|
36
|
-
elements.each do |element|
|
37
|
-
if block.call(element)
|
38
|
-
results << element
|
39
|
-
else
|
40
|
-
element.recursive_inject(results, &block)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
return results
|
45
|
-
end
|
46
|
-
|
47
|
-
# When Treetop parses the configuration file
|
48
|
-
# it will generate a tree, the generated tree will contain
|
49
|
-
# a few `Empty` nodes to represent the actual space/tab or newline in the file.
|
50
|
-
# Some of theses node will point to our concrete class.
|
51
|
-
# To fetch a specific types of object we need to follow each branch
|
52
|
-
# and ignore the empty nodes.
|
53
|
-
def recursive_select(klass)
|
54
|
-
return recursive_inject { |e| e.is_a?(klass) }
|
55
|
-
end
|
56
|
-
|
57
|
-
def recursive_inject_parent(results=[], &block)
|
58
|
-
if !parent.nil?
|
59
|
-
if block.call(parent)
|
60
|
-
results << parent
|
61
|
-
else
|
62
|
-
parent.recursive_inject_parent(results, &block)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
return results
|
66
|
-
end
|
67
|
-
|
68
|
-
def recursive_select_parent(results=[], klass)
|
69
|
-
return recursive_inject_parent(results) { |e| e.is_a?(klass) }
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
5
|
+
require "logstash/compiler/treetop_monkeypatches"
|
73
6
|
|
74
7
|
module LogStash; module Config; module AST
|
75
|
-
PROCESS_ESCAPE_SEQUENCES = :process_escape_sequences
|
76
8
|
|
77
9
|
def self.deferred_conditionals=(val)
|
78
10
|
@deferred_conditionals = val
|
@@ -105,11 +37,6 @@ module LogStash; module Config; module AST
|
|
105
37
|
end
|
106
38
|
|
107
39
|
class Config < Node
|
108
|
-
def process_escape_sequences=(val)
|
109
|
-
set_meta(PROCESS_ESCAPE_SEQUENCES, val)
|
110
|
-
end
|
111
|
-
|
112
|
-
|
113
40
|
def compile
|
114
41
|
LogStash::Config::AST.deferred_conditionals = []
|
115
42
|
LogStash::Config::AST.deferred_conditionals_index = 0
|
@@ -141,9 +68,8 @@ module LogStash; module Config; module AST
|
|
141
68
|
# of the output/filter function
|
142
69
|
definitions << "define_singleton_method :#{type}_func do |event|"
|
143
70
|
definitions << " targeted_outputs = []" if type == "output"
|
144
|
-
definitions << " events = event" if type == "filter"
|
145
|
-
definitions << " @logger.debug? && @logger.debug(\"#{type} received\", \"event\" => event.to_hash)"
|
146
|
-
definitions << " @logger.debug? && events.each { |e| @logger.debug(\"#{type} received\", \"event\" => e.to_hash)}" if type == "filter"
|
71
|
+
definitions << " events = [event]" if type == "filter"
|
72
|
+
definitions << " @logger.debug? && @logger.debug(\"#{type} received\", \"event\" => event.to_hash)"
|
147
73
|
|
148
74
|
sections.select { |s| s.plugin_type.text_value == type }.each do |s|
|
149
75
|
definitions << s.compile.split("\n", -1).map { |e| " #{e}" }
|
@@ -353,11 +279,7 @@ module LogStash; module Config; module AST
|
|
353
279
|
end
|
354
280
|
class String < Value
|
355
281
|
def compile
|
356
|
-
|
357
|
-
Unicode.wrap(LogStash::Config::StringEscape.process_escapes(text_value[1...-1]))
|
358
|
-
else
|
359
|
-
Unicode.wrap(text_value[1...-1])
|
360
|
-
end
|
282
|
+
return Unicode.wrap(text_value[1...-1])
|
361
283
|
end
|
362
284
|
end
|
363
285
|
class RegExp < Value
|
@@ -33,21 +33,37 @@ LogStash::Environment.load_locale!
|
|
33
33
|
# }
|
34
34
|
#
|
35
35
|
module LogStash::Config::Mixin
|
36
|
-
|
37
|
-
include LogStash::Util::EnvironmentVariables
|
38
|
-
|
39
36
|
attr_accessor :config
|
40
37
|
attr_accessor :original_params
|
41
38
|
|
42
39
|
PLUGIN_VERSION_1_0_0 = LogStash::Util::PluginVersion.new(1, 0, 0)
|
43
40
|
PLUGIN_VERSION_0_9_0 = LogStash::Util::PluginVersion.new(0, 9, 0)
|
44
|
-
|
41
|
+
|
42
|
+
ENV_PLACEHOLDER_REGEX = /\$\{(?<name>\w+)(\:(?<default>[^}]*))?\}/
|
43
|
+
|
45
44
|
# This method is called when someone does 'include LogStash::Config'
|
46
45
|
def self.included(base)
|
47
46
|
# Add the DSL methods to the 'base' given.
|
48
47
|
base.extend(LogStash::Config::Mixin::DSL)
|
49
48
|
end
|
50
|
-
|
49
|
+
|
50
|
+
# Recursive method to replace environment variable references in parameters
|
51
|
+
def deep_replace(value)
|
52
|
+
if (value.is_a?(Hash))
|
53
|
+
value.each do |valueHashKey, valueHashValue|
|
54
|
+
value[valueHashKey.to_s] = deep_replace(valueHashValue)
|
55
|
+
end
|
56
|
+
else
|
57
|
+
if (value.is_a?(Array))
|
58
|
+
value.each_index do | valueArrayIndex|
|
59
|
+
value[valueArrayIndex] = deep_replace(value[valueArrayIndex])
|
60
|
+
end
|
61
|
+
else
|
62
|
+
return replace_env_placeholders(value)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
51
67
|
def config_init(params)
|
52
68
|
# Validation will modify the values inside params if necessary.
|
53
69
|
# For example: converting a string to a number, etc.
|
@@ -60,6 +76,30 @@ module LogStash::Config::Mixin
|
|
60
76
|
# store the plugin type, turns LogStash::Inputs::Base into 'input'
|
61
77
|
@plugin_type = self.class.ancestors.find { |a| a.name =~ /::Base$/ }.config_name
|
62
78
|
|
79
|
+
# warn about deprecated variable use
|
80
|
+
params.each do |name, value|
|
81
|
+
opts = self.class.get_config[name]
|
82
|
+
if opts && opts[:deprecated]
|
83
|
+
extra = opts[:deprecated].is_a?(String) ? opts[:deprecated] : ""
|
84
|
+
extra.gsub!("%PLUGIN%", self.class.config_name)
|
85
|
+
self.logger.warn("You are using a deprecated config setting " +
|
86
|
+
"#{name.inspect} set in #{self.class.config_name}. " +
|
87
|
+
"Deprecated settings will continue to work, " +
|
88
|
+
"but are scheduled for removal from logstash " +
|
89
|
+
"in the future. #{extra} If you have any questions " +
|
90
|
+
"about this, please visit the #logstash channel " +
|
91
|
+
"on freenode irc.", :name => name, :plugin => self)
|
92
|
+
|
93
|
+
end
|
94
|
+
if opts && opts[:obsolete]
|
95
|
+
extra = opts[:obsolete].is_a?(String) ? opts[:obsolete] : ""
|
96
|
+
extra.gsub!("%PLUGIN%", self.class.config_name)
|
97
|
+
raise LogStash::ConfigurationError,
|
98
|
+
I18n.t("logstash.runner.configuration.obsolete", :name => name,
|
99
|
+
:plugin => self.class.config_name, :extra => extra)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
63
103
|
# Set defaults from 'config :foo, :default => somevalue'
|
64
104
|
self.class.get_config.each do |name, opts|
|
65
105
|
next if params.include?(name.to_s)
|
@@ -85,46 +125,17 @@ module LogStash::Config::Mixin
|
|
85
125
|
params[name.to_s] = deep_replace(value)
|
86
126
|
end
|
87
127
|
|
128
|
+
|
88
129
|
if !self.class.validate(params)
|
89
130
|
raise LogStash::ConfigurationError,
|
90
131
|
I18n.t("logstash.runner.configuration.invalid_plugin_settings")
|
91
132
|
end
|
92
133
|
|
93
|
-
# now that we know the parameters are valid, we can obfuscate the original copy
|
94
|
-
# of the parameters before storing them as an instance variable
|
95
|
-
self.class.secure_params!(original_params)
|
96
|
-
@original_params = original_params
|
97
|
-
|
98
|
-
# warn about deprecated variable use
|
99
|
-
original_params.each do |name, value|
|
100
|
-
opts = self.class.get_config[name]
|
101
|
-
if opts && opts[:deprecated]
|
102
|
-
extra = opts[:deprecated].is_a?(String) ? opts[:deprecated] : ""
|
103
|
-
extra.gsub!("%PLUGIN%", self.class.config_name)
|
104
|
-
self.logger.warn("You are using a deprecated config setting " +
|
105
|
-
"#{name.inspect} set in #{self.class.config_name}. " +
|
106
|
-
"Deprecated settings will continue to work, " +
|
107
|
-
"but are scheduled for removal from logstash " +
|
108
|
-
"in the future. #{extra} If you have any questions " +
|
109
|
-
"about this, please visit the #logstash channel " +
|
110
|
-
"on freenode irc.", :name => name, :plugin => self)
|
111
|
-
|
112
|
-
end
|
113
|
-
|
114
|
-
if opts && opts[:obsolete]
|
115
|
-
extra = opts[:obsolete].is_a?(String) ? opts[:obsolete] : ""
|
116
|
-
extra.gsub!("%PLUGIN%", self.class.config_name)
|
117
|
-
raise LogStash::ConfigurationError,
|
118
|
-
I18n.t("logstash.runner.configuration.obsolete", :name => name,
|
119
|
-
:plugin => self.class.config_name, :extra => extra)
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
134
|
# We remove any config options marked as obsolete,
|
124
135
|
# no code should be associated to them and their values should not bleed
|
125
136
|
# to the plugin context.
|
126
137
|
#
|
127
|
-
# This need to be done after fetching the options from the parents
|
138
|
+
# This need to be done after fetching the options from the parents classed
|
128
139
|
params.reject! do |name, value|
|
129
140
|
opts = self.class.get_config[name]
|
130
141
|
opts.include?(:obsolete)
|
@@ -139,13 +150,36 @@ module LogStash::Config::Mixin
|
|
139
150
|
instance_variable_set("@#{key}", value)
|
140
151
|
end
|
141
152
|
|
153
|
+
# now that we know the parameters are valid, we can obfuscate the original copy
|
154
|
+
# of the parameters before storing them as an instance variable
|
155
|
+
self.class.secure_params!(original_params)
|
156
|
+
@original_params = original_params
|
157
|
+
|
142
158
|
@config = params
|
143
159
|
end # def config_init
|
144
160
|
|
145
|
-
|
146
|
-
|
147
|
-
|
161
|
+
# Replace all environment variable references in 'value' param by environment variable value and return updated value
|
162
|
+
# Process following patterns : $VAR, ${VAR}, ${VAR:defaultValue}
|
163
|
+
def replace_env_placeholders(value)
|
164
|
+
return value unless value.is_a?(String)
|
165
|
+
|
166
|
+
value.gsub(ENV_PLACEHOLDER_REGEX) do |placeholder|
|
167
|
+
# Note: Ruby docs claim[1] Regexp.last_match is thread-local and scoped to
|
168
|
+
# the call, so this should be thread-safe.
|
169
|
+
#
|
170
|
+
# [1] http://ruby-doc.org/core-2.1.1/Regexp.html#method-c-last_match
|
171
|
+
name = Regexp.last_match(:name)
|
172
|
+
default = Regexp.last_match(:default)
|
173
|
+
|
174
|
+
replacement = ENV.fetch(name, default)
|
175
|
+
if replacement.nil?
|
176
|
+
raise LogStash::ConfigurationError, "Cannot evaluate `#{placeholder}`. Environment variable `#{name}` is not set and there is no default value given."
|
177
|
+
end
|
178
|
+
replacement
|
179
|
+
end
|
180
|
+
end # def replace_env_placeholders
|
148
181
|
|
182
|
+
module DSL
|
149
183
|
attr_accessor :flags
|
150
184
|
|
151
185
|
# If name is given, set the name and return it.
|
@@ -391,8 +425,6 @@ module LogStash::Config::Mixin
|
|
391
425
|
# (see LogStash::Inputs::File for example)
|
392
426
|
result = nil
|
393
427
|
|
394
|
-
value = deep_replace(value)
|
395
|
-
|
396
428
|
if validator.nil?
|
397
429
|
return true, value
|
398
430
|
elsif validator.is_a?(Array)
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "digest"
|
3
|
+
|
4
|
+
module LogStash module Config
|
5
|
+
class PipelineConfig
|
6
|
+
include LogStash::Util::Loggable
|
7
|
+
|
8
|
+
attr_reader :source, :pipeline_id, :config_parts, :settings, :read_at
|
9
|
+
|
10
|
+
def initialize(source, pipeline_id, config_parts, settings)
|
11
|
+
@source = source
|
12
|
+
@pipeline_id = pipeline_id
|
13
|
+
# We can't use Array() since config_parts may be a java object!
|
14
|
+
config_parts_array = config_parts.is_a?(Array) ? config_parts : [config_parts]
|
15
|
+
@config_parts = config_parts_array.sort_by { |config_part| [config_part.protocol.to_s, config_part.id] }
|
16
|
+
@settings = settings
|
17
|
+
@read_at = Time.now
|
18
|
+
end
|
19
|
+
|
20
|
+
def config_hash
|
21
|
+
@config_hash ||= Digest::SHA1.hexdigest(config_string)
|
22
|
+
end
|
23
|
+
|
24
|
+
def config_string
|
25
|
+
@config_string = config_parts.collect(&:text).join("\n")
|
26
|
+
end
|
27
|
+
|
28
|
+
def system?
|
29
|
+
@settings.get("pipeline.system")
|
30
|
+
end
|
31
|
+
|
32
|
+
def ==(other)
|
33
|
+
config_hash == other.config_hash && pipeline_id == other.pipeline_id
|
34
|
+
end
|
35
|
+
|
36
|
+
def display_debug_information
|
37
|
+
logger.debug("-------- Logstash Config ---------")
|
38
|
+
logger.debug("Config from source", :source => source, :pipeline_id => pipeline_id)
|
39
|
+
|
40
|
+
config_parts.each do |config_part|
|
41
|
+
logger.debug("Config string", :protocol => config_part.protocol, :id => config_part.id)
|
42
|
+
logger.debug("\n\n#{config_part.text}")
|
43
|
+
end
|
44
|
+
logger.debug("Merged config")
|
45
|
+
logger.debug("\n\n#{config_string}")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module LogStash module Config module Source
|
3
|
+
class Base
|
4
|
+
def initialize(settings)
|
5
|
+
@settings = settings
|
6
|
+
end
|
7
|
+
|
8
|
+
def pipeline_configs
|
9
|
+
raise NotImplementedError, "`#pipeline_configs` must be implemented!"
|
10
|
+
end
|
11
|
+
|
12
|
+
def match?
|
13
|
+
raise NotImplementedError, "`match?` must be implemented!"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end end end
|
@@ -0,0 +1,215 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/config/source/base"
|
3
|
+
require "logstash/config/pipeline_config"
|
4
|
+
require "logstash/util/loggable"
|
5
|
+
require "logstash/errors"
|
6
|
+
require "uri"
|
7
|
+
|
8
|
+
module LogStash module Config module Source
|
9
|
+
# A locally defined configuration source
|
10
|
+
#
|
11
|
+
# Which can aggregate the following config options:
|
12
|
+
# - settings.config_string: "input { stdin {} }"
|
13
|
+
# - settings.config_path: /tmp/logstash/*.conf
|
14
|
+
# - settings.config_path: http://localhost/myconfig.conf
|
15
|
+
#
|
16
|
+
# All theses option will create a unique pipeline, generated parts will be
|
17
|
+
# sorted alphabetically. Se `PipelineConfig` class for the sorting algorithm.
|
18
|
+
#
|
19
|
+
class Local < Base
|
20
|
+
class ConfigStringLoader
|
21
|
+
def self.read(config_string)
|
22
|
+
[org.logstash.common.SourceWithMetadata.new("string", "config_string", config_string)]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class ConfigPathLoader
|
27
|
+
include LogStash::Util::Loggable
|
28
|
+
|
29
|
+
TEMPORARY_FILE_RE = /~$/
|
30
|
+
LOCAL_FILE_URI = /^file:\/\//i
|
31
|
+
|
32
|
+
def initialize(path)
|
33
|
+
@path = normalize_path(path)
|
34
|
+
end
|
35
|
+
|
36
|
+
def read
|
37
|
+
config_parts = []
|
38
|
+
encoding_issue_files = []
|
39
|
+
|
40
|
+
get_files.each do |file|
|
41
|
+
next unless ::File.file?(file) # skip directory
|
42
|
+
|
43
|
+
logger.debug("Reading config file", :config_file => file)
|
44
|
+
|
45
|
+
if temporary_file?(file)
|
46
|
+
logger.warn("NOT reading config file because it is a temp file", :config_file => file)
|
47
|
+
next
|
48
|
+
end
|
49
|
+
|
50
|
+
config_string = ::File.read(file)
|
51
|
+
|
52
|
+
if valid_encoding?(config_string)
|
53
|
+
part = org.logstash.common.SourceWithMetadata.new("file", file, config_string)
|
54
|
+
config_parts << part
|
55
|
+
else
|
56
|
+
encoding_issue_files << file
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
if encoding_issue_files.any?
|
61
|
+
raise LogStash::ConfigLoadingError, "The following config files contains non-ascii characters but are not UTF-8 encoded #{encoding_issue_files}"
|
62
|
+
end
|
63
|
+
|
64
|
+
if config_parts.empty?
|
65
|
+
logger.info("No config files found in path", :path => path)
|
66
|
+
end
|
67
|
+
|
68
|
+
config_parts
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.read(path)
|
72
|
+
ConfigPathLoader.new(path).read
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
def normalize_path(path)
|
77
|
+
path.gsub!(LOCAL_FILE_URI, "")
|
78
|
+
::File.expand_path(path)
|
79
|
+
end
|
80
|
+
|
81
|
+
def get_files
|
82
|
+
Dir.glob(path).sort
|
83
|
+
end
|
84
|
+
|
85
|
+
def path
|
86
|
+
if ::File.directory?(@path)
|
87
|
+
::File.join(@path, "*")
|
88
|
+
else
|
89
|
+
@path
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def valid_encoding?(content)
|
94
|
+
content.ascii_only? && content.valid_encoding?
|
95
|
+
end
|
96
|
+
|
97
|
+
def temporary_file?(filepath)
|
98
|
+
filepath.match(TEMPORARY_FILE_RE)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class ConfigRemoteLoader
|
103
|
+
def self.read(uri)
|
104
|
+
uri = URI.parse(uri)
|
105
|
+
|
106
|
+
Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == "https") do |http|
|
107
|
+
request = Net::HTTP::Get.new(uri.path)
|
108
|
+
response = http.request(request)
|
109
|
+
|
110
|
+
# since we have fetching config we wont follow any redirection.
|
111
|
+
case response.code.to_i
|
112
|
+
when 200
|
113
|
+
[org.logstash.common.SourceWithMetadata.new(uri.scheme, uri.to_s, response.body)]
|
114
|
+
when 302
|
115
|
+
raise LogStash::ConfigLoadingError, I18n.t("logstash.runner.configuration.fetch-failed", :path => uri.to_s, :message => "We don't follow redirection for remote configuration")
|
116
|
+
when 404
|
117
|
+
raise LogStash::ConfigLoadingError, I18n.t("logstash.runner.configuration.fetch-failed", :path => uri.to_s, :message => "File not found")
|
118
|
+
when 403
|
119
|
+
raise LogStash::ConfigLoadingError, I18n.t("logstash.runner.configuration.fetch-failed", :path => uri.to_s, :message => "Permission denied")
|
120
|
+
when 500
|
121
|
+
raise LogStash::ConfigLoadingError, I18n.t("logstash.runner.configuration.fetch-failed", :path => uri.to_s, :message => "500 error on remote host")
|
122
|
+
else
|
123
|
+
raise LogStash::ConfigLoadingError, I18n.t("logstash.runner.configuration.fetch-failed", :path => uri.to_s, :message => "code: #{response.code}, message: #{response.class.to_s}")
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
PIPELINE_ID = LogStash::SETTINGS.get("pipeline.id").to_sym
|
130
|
+
HTTP_RE = /^http(s)?/
|
131
|
+
INPUT_BLOCK_RE = /input *{/
|
132
|
+
OUTPUT_BLOCK_RE = /output *{/
|
133
|
+
|
134
|
+
def pipeline_configs
|
135
|
+
config_parts = []
|
136
|
+
|
137
|
+
config_parts.concat(ConfigStringLoader.read(config_string)) if config_string?
|
138
|
+
if local_config?
|
139
|
+
local_config_parts = ConfigPathLoader.read(config_path)
|
140
|
+
config_parts.concat(local_config_parts)
|
141
|
+
else
|
142
|
+
local_config_parts = []
|
143
|
+
end
|
144
|
+
|
145
|
+
config_parts.concat(ConfigRemoteLoader.read(config_path)) if remote_config?
|
146
|
+
|
147
|
+
return if config_parts.empty?
|
148
|
+
return if config_string? && config_string.strip.empty? && local_config? && local_config_parts.empty?
|
149
|
+
|
150
|
+
add_missing_default_inputs_or_outputs(config_parts)
|
151
|
+
|
152
|
+
[PipelineConfig.new(self.class, PIPELINE_ID, config_parts, @settings)]
|
153
|
+
end
|
154
|
+
|
155
|
+
def match?
|
156
|
+
config_string? || config_path?
|
157
|
+
end
|
158
|
+
|
159
|
+
private
|
160
|
+
# Make sure we have an input and at least 1 output
|
161
|
+
# if its not the case we will add stdin and stdout
|
162
|
+
# this is for backward compatibility reason
|
163
|
+
def add_missing_default_inputs_or_outputs(config_parts)
|
164
|
+
if !config_parts.any? { |part| INPUT_BLOCK_RE.match(part.text) }
|
165
|
+
config_parts << org.logstash.common.SourceWithMetadata.new(self.class.name, "default input", LogStash::Config::Defaults.input)
|
166
|
+
end
|
167
|
+
|
168
|
+
# include a default stdout output if no outputs given
|
169
|
+
if !config_parts.any? { |part| OUTPUT_BLOCK_RE.match(part.text) }
|
170
|
+
config_parts << org.logstash.common.SourceWithMetadata.new(self.class.name, "default output", LogStash::Config::Defaults.output)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def config_string
|
175
|
+
@settings.get("config.string")
|
176
|
+
end
|
177
|
+
|
178
|
+
def config_string?
|
179
|
+
!config_string.nil?
|
180
|
+
end
|
181
|
+
|
182
|
+
def config_path
|
183
|
+
@settings.get("path.config")
|
184
|
+
end
|
185
|
+
|
186
|
+
def config_path?
|
187
|
+
!config_path.nil? && !config_path.empty?
|
188
|
+
end
|
189
|
+
|
190
|
+
def local_config?
|
191
|
+
return false unless config_path?
|
192
|
+
|
193
|
+
begin
|
194
|
+
uri = URI.parse(config_path)
|
195
|
+
uri.scheme == "file" || uri.scheme.nil?
|
196
|
+
rescue URI::InvalidURIError
|
197
|
+
# fallback for windows.
|
198
|
+
# if the parsing of the file failed we assume we can reach it locally.
|
199
|
+
# some relative path on windows arent parsed correctly (.\logstash.conf)
|
200
|
+
true
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def remote_config?
|
205
|
+
return false unless config_path?
|
206
|
+
|
207
|
+
begin
|
208
|
+
uri = URI.parse(config_path)
|
209
|
+
uri.scheme =~ HTTP_RE
|
210
|
+
rescue URI::InvalidURIError
|
211
|
+
false
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end end end
|