logstash-core 5.0.0.alpha3.snapshot2-java → 5.0.0.alpha3.snapshot4-java

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of logstash-core might be problematic. Click here for more details.

Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/lib/logstash-core/version.rb +1 -1
  3. data/lib/logstash/agent.rb +49 -31
  4. data/lib/logstash/api/init.ru +3 -3
  5. data/lib/logstash/api/lib/app/service.rb +1 -1
  6. data/lib/logstash/config/config_ast.rb +23 -18
  7. data/lib/logstash/config/loader.rb +4 -4
  8. data/lib/logstash/config/mixin.rb +10 -21
  9. data/lib/logstash/environment.rb +30 -0
  10. data/lib/logstash/filters/base.rb +2 -2
  11. data/lib/logstash/inputs/base.rb +2 -2
  12. data/lib/logstash/instrument/collector.rb +1 -1
  13. data/lib/logstash/logging/json.rb +21 -0
  14. data/lib/logstash/output_delegator.rb +2 -2
  15. data/lib/logstash/patches/clamp.rb +69 -0
  16. data/lib/logstash/pipeline.rb +37 -62
  17. data/lib/logstash/plugin.rb +1 -1
  18. data/lib/logstash/runner.rb +155 -146
  19. data/lib/logstash/settings.rb +267 -0
  20. data/lib/logstash/util/decorators.rb +6 -6
  21. data/lib/logstash/util/java_version.rb +1 -10
  22. data/lib/logstash/util/worker_threads_default_printer.rb +2 -2
  23. data/lib/logstash/version.rb +1 -1
  24. data/locales/en.yml +17 -20
  25. data/logstash-core.gemspec +1 -1
  26. data/spec/api/spec_helper.rb +15 -16
  27. data/spec/conditionals_spec.rb +113 -113
  28. data/spec/logstash/agent_spec.rb +77 -68
  29. data/spec/logstash/config/config_ast_spec.rb +4 -2
  30. data/spec/logstash/config/mixin_spec.rb +33 -7
  31. data/spec/logstash/filters/base_spec.rb +16 -16
  32. data/spec/logstash/inputs/base_spec.rb +8 -8
  33. data/spec/logstash/output_delegator_spec.rb +2 -0
  34. data/spec/logstash/pipeline_spec.rb +60 -26
  35. data/spec/logstash/plugin_spec.rb +2 -2
  36. data/spec/logstash/runner_spec.rb +112 -25
  37. data/spec/logstash/setting_spec.rb +130 -0
  38. data/spec/logstash/settings_spec.rb +62 -0
  39. metadata +11 -9
  40. data/lib/logstash/util/defaults_printer.rb +0 -31
  41. data/spec/logstash/util/defaults_printer_spec.rb +0 -50
  42. data/spec/logstash/util/worker_threads_default_printer_spec.rb +0 -45
@@ -75,7 +75,7 @@ module LogStash module Instrument
75
75
  logger.error("Collector: Something went wrong went sending data to the observers",
76
76
  :execution_time => time_of_execution,
77
77
  :result => result,
78
- :exception => exception)
78
+ :exception => exception.class.name)
79
79
  end
80
80
 
81
81
  # Snapshot the current Metric Store and return it immediately,
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+ require "logstash/namespace"
3
+ require "logstash/logging"
4
+ require "logstash/json"
5
+
6
+ module LogStash; class Logging; class JSON
7
+ def initialize(io)
8
+ raise ArgumentError, "Expected IO, got #{io.class.name}" unless io.is_a?(IO)
9
+
10
+ @io = io
11
+ @lock = Mutex.new
12
+ end
13
+
14
+ def <<(obj)
15
+ serialized = LogStash::Json.dump(obj)
16
+ @lock.synchronize do
17
+ @io.puts(serialized)
18
+ @io.flush
19
+ end
20
+ end
21
+ end; end; end
@@ -82,7 +82,7 @@ module LogStash class OutputDelegator
82
82
  @workers << @klass.new(@config)
83
83
  @workers.first.register # Needed in case register calls `workers_not_supported`
84
84
 
85
- @logger.debug("Will start workers for output", :worker_count => target_worker_count, :class => @klass)
85
+ @logger.debug("Will start workers for output", :worker_count => target_worker_count, :class => @klass.name)
86
86
 
87
87
  # Threadsafe versions don't need additional workers
88
88
  setup_additional_workers!(target_worker_count) unless @threadsafe
@@ -147,7 +147,7 @@ module LogStash class OutputDelegator
147
147
  end
148
148
 
149
149
  def do_close
150
- @logger.debug("closing output delegator", :klass => @klass)
150
+ @logger.debug("closing output delegator", :klass => @klass.name)
151
151
 
152
152
  if @threadsafe
