logstash-core 5.0.0.alpha6.snapshot5-java → 5.0.0-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/jars.rb +1 -1
- data/lib/logstash-core/version.rb +1 -1
- data/lib/logstash/agent.rb +45 -11
- data/lib/logstash/api/app_helpers.rb +43 -7
- data/lib/logstash/api/commands/stats.rb +2 -1
- data/lib/logstash/api/errors.rb +28 -0
- data/lib/logstash/api/modules/base.rb +9 -7
- data/lib/logstash/api/modules/logging.rb +52 -0
- data/lib/logstash/api/modules/node.rb +13 -9
- data/lib/logstash/api/modules/root.rb +0 -2
- data/lib/logstash/api/modules/stats.rb +0 -2
- data/lib/logstash/api/rack_app.rb +5 -3
- data/lib/logstash/environment.rb +4 -5
- data/lib/logstash/instrument/collector.rb +4 -0
- data/lib/logstash/instrument/metric_store.rb +27 -2
- data/lib/logstash/logging/logger.rb +15 -4
- data/lib/logstash/patches/puma.rb +44 -0
- data/lib/logstash/pipeline.rb +8 -15
- data/lib/logstash/runner.rb +31 -17
- data/lib/logstash/settings.rb +34 -9
- data/lib/logstash/util/wrapped_synchronous_queue.rb +26 -9
- data/lib/logstash/version.rb +1 -1
- data/lib/logstash/webserver.rb +13 -2
- data/locales/en.yml +7 -2
- data/logstash-core.gemspec +1 -1
- data/spec/api/lib/api/logging_spec.rb +41 -0
- data/spec/api/lib/api/node_plugins_spec.rb +4 -3
- data/spec/api/lib/api/node_spec.rb +2 -0
- data/spec/api/lib/api/node_stats_spec.rb +2 -0
- data/spec/api/lib/api/plugins_spec.rb +3 -1
- data/spec/api/lib/api/root_spec.rb +3 -0
- data/spec/api/lib/errors_spec.rb +27 -0
- data/spec/api/lib/rack_app_spec.rb +4 -4
- data/spec/logstash/agent_spec.rb +112 -26
- data/spec/logstash/instrument/metric_store_spec.rb +37 -0
- data/spec/logstash/pipeline_spec.rb +54 -0
- data/spec/logstash/runner_spec.rb +2 -1
- data/spec/logstash/setting_spec.rb +23 -1
- data/spec/logstash/settings/string_spec.rb +1 -1
- data/spec/logstash/settings_spec.rb +27 -0
- data/spec/logstash/util/wrapped_synchronous_queue_spec.rb +49 -11
- data/spec/logstash/webserver_spec.rb +76 -18
- data/spec/support/helpers.rb +8 -0
- data/spec/support/mocks_classes.rb +22 -0
- data/spec/support/shared_examples.rb +10 -0
- data/vendor/jars/org/logstash/logstash-core/{5.0.0-alpha6/logstash-core-5.0.0-alpha6.jar → 5.0.0/logstash-core-5.0.0.jar} +0 -0
- metadata +16 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 580f202da437b439172ac7d75a2040fe78b5b2f5
|
4
|
+
data.tar.gz: 5a33bf37b1e0d52b16d71e996bae012f02cbe7d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 77708d863472390ae13396223803caa3aa95392a6755811e3d8b5e14085d84904712f97e2dc9911bfc675edfca9c67c0d28a57a2fc92449791d2cc5826d4eec0
|
7
|
+
data.tar.gz: ba5fa135b749b89e3f908b39d4381c45dcb004b3a1c8763cdf94339fc710e6bb3efc17a6c9ff65611cea88d2901d093986c0aaea45d59dd7f8c1b1bdc6b4947e
|
data/lib/jars.rb
CHANGED
@@ -4,4 +4,4 @@ require_jar('org.apache.logging.log4j', 'log4j-api', '2.6.2')
|
|
4
4
|
require_jar('org.apache.logging.log4j', 'log4j-core', '2.6.2')
|
5
5
|
require_jar('com.fasterxml.jackson.core', 'jackson-core', '2.7.4')
|
6
6
|
require_jar('com.fasterxml.jackson.core', 'jackson-databind', '2.7.4')
|
7
|
-
require_jar('org.logstash', 'logstash-core', '5.0.0
|
7
|
+
require_jar('org.logstash', 'logstash-core', '5.0.0')
|
data/lib/logstash/agent.rb
CHANGED
@@ -48,11 +48,13 @@ class LogStash::Agent
|
|
48
48
|
|
49
49
|
# Create the collectors and configured it with the library
|
50
50
|
configure_metrics_collectors
|
51
|
+
|
52
|
+
@reload_metric = metric.namespace([:stats, :pipelines])
|
51
53
|
end
|
52
54
|
|
53
55
|
def execute
|
54
56
|
@thread = Thread.current # this var is implicilty used by Stud.stop?
|
55
|
-
@logger.
|
57
|
+
@logger.debug("starting agent")
|
56
58
|
|
57
59
|
start_pipelines
|
58
60
|
start_webserver
|
@@ -99,6 +101,11 @@ class LogStash::Agent
|
|
99
101
|
begin
|
100
102
|
reload_pipeline!(pipeline_id)
|
101
103
|
rescue => e
|
104
|
+
@reload_metric.namespace([pipeline_id.to_sym, :reloads]).tap do |n|
|
105
|
+
n.increment(:failures)
|
106
|
+
n.gauge(:last_error, { :message => e.message, :backtrace => e.backtrace})
|
107
|
+
n.gauge(:last_failure_timestamp, LogStash::Timestamp.now)
|
108
|
+
end
|
102
109
|
@logger.error(I18n.t("oops"), :message => e.message, :class => e.class.name, :backtrace => e.backtrace)
|
103
110
|
end
|
104
111
|
end
|
@@ -162,9 +169,12 @@ class LogStash::Agent
|
|
162
169
|
@periodic_pollers.start
|
163
170
|
end
|
164
171
|
|
165
|
-
def
|
166
|
-
|
167
|
-
|
172
|
+
def reset_pipeline_metrics(id)
|
173
|
+
# selectively reset metrics we don't wish to keep after reloading
|
174
|
+
# these include metrics about the plugins and number of processed events
|
175
|
+
# we want to keep other metrics like reload counts and error messages
|
176
|
+
@collector.clear("stats/pipelines/#{id}/plugins")
|
177
|
+
@collector.clear("stats/pipelines/#{id}/events")
|
168
178
|
end
|
169
179
|
|
170
180
|
def collect_metrics?
|
@@ -184,6 +194,11 @@ class LogStash::Agent
|
|
184
194
|
begin
|
185
195
|
LogStash::Pipeline.new(config, settings, metric)
|
186
196
|
rescue => e
|
197
|
+
@reload_metric.namespace([settings.get("pipeline.id").to_sym, :reloads]).tap do |n|
|
198
|
+
n.increment(:failures)
|
199
|
+
n.gauge(:last_error, { :message => e.message, :backtrace => e.backtrace})
|
200
|
+
n.gauge(:last_failure_timestamp, LogStash::Timestamp.now)
|
201
|
+
end
|
187
202
|
if @logger.debug?
|
188
203
|
@logger.error("fetched an invalid config", :config => config, :reason => e.message, :backtrace => e.backtrace)
|
189
204
|
else
|
@@ -208,11 +223,6 @@ class LogStash::Agent
|
|
208
223
|
return
|
209
224
|
end
|
210
225
|
|
211
|
-
# Reset the current collected stats,
|
212
|
-
# starting a pipeline with a new configuration should be the same as restarting
|
213
|
-
# logstash.
|
214
|
-
reset_metrics_collectors
|
215
|
-
|
216
226
|
new_pipeline = create_pipeline(old_pipeline.settings, new_config)
|
217
227
|
|
218
228
|
return if new_pipeline.nil?
|
@@ -233,12 +243,17 @@ class LogStash::Agent
|
|
233
243
|
pipeline = @pipelines[id]
|
234
244
|
return unless pipeline.is_a?(LogStash::Pipeline)
|
235
245
|
return if pipeline.ready?
|
236
|
-
@logger.
|
246
|
+
@logger.debug("starting pipeline", :id => id)
|
237
247
|
Thread.new do
|
238
248
|
LogStash::Util.set_thread_name("pipeline.#{id}")
|
239
249
|
begin
|
240
250
|
pipeline.run
|
241
251
|
rescue => e
|
252
|
+
@reload_metric.namespace([id.to_sym, :reloads]) do |n|
|
253
|
+
n.increment(:failures)
|
254
|
+
n.gauge(:last_error, { :message => e.message, :backtrace => e.backtrace})
|
255
|
+
n.gauge(:last_failure_timestamp, LogStash::Timestamp.now)
|
256
|
+
end
|
242
257
|
@logger.error("Pipeline aborted due to error", :exception => e, :backtrace => e.backtrace)
|
243
258
|
end
|
244
259
|
end
|
@@ -254,7 +269,11 @@ class LogStash::Agent
|
|
254
269
|
end
|
255
270
|
|
256
271
|
def start_pipelines
|
257
|
-
@pipelines.each
|
272
|
+
@pipelines.each do |id, _|
|
273
|
+
start_pipeline(id)
|
274
|
+
# no reloads yet, initalize all the reload metrics
|
275
|
+
init_pipeline_reload_metrics(id)
|
276
|
+
end
|
258
277
|
end
|
259
278
|
|
260
279
|
def shutdown_pipelines
|
@@ -268,8 +287,13 @@ class LogStash::Agent
|
|
268
287
|
|
269
288
|
def upgrade_pipeline(pipeline_id, new_pipeline)
|
270
289
|
stop_pipeline(pipeline_id)
|
290
|
+
reset_pipeline_metrics(pipeline_id)
|
271
291
|
@pipelines[pipeline_id] = new_pipeline
|
272
292
|
start_pipeline(pipeline_id)
|
293
|
+
@reload_metric.namespace([pipeline_id.to_sym, :reloads]).tap do |n|
|
294
|
+
n.increment(:successes)
|
295
|
+
n.gauge(:last_success_timestamp, LogStash::Timestamp.now)
|
296
|
+
end
|
273
297
|
end
|
274
298
|
|
275
299
|
def clean_state?
|
@@ -279,4 +303,14 @@ class LogStash::Agent
|
|
279
303
|
def setting(key)
|
280
304
|
@settings.get(key)
|
281
305
|
end
|
306
|
+
|
307
|
+
def init_pipeline_reload_metrics(id)
|
308
|
+
@reload_metric.namespace([id.to_sym, :reloads]).tap do |n|
|
309
|
+
n.increment(:successes, 0)
|
310
|
+
n.increment(:failures, 0)
|
311
|
+
n.gauge(:last_error, nil)
|
312
|
+
n.gauge(:last_success_timestamp, nil)
|
313
|
+
n.gauge(:last_failure_timestamp, nil)
|
314
|
+
end
|
315
|
+
end
|
282
316
|
end # class LogStash::Agent
|
@@ -1,27 +1,43 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require "logstash/json"
|
3
|
+
require "logstash/api/errors"
|
3
4
|
|
4
5
|
module LogStash::Api::AppHelpers
|
5
|
-
|
6
|
+
# This method handle both of the normal flow *happy path*
|
7
|
+
# and the display or errors, if more custom logic is added here
|
8
|
+
# it will make sense to separate them.
|
9
|
+
#
|
10
|
+
# See `#error` method in the `LogStash::Api::Module::Base`
|
6
11
|
def respond_with(data, options={})
|
7
12
|
as = options.fetch(:as, :json)
|
8
13
|
filter = options.fetch(:filter, "")
|
9
|
-
|
14
|
+
|
15
|
+
status data.respond_to?(:status_code) ? data.status_code : 200
|
10
16
|
|
11
17
|
if as == :json
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
18
|
+
if api_error?(data)
|
19
|
+
data = generate_error_hash(data)
|
20
|
+
else
|
21
|
+
selected_fields = extract_fields(filter.to_s.strip)
|
22
|
+
data.select! { |k,v| selected_fields.include?(k) } unless selected_fields.empty?
|
23
|
+
unless options.include?(:exclude_default_metadata)
|
24
|
+
data = data.to_hash
|
25
|
+
if data.values.size == 0 && selected_fields.size > 0
|
26
|
+
raise LogStash::Api::NotFoundError
|
27
|
+
end
|
28
|
+
data = default_metadata.merge(data)
|
29
|
+
end
|
16
30
|
end
|
31
|
+
|
17
32
|
content_type "application/json"
|
18
|
-
LogStash::Json.dump(data, {:pretty => pretty})
|
33
|
+
LogStash::Json.dump(data, {:pretty => pretty?})
|
19
34
|
else
|
20
35
|
content_type "text/plain"
|
21
36
|
data.to_s
|
22
37
|
end
|
23
38
|
end
|
24
39
|
|
40
|
+
protected
|
25
41
|
def extract_fields(filter_string)
|
26
42
|
(filter_string.empty? ? [] : filter_string.split(",").map { |s| s.strip.to_sym })
|
27
43
|
end
|
@@ -35,4 +51,24 @@ module LogStash::Api::AppHelpers
|
|
35
51
|
def default_metadata
|
36
52
|
@factory.build(:default_metadata).all
|
37
53
|
end
|
54
|
+
|
55
|
+
def api_error?(error)
|
56
|
+
error.is_a?(LogStash::Api::ApiError)
|
57
|
+
end
|
58
|
+
|
59
|
+
def pretty?
|
60
|
+
params.has_key?("pretty")
|
61
|
+
end
|
62
|
+
|
63
|
+
def generate_error_hash(error)
|
64
|
+
{
|
65
|
+
:path => request.path,
|
66
|
+
:status => error.status_code,
|
67
|
+
:error => error.to_hash
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
def human?
|
72
|
+
params.has_key?("human") && (params["human"].nil? || as_boolean(params["human"]) == true)
|
73
|
+
end
|
38
74
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module LogStash
|
3
|
+
module Api
|
4
|
+
class ApiError < StandardError;
|
5
|
+
def initialize(message = nil)
|
6
|
+
super(message || "Api Error")
|
7
|
+
end
|
8
|
+
|
9
|
+
def status_code
|
10
|
+
500
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_hash
|
14
|
+
{ :message => to_s }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class NotFoundError < ApiError
|
19
|
+
def initialize
|
20
|
+
super("Not Found")
|
21
|
+
end
|
22
|
+
|
23
|
+
def status_code
|
24
|
+
404
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -1,11 +1,13 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require "logstash/api/app_helpers"
|
3
3
|
require "logstash/api/command_factory"
|
4
|
+
require "logstash/api/errors"
|
4
5
|
|
5
6
|
module LogStash
|
6
7
|
module Api
|
7
8
|
module Modules
|
8
9
|
class Base < ::Sinatra::Base
|
10
|
+
|
9
11
|
helpers AppHelpers
|
10
12
|
|
11
13
|
# These options never change
|
@@ -29,15 +31,15 @@ module LogStash
|
|
29
31
|
end
|
30
32
|
|
31
33
|
not_found do
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
respond_with(text, :as => as)
|
34
|
+
# We cannot raise here because it wont be catched by the `error` handler.
|
35
|
+
# So we manually create a new instance of NotFound and just pass it down.
|
36
|
+
respond_with(NotFoundError.new)
|
36
37
|
end
|
37
38
|
|
38
|
-
|
39
|
-
|
40
|
-
|
39
|
+
# This allow to have custom exception but keep a consistent
|
40
|
+
# format to report them.
|
41
|
+
error ApiError do |error|
|
42
|
+
respond_with(error)
|
41
43
|
end
|
42
44
|
end
|
43
45
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
java_import org.apache.logging.log4j.core.LoggerContext
|
4
|
+
|
5
|
+
module LogStash
|
6
|
+
module Api
|
7
|
+
module Modules
|
8
|
+
class Logging < ::LogStash::Api::Modules::Base
|
9
|
+
# retrieve logging specific parameters from the provided settings
|
10
|
+
#
|
11
|
+
# return any unused configurations
|
12
|
+
def handle_logging(settings)
|
13
|
+
Hash[settings.map do |key, level|
|
14
|
+
if key.start_with?("logger.")
|
15
|
+
_, path = key.split("logger.")
|
16
|
+
LogStash::Logging::Logger::configure_logging(level, path)
|
17
|
+
nil
|
18
|
+
else
|
19
|
+
[key, level]
|
20
|
+
end
|
21
|
+
end]
|
22
|
+
end
|
23
|
+
|
24
|
+
put "/" do
|
25
|
+
begin
|
26
|
+
request.body.rewind
|
27
|
+
req_body = LogStash::Json.load(request.body.read)
|
28
|
+
remaining = handle_logging(req_body)
|
29
|
+
unless remaining.empty?
|
30
|
+
raise ArgumentError, I18n.t("logstash.web_api.logging.unrecognized_option", :option => remaining.keys.first)
|
31
|
+
end
|
32
|
+
respond_with({"acknowledged" => true})
|
33
|
+
rescue ArgumentError => e
|
34
|
+
status 400
|
35
|
+
respond_with({"error" => e.message})
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
get "/" do
|
40
|
+
context = LogStash::Logging::Logger::get_logging_context
|
41
|
+
if context.nil?
|
42
|
+
status 500
|
43
|
+
respond_with({"error" => "Logstash loggers were not initialized properly"})
|
44
|
+
else
|
45
|
+
loggers = context.getLoggers.map { |lgr| [lgr.getName, lgr.getLevel.name] }.sort
|
46
|
+
respond_with({"loggers" => Hash[loggers]})
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require "logstash/api/modules/base"
|
3
|
+
require "logstash/api/errors"
|
3
4
|
|
4
5
|
module LogStash
|
5
6
|
module Api
|
@@ -12,20 +13,23 @@ module LogStash
|
|
12
13
|
get "/hot_threads" do
|
13
14
|
ignore_idle_threads = params["ignore_idle_threads"] || true
|
14
15
|
|
15
|
-
options = {
|
16
|
-
:ignore_idle_threads => as_boolean(ignore_idle_threads),
|
17
|
-
:human => human?
|
18
|
-
}
|
16
|
+
options = { :ignore_idle_threads => as_boolean(ignore_idle_threads) }
|
19
17
|
options[:threads] = params["threads"].to_i if params.has_key?("threads")
|
20
18
|
|
21
|
-
as =
|
19
|
+
as = human? ? :string : :json
|
22
20
|
respond_with(node.hot_threads(options), {:as => as})
|
23
21
|
end
|
24
22
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
23
|
+
get "/?:filter?" do
|
24
|
+
selected_fields = extract_fields(params["filter"].to_s.strip)
|
25
|
+
values = node.all(selected_fields)
|
26
|
+
|
27
|
+
if values.size == 0
|
28
|
+
raise NotFoundError
|
29
|
+
else
|
30
|
+
respond_with(values)
|
31
|
+
end
|
32
|
+
end
|
29
33
|
end
|
30
34
|
end
|
31
35
|
end
|
@@ -3,7 +3,6 @@ module LogStash
|
|
3
3
|
module Api
|
4
4
|
module Modules
|
5
5
|
class Stats < ::LogStash::Api::Modules::Base
|
6
|
-
|
7
6
|
def stats_command
|
8
7
|
factory.build(:stats)
|
9
8
|
end
|
@@ -36,7 +35,6 @@ module LogStash
|
|
36
35
|
}
|
37
36
|
respond_with(payload, {:filter => params["filter"]})
|
38
37
|
end
|
39
|
-
|
40
38
|
end
|
41
39
|
end
|
42
40
|
end
|
@@ -5,6 +5,7 @@ require "logstash/api/modules/node"
|
|
5
5
|
require "logstash/api/modules/node_stats"
|
6
6
|
require "logstash/api/modules/plugins"
|
7
7
|
require "logstash/api/modules/root"
|
8
|
+
require "logstash/api/modules/logging"
|
8
9
|
require "logstash/api/modules/stats"
|
9
10
|
|
10
11
|
module LogStash
|
@@ -31,9 +32,9 @@ module LogStash
|
|
31
32
|
status, headers, body = res
|
32
33
|
|
33
34
|
if fatal_error?(status)
|
34
|
-
@logger.
|
35
|
+
@logger.error? && @logger.error(LOG_MESSAGE, RackApp.log_metadata(status, env))
|
35
36
|
else
|
36
|
-
@logger.
|
37
|
+
@logger.debug? && @logger.debug(LOG_MESSAGE, RackApp.log_metadata(status, env))
|
37
38
|
end
|
38
39
|
|
39
40
|
res
|
@@ -103,7 +104,8 @@ module LogStash
|
|
103
104
|
"/_node" => LogStash::Api::Modules::Node,
|
104
105
|
"/_stats" => LogStash::Api::Modules::Stats,
|
105
106
|
"/_node/stats" => LogStash::Api::Modules::NodeStats,
|
106
|
-
"/_node/plugins" => LogStash::Api::Modules::Plugins
|
107
|
+
"/_node/plugins" => LogStash::Api::Modules::Plugins,
|
108
|
+
"/_node/logging" => LogStash::Api::Modules::Logging
|
107
109
|
}
|
108
110
|
end
|
109
111
|
end
|