logstash-core 5.0.0.alpha6.snapshot5-java → 5.0.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of logstash-core might be problematic. Click here for more details.
- checksums.yaml +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
|