153
153
  @workers.each(&:do_close)
@@ -0,0 +1,69 @@
1
+ require 'clamp'
2
+ require 'logstash/environment'
3
+
4
+ module Clamp
5
+ module Attribute
6
+ class Instance
7
+ def default_from_environment
8
+ # we don't want uncontrolled var injection from the environment
9
+ # since we're establishing that settings can be pulled from only three places:
10
+ # 1. default settings
11
+ # 2. yaml file
12
+ # 3. cli arguments
13
+ end
14
+ end
15
+ end
16
+
17
+ module Option
18
+
19
+ module StrictDeclaration
20
+
21
+ include Clamp::Attribute::Declaration
22
+
23
+ # Instead of letting Clamp set up accessors for the options
24
+ # weŕe going to tightly controlling them through
25
+ # LogStash::SETTINGS
26
+ def define_simple_writer_for(option, &block)
27
+ LogStash::SETTINGS.get(option.attribute_name)
28
+ define_method(option.write_method) do |value|
29
+ value = instance_exec(value, &block) if block
30
+ LogStash::SETTINGS.set_value(option.attribute_name, value)
31
+ end
32
+ end
33
+
34
+ def define_reader_for(option)
35
+ define_method(option.read_method) do
36
+ LogStash::SETTINGS.get_value(option.attribute_name)
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ class Definition
43
+ # Allow boolean flags to optionally receive a true/false argument
44
+ # to explicitly set them, i.e.
45
+ # --long.flag.name => sets flag to true
46
+ # --long.flag.name true => sets flag to true
47
+ # --long.flag.name false => sets flag to false
48
+ # --long.flag.name=true => sets flag to true
49
+ # --long.flag.name=false => sets flag to false
50
+ def extract_value(switch, arguments)
51
+ if flag? && (arguments.first.nil? || arguments.first.match("^-"))
52
+ flag_value(switch)
53
+ else
54
+ arguments.shift
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ # Create a subclass of Clamp::Command that enforces the use of
61
+ # LogStash::SETTINGS for setting validation
62
+ class StrictCommand < Command
63
+ class << self
64
+ include ::Clamp::Option::StrictDeclaration
65
+ end
66
+ end
67
+ end
68
+
69
+
@@ -9,8 +9,6 @@ require "logstash/config/file"
9
9
  require "logstash/filters/base"
10
10
  require "logstash/inputs/base"
11
11
  require "logstash/outputs/base"
12
- require "logstash/config/cpu_core_strategy"
13
- require "logstash/util/defaults_printer"
14
12
  require "logstash/shutdown_watcher"
15
13
  require "logstash/util/wrapped_synchronous_queue"
16
14
  require "logstash/pipeline_reporter"
@@ -22,7 +20,7 @@ require "logstash/output_delegator"
22
20
  require "logstash/filter_delegator"
23
21
 
24
22
  module LogStash; class Pipeline
25
- attr_reader :inputs,
23
+ attr_reader :inputs,
26
24
  :filters,
27
25
  :outputs,
28
26
  :worker_threads,
@@ -30,39 +28,25 @@ module LogStash; class Pipeline
30
28
  :events_filtered,
31
29
  :reporter,
32
30
  :pipeline_id,
33
- :metric,
34
31
  :logger,
35
32
  :started_at,
36
33
  :thread,
37
34
  :config_str,
38
- :original_settings
39
-
40
- DEFAULT_OUTPUT_WORKERS = 1
41
-
42
- DEFAULT_SETTINGS = {
43
- :default_pipeline_workers => LogStash::Config::CpuCoreStrategy.maximum,
44
- :pipeline_batch_size => 125,
45
- :pipeline_batch_delay => 5, # in milliseconds
46
- :flush_interval => 5, # in seconds
47
- :flush_timeout_interval => 60, # in seconds
48
- :debug_config => false,
49
- :allow_env => false
50
- }
35
+ :settings
36
+ attr_accessor :metric
37
+
51
38
  MAX_INFLIGHT_WARN_THRESHOLD = 10_000
52
39
 
53
40
  RELOAD_INCOMPATIBLE_PLUGINS = [
54
41
  "LogStash::Inputs::Stdin"
55
42
  ]
56
43
 
57
- def initialize(config_str, settings = {})
44
+ def initialize(config_str, settings = LogStash::SETTINGS)
58
45
  @config_str = config_str
59
- @original_settings = settings
60
46
  @logger = Cabin::Channel.get(LogStash)
61
- @pipeline_id = settings[:pipeline_id] || self.object_id
62
- @settings = DEFAULT_SETTINGS.clone
63
- settings.each {|setting, value| configure(setting, value) }
47
+ @settings = settings
48
+ @pipeline_id = @settings.get_value("pipeline.id") || self.object_id
64
49
  @reporter = LogStash::PipelineReporter.new(@logger, self)
