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.
- checksums.yaml +4 -4
- data/lib/logstash-core/version.rb +1 -1
- data/lib/logstash/agent.rb +49 -31
- data/lib/logstash/api/init.ru +3 -3
- data/lib/logstash/api/lib/app/service.rb +1 -1
- data/lib/logstash/config/config_ast.rb +23 -18
- data/lib/logstash/config/loader.rb +4 -4
- data/lib/logstash/config/mixin.rb +10 -21
- data/lib/logstash/environment.rb +30 -0
- data/lib/logstash/filters/base.rb +2 -2
- data/lib/logstash/inputs/base.rb +2 -2
- data/lib/logstash/instrument/collector.rb +1 -1
- data/lib/logstash/logging/json.rb +21 -0
- data/lib/logstash/output_delegator.rb +2 -2
- data/lib/logstash/patches/clamp.rb +69 -0
- data/lib/logstash/pipeline.rb +37 -62
- data/lib/logstash/plugin.rb +1 -1
- data/lib/logstash/runner.rb +155 -146
- data/lib/logstash/settings.rb +267 -0
- data/lib/logstash/util/decorators.rb +6 -6
- data/lib/logstash/util/java_version.rb +1 -10
- data/lib/logstash/util/worker_threads_default_printer.rb +2 -2
- data/lib/logstash/version.rb +1 -1
- data/locales/en.yml +17 -20
- data/logstash-core.gemspec +1 -1
- data/spec/api/spec_helper.rb +15 -16
- data/spec/conditionals_spec.rb +113 -113
- data/spec/logstash/agent_spec.rb +77 -68
- data/spec/logstash/config/config_ast_spec.rb +4 -2
- data/spec/logstash/config/mixin_spec.rb +33 -7
- data/spec/logstash/filters/base_spec.rb +16 -16
- data/spec/logstash/inputs/base_spec.rb +8 -8
- data/spec/logstash/output_delegator_spec.rb +2 -0
- data/spec/logstash/pipeline_spec.rb +60 -26
- data/spec/logstash/plugin_spec.rb +2 -2
- data/spec/logstash/runner_spec.rb +112 -25
- data/spec/logstash/setting_spec.rb +130 -0
- data/spec/logstash/settings_spec.rb +62 -0
- metadata +11 -9
- data/lib/logstash/util/defaults_printer.rb +0 -31
- data/spec/logstash/util/defaults_printer_spec.rb +0 -50
- 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
|
+
|
data/lib/logstash/pipeline.rb
CHANGED
@@ -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
|
-
|
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
|
-
:
|
39
|
-
|
40
|
-
|
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
|
-
@
|
62
|
-
@
|
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
|
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
|
-
|
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
|
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 =
|
132
|
-
|
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.
|
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
|
-
|
148
|
-
|
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 =>
|
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
|
-
|
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
|
221
|
-
batch_delay = @settings
|
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
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
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,
|
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
|
data/lib/logstash/plugin.rb
CHANGED
data/lib/logstash/runner.rb
CHANGED
@@ -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"
|
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::
|
19
|
+
class LogStash::Runner < Clamp::StrictCommand
|
17
20
|
|
18
|
-
|
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 =>
|
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
|
-
|
25
|
-
|
26
|
-
:default =>
|
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
|
-
|
39
|
+
# Pipeline settings
|
40
|
+
option ["-w", "--pipeline.workers"], "COUNT",
|
29
41
|
I18n.t("logstash.runner.flag.pipeline-workers"),
|
30
|
-
:attribute_name =>
|
31
|
-
:default => LogStash::
|
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 ["-
|
34
|
-
|
35
|
-
|
36
|
-
|
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 ["
|
39
|
-
|
40
|
-
|
41
|
-
|
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
|
-
|
66
|
+
# Logging Settings
|
67
|
+
option ["-l", "--path.log"], "FILE",
|
44
68
|
I18n.t("logstash.runner.flag.log"),
|
45
|
-
:attribute_name =>
|
69
|
+
:attribute_name => "path.log"
|
46
70
|
|
47
|
-
|
48
|
-
|
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 "--
|
53
|
-
|
54
|
-
|
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
|
-
|
57
|
-
|
58
|
-
|
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 ["-
|
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 =>
|
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 ["-
|
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 =>
|
94
|
+
:attribute_name => "config.reload.automatic",
|
95
|
+
:default => LogStash::SETTINGS.get_default("config.reload.automatic")
|
88
96
|
|
89
|
-
option ["--reload
|
97
|
+
option ["--config.reload.interval"], "RELOAD_INTERVAL",
|
90
98
|
I18n.t("logstash.runner.flag.reload_interval"),
|
91
|
-
:attribute_name =>
|
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
|
98
|
-
I18n.t("logstash.
|
99
|
-
:attribute_name =>
|
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
|
-
|
114
|
-
|
115
|
-
|
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
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
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
|
-
|
124
|
-
|
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
|
-
@
|
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(
|
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
|
-
#
|
153
|
-
LogStash::Util::JavaVersion.
|
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
|
-
|
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(
|
172
|
+
return start_shell(setting("interactive"), binding) if setting("interactive")
|
173
|
+
|
174
|
+
@settings.format_settings.each {|line| @logger.info(line) }
|
166
175
|
|
167
|
-
if
|
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
|
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
|
177
|
-
config_loader = LogStash::Config::Loader.new(@logger
|
178
|
-
config_str = config_loader.format_config(
|
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(
|
190
|
-
|
191
|
-
|
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
|
235
|
+
if @logger.debug? || @logger.info?
|
240
236
|
show_version_ruby
|
241
237
|
show_version_java if LogStash::Environment.jruby?
|
242
|
-
show_gems if
|
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
|
-
|
281
|
+
case level
|
282
|
+
when "quiet"
|
293
283
|
@logger.level = :error
|
294
|
-
|
284
|
+
when "verbose"
|
295
285
|
@logger.level = :info
|
296
|
-
|
286
|
+
when "debug"
|
297
287
|
@logger.level = :debug
|
298
288
|
else
|
299
|
-
|
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
|
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
|
-
|
326
|
-
|
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
|
-
|
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
|
333
|
-
@logger.warn("--debug
|
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
|
-
|
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
|