65
- @allow_env = settings[:allow_env]
66
50
 
67
51
  @inputs = nil
68
52
  @filters = nil
@@ -76,9 +60,11 @@ module LogStash; class Pipeline
76
60
  # We also do this to make the changes backward compatible with previous testing of the
77
61
  # pipeline.
78
62
  #
79
- # This need to be configured before we evaluate the code to make
63
+ # This needs to be configured before we evaluate the code to make
80
64
  # sure the metric instance is correctly send to the plugin.
81
- @metric = settings.fetch(:metric, Instrument::NullMetric.new)
65
+ # NOTE: It is the responsibility of the Agent to set this externally with a setter
66
+ # if there's an intent of this not being a NullMetric
67
+ @metric = Instrument::NullMetric.new
82
68
 
83
69
  grammar = LogStashConfigParser.new
84
70
  @config = grammar.parse(config_str)
@@ -94,7 +80,7 @@ module LogStash; class Pipeline
94
80
  # The config code is hard to represent as a log message...
95
81
  # So just print it.
96
82
 
97
- if @settings[:debug_config] && logger.debug?
83
+ if @settings.get("config.debug") && logger.debug?
98
84
  logger.debug("Compiled pipeline code", :code => code)
99
85
  end
100
86
 
@@ -123,38 +109,29 @@ module LogStash; class Pipeline
123
109
  @ready.value
124
110
  end
125
111
 
126
- def configure(setting, value)
127
- @settings[setting] = value
128
- end
129
-
130
112
  def safe_pipeline_worker_count
131
- default = DEFAULT_SETTINGS[:default_pipeline_workers]
132
- thread_count = @settings[:pipeline_workers] #override from args "-w 8" or config
113
+ default = @settings.get_default("pipeline.workers")
114
+ pipeline_workers = @settings.get("pipeline.workers") #override from args "-w 8" or config
133
115
  safe_filters, unsafe_filters = @filters.partition(&:threadsafe?)
116
+ plugins = unsafe_filters.collect { |f| f.config_name }
134
117
 
135
- if unsafe_filters.any?
136
- plugins = unsafe_filters.collect { |f| f.config_name }
137
- case thread_count
138
- when nil
139
- # user did not specify a worker thread count
140
- # warn if the default is multiple
141
-
142
- if default > 1
143
- @logger.warn("Defaulting pipeline worker threads to 1 because there are some filters that might not work with multiple worker threads",
144
- :count_was => default, :filters => plugins)
145
- end
118
+ return pipeline_workers if unsafe_filters.empty?
146
119
 
147
- 1 # can't allow the default value to propagate if there are unsafe filters
148
- when 0, 1
149
- 1
150
- else
120
+ if @settings.set?("pipeline.workers")
121
+ if pipeline_workers > 1
151
122
  @logger.warn("Warning: Manual override - there are filters that might not work with multiple worker threads",
152
- :worker_threads => thread_count, :filters => plugins)
153
- thread_count # allow user to force this even if there are unsafe filters
123
+ :worker_threads => pipeline_workers, :filters => plugins)
154
124
  end
155
125
  else
156
- thread_count || default
126
+ # user did not specify a worker thread count
127
+ # warn if the default is multiple
128
+ if default > 1
129
+ @logger.warn("Defaulting pipeline worker threads to 1 because there are some filters that might not work with multiple worker threads",
130
+ :count_was => default, :filters => plugins)
131
+ return 1 # can't allow the default value to propagate if there are unsafe filters
132
+ end
157
133
  end
134
+ pipeline_workers
158
135
  end
159
136
 
160
137
  def filters?
@@ -164,9 +141,8 @@ module LogStash; class Pipeline
164
141
  def run
165
142
  @started_at = Time.now
166
143
 
167
- LogStash::Util.set_thread_name("[#{pipeline_id}]-pipeline-manager")
168
- @logger.terminal(LogStash::Util::DefaultsPrinter.print(@settings))
169
144
  @thread = Thread.current
145
+ LogStash::Util.set_thread_name("[#{pipeline_id}]-pipeline-manager")
170
146
 
171
147
  start_workers
172
148
 
@@ -217,15 +193,15 @@ module LogStash; class Pipeline
217
193
  @filters.each {|f| f.register }
218
194
 
219
195
  pipeline_workers = safe_pipeline_worker_count
220
- batch_size = @settings[:pipeline_batch_size]
221
- batch_delay = @settings[:pipeline_batch_delay]
196
+ batch_size = @settings.get("pipeline.batch.size")
197
+ batch_delay = @settings.get("pipeline.batch.delay")
222
198
  max_inflight = batch_size * pipeline_workers
223
199
  @logger.info("Starting pipeline",
224
- :id => self.pipeline_id,
225
- :pipeline_workers => pipeline_workers,
226
- :batch_size => batch_size,
227
- :batch_delay => batch_delay,
228
- :max_inflight => max_inflight)
200
+ "id" => self.pipeline_id,
201
+ "pipeline.workers" => pipeline_workers,
202
+ "pipeline.batch.size" => batch_size,
203
+ "pipeline.batch.delay" => batch_delay,
204
+ "pipeline.max_inflight" => max_inflight)
229
205
  if max_inflight > MAX_INFLIGHT_WARN_THRESHOLD
230
206
  @logger.warn "CAUTION: Recommended inflight events max exceeded! Logstash will run with up to #{max_inflight} events in memory in your current configuration. If your message sizes are large this may cause instability with the default heap size. Please consider setting a non-standard heap size, changing the batch size (currently #{batch_size}), or changing the number of pipeline workers (currently #{pipeline_workers})"
231
207
  end
@@ -438,7 +414,7 @@ module LogStash; class Pipeline
438
414
  def shutdown_workers
439
415
  # Each worker thread will receive this exactly once!
440
416
  @worker_threads.each do |t|
441
- @logger.debug("Pushing shutdown", :thread => t)
417
+ @logger.debug("Pushing shutdown", :thread => t.inspect)
442
418
  @input_queue.push(LogStash::SHUTDOWN)
443
419
  end
444
420
 
@@ -453,14 +429,13 @@ module LogStash; class Pipeline
453
429
 
454
430
  def plugin(plugin_type, name, *args)
455
431
  args << {} if args.empty?
456
- args.first.merge!(LogStash::Config::Mixin::ALLOW_ENV_FLAG => @allow_env)
457
432
 
458
433
  pipeline_scoped_metric = metric.namespace([:stats, :pipelines, pipeline_id.to_s.to_sym, :plugins])
459
434
 
460
435
  klass = LogStash::Plugin.lookup(plugin_type, name)
461
436
 
462
437
  if plugin_type == "output"
463
- LogStash::OutputDelegator.new(@logger, klass, DEFAULT_OUTPUT_WORKERS, pipeline_scoped_metric.namespace(:outputs), *args)
438
+ LogStash::OutputDelegator.new(@logger, klass, @settings.get("pipeline.output.workers"), pipeline_scoped_metric.namespace(:outputs), *args)
464
439
  elsif plugin_type == "filter"
465
440
  LogStash::FilterDelegator.new(@logger, klass, pipeline_scoped_metric.namespace(:filters), *args)
466
441
  else
@@ -71,7 +71,7 @@ class LogStash::Plugin
71
71
  # close is called during shutdown, after the plugin worker
72
72
  # main task terminates
73
73
  def do_close
74
- @logger.debug("closing", :plugin => self)
74
+ @logger.debug("closing", :plugin => self.class.name)
75
75
  close
76
76
  end
77
77
 
@@ -3,7 +3,8 @@ Thread.abort_on_exception = true
3
3
  Encoding.default_external = Encoding::UTF_8
4
4
  $DEBUGLIST = (ENV["DEBUG"] || "").split(",")
5
5
 
6
- require "clamp" # gem 'clamp'
6
+ require "clamp"
7
+ require "cabin"
7
8
  require "net/http"
8
9
  require "logstash/environment"
9
10
 
@@ -12,135 +13,137 @@ LogStash::Environment.load_locale!
12
13
  require "logstash/namespace"
13
14
  require "logstash/agent"
14
15
  require "logstash/config/defaults"
16
+ require "logstash/shutdown_watcher"
17
+ require "logstash/patches/clamp"
15
18
 
16
- class LogStash::Runner < Clamp::Command
19
+ class LogStash::Runner < Clamp::StrictCommand
17
20
 
18
- option ["-f", "--config"], "CONFIG_PATH",
21
+ # Node Settings
22
+ option ["-n", "--node.name"], "NAME",
23
+ I18n.t("logstash.runner.flag.node_name"),
24
+ :attribute_name => "node.name",
25
+ :default => LogStash::SETTINGS.get_default("node.name")
26
+
27
+ # Config Settings
28
+ option ["-f", "--path.config"], "CONFIG_PATH",
19
29
  I18n.t("logstash.runner.flag.config"),
20
- :attribute_name => :config_path
30
+ :attribute_name => "path.config"
21
31
 
22
- option "-e", "CONFIG_STRING",
32
+ option ["-e", "--config.string"], "CONFIG_STRING",
23
33
  I18n.t("logstash.runner.flag.config-string",
24
- :default_input => LogStash::Config::Defaults.input,
25
- :default_output => LogStash::Config::Defaults.output),
26
- :default => nil, :attribute_name => :config_string
34
+ :default_input => LogStash::Config::Defaults.input,
35
+ :default_output => LogStash::Config::Defaults.output),
36
+ :default => LogStash::SETTINGS.get_default("config.string"),
37
+ :attribute_name => "config.string"
27
38
 
28
- option ["-w", "--pipeline-workers"], "COUNT",
39
+ # Pipeline settings
40
+ option ["-w", "--pipeline.workers"], "COUNT",
29
41
  I18n.t("logstash.runner.flag.pipeline-workers"),
30
- :attribute_name => :pipeline_workers,
31
- :default => LogStash::Pipeline::DEFAULT_SETTINGS[:default_pipeline_workers]
42
+ :attribute_name => "pipeline.workers",
43
+ :default => LogStash::SETTINGS.get_default("pipeline.workers"), &:to_i
44
+
45
+ option ["-b", "--pipeline.batch.size"], "SIZE",
46
+ I18n.t("logstash.runner.flag.pipeline-batch-size"),
47
+ :attribute_name => "pipeline.batch.size",
48
+ :default => LogStash::SETTINGS.get_default("pipeline.batch.size"), &:to_i
32
49
 
33
- option ["-b", "--pipeline-batch-size"], "SIZE",
34
- I18n.t("logstash.runner.flag.pipeline-batch-size"),
35
- :attribute_name => :pipeline_batch_size,
36
- :default => LogStash::Pipeline::DEFAULT_SETTINGS[:pipeline_batch_size]
50
+ option ["-u", "--pipeline.batch.delay"], "DELAY_IN_MS",
51
+ I18n.t("logstash.runner.flag.pipeline-batch-delay"),
52
+ :attribute_name => "pipeline.batch.delay",
53
+ :default => LogStash::SETTINGS.get_default("pipeline.batch.delay"), &:to_i
37
54
 
38
- option ["-u", "--pipeline-batch-delay"], "DELAY_IN_MS",
39
- I18n.t("logstash.runner.flag.pipeline-batch-delay"),
40
- :attribute_name => :pipeline_batch_delay,
41
- :default => LogStash::Pipeline::DEFAULT_SETTINGS[:pipeline_batch_delay]
55
+ option ["--pipeline.unsafe_shutdown"], :flag,
56
+ I18n.t("logstash.runner.flag.unsafe_shutdown"),
57
+ :attribute_name => "pipeline.unsafe_shutdown",
58
+ :default => LogStash::SETTINGS.get_default("pipeline.unsafe_shutdown")
59
+
60
+ # Plugins Settings
61
+ option ["-p", "--path.plugins"] , "PATH",
62
+ I18n.t("logstash.runner.flag.pluginpath"),
63
+ :multivalued => true, :attribute_name => "path.plugins",
64
+ :default => LogStash::SETTINGS.get_default("path.plugins")
42
65
 
43
- option ["-l", "--log"], "FILE",
66
+ # Logging Settings
67
+ option ["-l", "--path.log"], "FILE",
44
68
  I18n.t("logstash.runner.flag.log"),
45
- :attribute_name => :log_file
69
+ :attribute_name => "path.log"
46
70
 
47
- # Old support for the '-v' flag'
48
- option "-v", :flag,
49
- I18n.t("logstash.runner.flag.verbosity"),
50
- :attribute_name => :verbosity, :multivalued => true
71
+ option "--log.level", "LEVEL", I18n.t("logstash.runner.flag.log_level"),
72
+ :default => LogStash::SETTINGS.get_default("log.level")
51
73
 
52
- option "--quiet", :flag, I18n.t("logstash.runner.flag.quiet")
53
- option "--verbose", :flag, I18n.t("logstash.runner.flag.verbose")
54
- option "--debug", :flag, I18n.t("logstash.runner.flag.debug")
74
+ option "--config.debug", :flag,
75
+ I18n.t("logstash.runner.flag.config_debug"),
76
+ :default => LogStash::SETTINGS.get_default("config.debug"),
77
+ :attribute_name => "config.debug"
55
78
 
56
- option ["--debug-config"], :flag,
57
- I18n.t("logstash.runner.flag.debug_config"),
58
- :attribute_name => :debug_config, :default => false
79
+ # Other settings
80
+ option ["-i", "--interactive"], "SHELL",
81
+ I18n.t("logstash.runner.flag.rubyshell"),
82
+ :attribute_name => "interactive"
59
83
 
60
84
  option ["-V", "--version"], :flag,
61
85
  I18n.t("logstash.runner.flag.version")
62
86
 
63
- option ["-p", "--pluginpath"] , "PATH",
64
- I18n.t("logstash.runner.flag.pluginpath"),
65
- :multivalued => true,
66
- :attribute_name => :plugin_paths
67
-
68
- option ["-t", "--configtest"], :flag,
87
+ option ["-t", "--config.test_and_exit"], :flag,
69
88
  I18n.t("logstash.runner.flag.configtest"),
70
- :attribute_name => :config_test
71
-
72
- option "--[no-]allow-unsafe-shutdown", :flag,
73
- I18n.t("logstash.runner.flag.unsafe_shutdown"),
74
- :attribute_name => :unsafe_shutdown,
75
- :default => false
89
+ :attribute_name => "config.test_and_exit",
90
+ :default => LogStash::SETTINGS.get_default("config.test_and_exit")
76
91
 
77
- option ["-i", "--interactive"], "SHELL",
78
- I18n.t("logstash.runner.flag.rubyshell"),
79
- :attribute_name => :ruby_shell
80
-
81
- option ["-n", "--node-name"], "NAME",
82
- I18n.t("logstash.runner.flag.node_name"),
83
- :attribute_name => :node_name
84
-
85
- option ["-r", "--[no-]auto-reload"], :flag,
92
+ option ["-r", "--config.reload.automatic"], :flag,
86
93
  I18n.t("logstash.runner.flag.auto_reload"),
87
- :attribute_name => :auto_reload, :default => false
94
+ :attribute_name => "config.reload.automatic",
95
+ :default => LogStash::SETTINGS.get_default("config.reload.automatic")
88
96
 
89
- option ["--reload-interval"], "RELOAD_INTERVAL",
97
+ option ["--config.reload.interval"], "RELOAD_INTERVAL",
90
98
  I18n.t("logstash.runner.flag.reload_interval"),
91
- :attribute_name => :reload_interval, :default => 3, &:to_i
92
-
93
- option ["--http-host"], "WEB_API_HTTP_HOST",
94
- I18n.t("logstash.web_api.flag.http_host"),
95
- :attribute_name => :web_api_http_host, :default => "127.0.0.1"
99
+ :attribute_name => "config.reload.interval",
100
+ :default => LogStash::SETTINGS.get_default("config.reload.interval"), &:to_i
96
101
 
97
- option ["--http-port"], "WEB_API_HTTP_PORT",
98
- I18n.t("logstash.web_api.flag.http_port"),
99
- :attribute_name => :web_api_http_port, :default => 9600
100
-
101
- option ["--allow-env"], :flag,
102
- I18n.t("logstash.runner.flag.allow-env"),
103
- :attribute_name => :allow_env, :default => false
104
-
105
- def pipeline_workers=(pipeline_workers_value)
106
- @pipeline_settings[:pipeline_workers] = validate_positive_integer(pipeline_workers_value)
107
- end
108
-
109
- def pipeline_batch_size=(pipeline_batch_size_value)
110
- @pipeline_settings[:pipeline_batch_size] = validate_positive_integer(pipeline_batch_size_value)
111
- end
102
+ option ["--http.host"], "HTTP_HOST",
103
+ I18n.t("logstash.runner.flag.http_host"),
104
+ :attribute_name => "http.host",
105
+ :default => LogStash::SETTINGS.get_default("http.host")
112
106
 
113
- def pipeline_batch_delay=(pipeline_batch_delay_value)
114
- @pipeline_settings[:pipeline_batch_delay] = validate_positive_integer(pipeline_batch_delay_value)
115
- end
107
+ option ["--http.port"], "HTTP_PORT",
108
+ I18n.t("logstash.runner.flag.http_port"),
109
+ :attribute_name => "http.port",
110
+ :default => LogStash::SETTINGS.get_default("http.port"), &:to_i
116
111
 
117
- def validate_positive_integer(str_arg)
118
- int_arg = str_arg.to_i
119
- if str_arg !~ /^\d+$/ || int_arg < 1
120
- raise ArgumentError, "Expected a positive integer, got '#{str_arg}'"
121
- end
112
+ option ["--log.format"], "FORMAT",
113
+ I18n.t("logstash.runner.flag.log_format"),
114
+ :attribute_name => "log.format",
115
+ :default => LogStash::SETTINGS.get_default("log.format")
122
116
 
123
- int_arg
124
- end
117
+ option ["--path.settings"], "SETTINGS_DIR",
118
+ I18n.t("logstash.runner.flag.path_settings"),
119
+ :attribute_name => "path.settings",
120
+ :default => LogStash::SETTINGS.get_default("path.settings")
125
121
 
126
122
  attr_reader :agent
127
123
 
128
124
  def initialize(*args)
129
125
  @logger = Cabin::Channel.get(LogStash)
130
- @pipeline_settings ||= { :pipeline_id => "main" }
126
+ @settings = LogStash::SETTINGS
131
127
  super(*args)
132
128
  end
133
129
 
130
+ def run(args)
131
+ settings_path = fetch_settings_path(args)
132
+ @settings.set("path.settings", settings_path) if settings_path
133
+ LogStash::SETTINGS.from_yaml(LogStash::SETTINGS.get("path.settings"))
134
+ super(*[args])
135
+ end
136
+
134
137
  def execute
135
138
  require "logstash/util"
136
139
  require "logstash/util/java_version"
137
140
  require "stud/task"
138
141
  require "cabin" # gem 'cabin'
139
-
142
+ require "logstash/logging/json"
140
143
 
141
144
  # Configure Logstash logging facility, this need to be done before everything else to
142
145
  # make sure the logger has the correct settings and the log level is correctly defined.
143
- configure_logging(log_file)
146
+ configure_logging(setting("path.log"), setting("log.level"))
144
147
 
145
148
  LogStash::Util::set_thread_name(self.class.name)
146
149
 
@@ -149,33 +152,39 @@ class LogStash::Runner < Clamp::Command
149
152
  return 1
150
153
  end
151
154
 
152
- # Print a warning to STDERR for bad java versions
153
- LogStash::Util::JavaVersion.warn_on_bad_java_version
155
+ # Exit on bad java versions
156
+ java_version = LogStash::Util::JavaVersion.version
157
+ if LogStash::Util::JavaVersion.bad_java_version?(java_version)
158
+ $stderr.puts "Java version 1.8.0 or later is required. (You are running: #{java_version})"
159
+ return 1
160
+ end
154
161
 
155
- LogStash::ShutdownWatcher.unsafe_shutdown = unsafe_shutdown?
162
+ LogStash::ShutdownWatcher.unsafe_shutdown = setting("pipeline.unsafe_shutdown")
156
163
  LogStash::ShutdownWatcher.logger = @logger
157
164
 
158
- configure
165
+ configure_plugin_paths(setting("path.plugins"))
159
166
 
160
167
  if version?
161
168
  show_version
162
169
  return 0
163
170
  end
164
171
 
165
- return start_shell(@ruby_shell, binding) if @ruby_shell
172
+ return start_shell(setting("interactive"), binding) if setting("interactive")
173
+
174
+ @settings.format_settings.each {|line| @logger.info(line) }
166
175
 
167
- if config_string.nil? && config_path.nil?
176
+ if setting("config.string").nil? && setting("path.config").nil?
168
177
  fail(I18n.t("logstash.runner.missing-configuration"))
169
178
  end
170
179
 
171
- if @auto_reload && config_path.nil?
180
+ if setting("config.reload.automatic") && setting("path.config").nil?
172
181
  # there's nothing to reload
173
182
  signal_usage_error(I18n.t("logstash.runner.reload-without-config-path"))
174
183
  end
175
184
 
176
- if config_test?
177
- config_loader = LogStash::Config::Loader.new(@logger, @debug_config)
178
- config_str = config_loader.format_config(config_path, config_string)
185
+ if setting("config.test_and_exit")
186
+ config_loader = LogStash::Config::Loader.new(@logger)
187
+ config_str = config_loader.format_config(setting("path.config"), setting("config.string"))
179
188
  begin
180
189
  LogStash::Pipeline.new(config_str)
181
190
  @logger.terminal "Configuration OK"
@@ -186,22 +195,9 @@ class LogStash::Runner < Clamp::Command
186
195
  end
187
196
  end
188
197
 
189
- @agent = create_agent(:logger => @logger,
190
- :auto_reload => @auto_reload,
191
- :reload_interval => @reload_interval,
192
- :collect_metric => true,
193
- :debug => debug?,
194
- :node_name => node_name,
195
- :debug_config => debug_config?,
196
- :web_api_http_host => @web_api_http_host,
197
- :web_api_http_port => @web_api_http_port)
198
-
199
- @agent.register_pipeline("main", @pipeline_settings.merge({
200
- :config_string => config_string,
201
- :config_path => config_path,
202
- :debug_config => debug_config?,
203
- :allow_env => allow_env?
204
- }))
198
+ @agent = create_agent(@settings)
199
+
200
+ @agent.register_pipeline("main", @settings)
205
201
 
206
202
  # enable sigint/sigterm before starting the agent
207
203
  # to properly handle a stalled agent
@@ -236,10 +232,10 @@ class LogStash::Runner < Clamp::Command
236
232
  def show_version
237
233
  show_version_logstash
238
234
 
239
- if [:info, :debug].include?(verbosity?) || debug? || verbose?
235
+ if @logger.debug? || @logger.info?
240
236
  show_version_ruby
241
237
  show_version_java if LogStash::Environment.jruby?
242
- show_gems if [:debug].include?(verbosity?) || debug?
238
+ show_gems if @logger.debug?
243
239
  end
244
240
  end # def show_version
245
241
 
@@ -265,13 +261,6 @@ class LogStash::Runner < Clamp::Command
265
261
  end
266
262
  end # def show_gems
267
263
 
268
- # Do any start-time configuration.
269
- #
270
- # Log file stuff, plugin path checking, etc.
271
- def configure
272
- configure_plugin_paths(plugin_paths)
273
- end # def configure
274
-
275
264
  # add the given paths for ungemified/bare plugins lookups
276
265
  # @param paths [String, Array<String>] plugins path string or list of path strings to add
277
266
  def configure_plugin_paths(paths)
@@ -286,32 +275,21 @@ class LogStash::Runner < Clamp::Command
286
275
  end
287
276
 
288
277
  # Point logging at a specific path.
289
- def configure_logging(path)
278
+ def configure_logging(path, level)
290
279
  @logger = Cabin::Channel.get(LogStash)
291
280
  # Set with the -v (or -vv...) flag
292
- if quiet?
281
+ case level
282
+ when "quiet"
293
283
  @logger.level = :error
294
- elsif verbose?
284
+ when "verbose"
295
285
  @logger.level = :info
296
- elsif debug?
286
+ when "debug"
297
287
  @logger.level = :debug
298
288
  else
299
- # Old support for the -v and -vv stuff.
300
- if verbosity? && verbosity?.any?
301
- # this is an array with length of how many times the flag is given
302
- if verbosity?.length == 1
303
- @logger.warn("The -v flag is deprecated and will be removed in a future release. You should use --verbose instead.")
304
- @logger.level = :info
305
- else
306
- @logger.warn("The -vv flag is deprecated and will be removed in a future release. You should use --debug instead.")
307
- @logger.level = :debug
308
- end
309
- else
310
- @logger.level = :warn
311
- end
289
+ @logger.level = :warn
312
290
  end
313
291
 
314
- if log_file
292
+ if path
315
293
  # TODO(sissel): Implement file output/rotation in Cabin.
316
294
  # TODO(sissel): Catch exceptions, report sane errors.
317
295
  begin
@@ -322,15 +300,24 @@ class LogStash::Runner < Clamp::Command
322
300
  :path => path, :error => e))
323
301
  end
324
302
 
325
- @logger.subscribe(STDOUT, :level => :fatal)
326
- @logger.subscribe(@log_fd)
303
+ if setting("log.format") == "json"
304
+ @logger.subscribe(LogStash::Logging::JSON.new(STDOUT), :level => :fatal)
305
+ @logger.subscribe(LogStash::Logging::JSON.new(@log_fd))
306
+ else
307
+ @logger.subscribe(STDOUT, :level => :fatal)
308
+ @logger.subscribe(@log_fd)
309
+ end
327
310
  @logger.terminal "Sending logstash logs to #{path}."
328
311
  else
329
- @logger.subscribe(STDOUT)
312
+ if setting("log.format") == "json"
313
+ @logger.subscribe(LogStash::Logging::JSON.new(STDOUT))
314
+ else
315
+ @logger.subscribe(STDOUT)
316
+ end
330
317
  end
331
318
 
332
- if debug_config? && @logger.level != :debug
333
- @logger.warn("--debug-config was specified, but log level was not set to --debug! No config info will be logged.")
319
+ if setting("config.debug") && @logger.level != :debug
320
+ @logger.warn("--config.debug was specified, but log.level was not set to \'debug\'! No config info will be logged.")
334
321
  end
335
322
 
336
323
  # TODO(sissel): redirect stdout/stderr to the log as well
@@ -390,4 +377,26 @@ class LogStash::Runner < Clamp::Command
390
377
  end
391
378
  end
392
379
 
393
- end # class LogStash::Runner
380
+ def setting(key)
381
+ @settings.get_value(key)
382
+ end
383
+
384
+ # where can I find the logstash.yml file?
385
+ # 1. look for a "--path.settings path"
386
+ # 2. look for a "--path.settings=path"
387
+ # 3. check if the LS_SETTINGS_DIR environment variable is set
388
+ # 4. return nil if not found
389
+ def fetch_settings_path(cli_args)
390
+ if i=cli_args.find_index("--path.settings")
391
+ cli_args[i+1]
392
+ elsif settings_arg = cli_args.find {|v| v.match(/--path.settings=/) }
393
+ match = settings_arg.match(/--path.settings=(.*)/)
394
+ match[1]
395
+ elsif ENV['LS_SETTINGS_DIR']
396
+ ENV['LS_SETTINGS_DIR']
397
+ else
398
+ nil
399
+ end
400
+ end
401
+
402
+ end