logstash-core 5.0.0.alpha2.snapshot2-java → 5.0.0.alpha3-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 (86) hide show
  1. checksums.yaml +4 -4
  2. data/lib/logstash-core/version.rb +1 -1
  3. data/lib/logstash/agent.rb +48 -31
  4. data/lib/logstash/api/{lib/helpers/app_helpers.rb → app_helpers.rb} +0 -0
  5. data/lib/logstash/api/command_factory.rb +34 -0
  6. data/lib/logstash/api/commands/base.rb +25 -0
  7. data/lib/logstash/api/commands/stats.rb +105 -0
  8. data/lib/logstash/api/commands/system/basicinfo_command.rb +23 -0
  9. data/lib/logstash/api/commands/system/plugins_command.rb +35 -0
  10. data/lib/logstash/api/modules/base.rb +43 -0
  11. data/lib/logstash/api/modules/node.rb +24 -0
  12. data/lib/logstash/api/modules/node_stats.rb +59 -0
  13. data/lib/logstash/api/modules/plugins.rb +15 -0
  14. data/lib/logstash/api/modules/root.rb +15 -0
  15. data/lib/logstash/api/modules/stats.rb +63 -0
  16. data/lib/logstash/api/rack_app.rb +33 -0
  17. data/lib/logstash/api/service.rb +73 -0
  18. data/lib/logstash/config/config_ast.rb +23 -18
  19. data/lib/logstash/config/loader.rb +4 -4
  20. data/lib/logstash/config/mixin.rb +10 -21
  21. data/lib/logstash/environment.rb +29 -0
  22. data/lib/logstash/filters/base.rb +2 -2
  23. data/lib/logstash/inputs/base.rb +2 -2
  24. data/lib/logstash/instrument/collector.rb +1 -1
  25. data/lib/logstash/instrument/metric_store.rb +11 -1
  26. data/lib/logstash/instrument/periodic_poller/base.rb +2 -0
  27. data/lib/logstash/instrument/periodic_poller/jvm.rb +47 -2
  28. data/lib/logstash/logging/json.rb +21 -0
  29. data/lib/logstash/output_delegator.rb +2 -2
  30. data/lib/logstash/patches/clamp.rb +69 -0
  31. data/lib/logstash/pipeline.rb +36 -69
  32. data/lib/logstash/plugin.rb +1 -1
  33. data/lib/logstash/runner.rb +171 -146
  34. data/lib/logstash/settings.rb +267 -0
  35. data/lib/logstash/util/decorators.rb +6 -6
  36. data/lib/logstash/util/java_version.rb +1 -10
  37. data/lib/logstash/util/thread_dump.rb +55 -0
  38. data/lib/logstash/util/worker_threads_default_printer.rb +2 -2
  39. data/lib/logstash/version.rb +1 -1
  40. data/lib/logstash/webserver.rb +15 -49
  41. data/locales/en.yml +22 -25
  42. data/logstash-core.gemspec +3 -3
  43. data/spec/api/lib/api/node_spec.rb +2 -2
  44. data/spec/api/lib/api/node_stats_spec.rb +32 -57
  45. data/spec/api/lib/api/plugins_spec.rb +3 -3
  46. data/spec/api/lib/api/root_spec.rb +2 -2
  47. data/spec/api/lib/api/support/resource_dsl_methods.rb +47 -0
  48. data/spec/api/lib/commands/stats.rb +47 -0
  49. data/spec/api/spec_helper.rb +21 -21
  50. data/spec/conditionals_spec.rb +113 -113
  51. data/spec/logstash/agent_spec.rb +85 -68
  52. data/spec/logstash/config/config_ast_spec.rb +4 -2
  53. data/spec/logstash/config/mixin_spec.rb +33 -7
  54. data/spec/logstash/filters/base_spec.rb +16 -16
  55. data/spec/logstash/inputs/base_spec.rb +8 -8
  56. data/spec/logstash/instrument/periodic_poller/jvm_spec.rb +45 -0
  57. data/spec/logstash/output_delegator_spec.rb +2 -0
  58. data/spec/logstash/pipeline_reporter_spec.rb +5 -1
  59. data/spec/logstash/pipeline_spec.rb +75 -30
  60. data/spec/logstash/plugin_spec.rb +2 -2
  61. data/spec/logstash/runner_spec.rb +112 -25
  62. data/spec/logstash/setting_spec.rb +130 -0
  63. data/spec/logstash/settings_spec.rb +62 -0
  64. metadata +37 -43
  65. data/lib/logstash/api/init.ru +0 -31
  66. data/lib/logstash/api/lib/app.rb +0 -40
  67. data/lib/logstash/api/lib/app/command.rb +0 -29
  68. data/lib/logstash/api/lib/app/command_factory.rb +0 -29
  69. data/lib/logstash/api/lib/app/commands/stats/events_command.rb +0 -13
  70. data/lib/logstash/api/lib/app/commands/stats/hotthreads_command.rb +0 -120
  71. data/lib/logstash/api/lib/app/commands/stats/memory_command.rb +0 -25
  72. data/lib/logstash/api/lib/app/commands/system/basicinfo_command.rb +0 -15
  73. data/lib/logstash/api/lib/app/commands/system/plugins_command.rb +0 -28
  74. data/lib/logstash/api/lib/app/modules/node.rb +0 -25
  75. data/lib/logstash/api/lib/app/modules/node_stats.rb +0 -51
  76. data/lib/logstash/api/lib/app/modules/plugins.rb +0 -15
  77. data/lib/logstash/api/lib/app/modules/stats.rb +0 -21
  78. data/lib/logstash/api/lib/app/root.rb +0 -13
  79. data/lib/logstash/api/lib/app/service.rb +0 -61
  80. data/lib/logstash/api/lib/app/stats.rb +0 -56
  81. data/lib/logstash/util/defaults_printer.rb +0 -31
  82. data/spec/api/lib/api/stats_spec.rb +0 -19
  83. data/spec/api/lib/commands/events_spec.rb +0 -17
  84. data/spec/api/lib/commands/jvm_spec.rb +0 -45
  85. data/spec/logstash/util/defaults_printer_spec.rb +0 -50
  86. data/spec/logstash/util/worker_threads_default_printer_spec.rb +0 -45
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ module LogStash
3
+ module Api
4
+ module Modules
5
+ class Node < ::LogStash::Api::Modules::Base
6
+ # return hot threads information
7
+ get "/hot_threads" do
8
+ ignore_idle_threads = params["ignore_idle_threads"] || true
9
+
10
+ options = {
11
+ :ignore_idle_threads => as_boolean(ignore_idle_threads),
12
+ :human => params.has_key?("human")
13
+ }
14
+ options[:threads] = params["threads"].to_i if params.has_key?("threads")
15
+
16
+ stats = factory.build(:stats)
17
+ as = options[:human] ? :string : :json
18
+ respond_with(stats.hot_threads(options), {:as => as})
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,59 @@
1
+ # encoding: utf-8
2
+ module LogStash
3
+ module Api
4
+ module Modules
5
+ class NodeStats < ::LogStash::Api::Modules::Base
6
+
7
+ before do
8
+ @stats = factory.build(:stats)
9
+ end
10
+
11
+ # Global _stats resource where all information is
12
+ # retrieved and show
13
+ get "/" do
14
+ payload = {
15
+ :events => events_payload,
16
+ :jvm => jvm_payload,
17
+ :process => process_payload
18
+ }
19
+
20
+ respond_with payload
21
+ end
22
+
23
+ # Show all events stats information
24
+ # (for ingested, emitted, dropped)
25
+ # - #events since startup
26
+ # - #data (bytes) since startup
27
+ # - events/s
28
+ # - bytes/s
29
+ # - dropped events/s
30
+ # - events in the pipeline
31
+ get "/events" do
32
+ respond_with({ :events => events_payload })
33
+ end
34
+
35
+ get "/jvm" do
36
+ respond_with :jvm => jvm_payload
37
+ end
38
+
39
+ get "/process" do
40
+ respond_with :process => process_payload
41
+ end
42
+
43
+ private
44
+
45
+ def events_payload
46
+ @stats.events
47
+ end
48
+
49
+ def jvm_payload
50
+ @stats.jvm
51
+ end
52
+
53
+ def process_payload
54
+ @stats.process
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+ module LogStash
3
+ module Api
4
+ module Modules
5
+ class Plugins < ::LogStash::Api::Modules::Base
6
+
7
+ get "/" do
8
+ command = factory.build(:plugins_command)
9
+ respond_with(command.run())
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+ module LogStash
3
+ module Api
4
+ module Modules
5
+ class Root < ::LogStash::Api::Modules::Base
6
+
7
+ get "/" do
8
+ command = factory.build(:system_basic_info)
9
+ respond_with command.run
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,63 @@
1
+ # encoding: utf-8
2
+ module LogStash
3
+ module Api
4
+ module Modules
5
+ class Stats < ::LogStash::Api::Modules::Base
6
+
7
+ def stats_command
8
+ factory.build(:stats)
9
+ end
10
+
11
+ # Global _stats resource where all information is
12
+ # retrieved and show
13
+ get "/" do
14
+ payload = {
15
+ :events => stats_command.events,
16
+ :jvm => { :memory => stats_command.memory }
17
+ }
18
+ respond_with payload
19
+ end
20
+
21
+
22
+ # return hot threads information
23
+ get "/jvm" do
24
+ jvm_payload = {
25
+ :timestamp => stats_command.started_at,
26
+ :uptime_in_millis => stats_command.uptime,
27
+ :mem => stats_command.memory
28
+ }
29
+ respond_with({:jvm => jvm_payload})
30
+ end
31
+
32
+ # Show all events stats information
33
+ # (for ingested, emitted, dropped)
34
+ # - #events since startup
35
+ # - #data (bytes) since startup
36
+ # - events/s
37
+ # - bytes/s
38
+ # - dropped events/s
39
+ # - events in the pipeline
40
+ get "/events" do
41
+ respond_with({ :events => stats_command.events })
42
+ end
43
+
44
+ # return hot threads information
45
+ get "/jvm/hot_threads" do
46
+ top_threads_count = params["threads"] || 3
47
+ ignore_idle_threads = params["ignore_idle_threads"] || true
48
+ options = {
49
+ :threads => top_threads_count.to_i,
50
+ :ignore_idle_threads => as_boolean(ignore_idle_threads)
51
+ }
52
+
53
+ respond_with(stats_command.hot_threads(options))
54
+ end
55
+
56
+ # return hot threads information
57
+ get "/jvm/memory" do
58
+ respond_with({ :memory => stats_command.memory })
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,33 @@
1
+ require "logstash/api/modules/base"
2
+ require "logstash/api/modules/node"
3
+ require "logstash/api/modules/node_stats"
4
+ require "logstash/api/modules/plugins"
5
+ require "logstash/api/modules/root"
6
+ require "logstash/api/modules/stats"
7
+
8
+ module LogStash
9
+ module Api
10
+ module RackApp
11
+ def self.app
12
+ namespaces = rack_namespaces
13
+ Rack::Builder.new do
14
+ run LogStash::Api::Modules::Root
15
+ namespaces.each_pair do |namespace, app|
16
+ map(namespace) do
17
+ run app
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ def self.rack_namespaces
24
+ {
25
+ "/_node" => LogStash::Api::Modules::Node,
26
+ "/_stats" => LogStash::Api::Modules::Stats,
27
+ "/_node/stats" => LogStash::Api::Modules::NodeStats,
28
+ "/_plugins" => LogStash::Api::Modules::Plugins
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,73 @@
1
+ # encoding: utf-8
2
+ require "logstash/instrument/collector"
3
+ require "logstash/util/loggable"
4
+
5
+ module LogStash
6
+ module Api
7
+ class Service
8
+
9
+ include Singleton
10
+ include LogStash::Util::Loggable
11
+
12
+ def initialize
13
+ @snapshot_rotation_mutex = Mutex.new
14
+ @snapshot = nil
15
+ logger.debug("[api-service] start") if logger.debug?
16
+ LogStash::Instrument::Collector.instance.add_observer(self)
17
+ end
18
+
19
+ def stop
20
+ logger.debug("[api-service] stop") if logger.debug?
21
+ LogStash::Instrument::Collector.instance.delete_observer(self)
22
+ end
23
+
24
+ def agent
25
+ LogStash::Instrument::Collector.instance.agent
26
+ end
27
+
28
+ def started?
29
+ !@snapshot.nil? && has_counters?
30
+ end
31
+
32
+ def update(snapshot)
33
+ logger.debug("[api-service] snapshot received", :snapshot_time => snapshot.created_at) if logger.debug?
34
+
35
+ @snapshot_rotation_mutex.synchronize do
36
+ @snapshot = snapshot
37
+ end
38
+ end
39
+
40
+ def snapshot
41
+ @snapshot_rotation_mutex.synchronize { @snapshot }
42
+ end
43
+
44
+ def get_shallow(*path)
45
+ snapshot.metric_store.get_shallow(*path)
46
+ end
47
+
48
+ def get(key)
49
+ metric_store = @snapshot_rotation_mutex.synchronize { @snapshot.metric_store }
50
+ if key == :jvm_memory_stats
51
+ data = metric_store.get_shallow(:jvm, :memory)
52
+ else
53
+ data = metric_store.get_with_path("stats/events")
54
+ end
55
+ LogStash::Json.dump(data)
56
+ end
57
+
58
+ private
59
+
60
+ def has_counters?
61
+ (["LogStash::Instrument::MetricType::Counter", "LogStash::Instrument::MetricType::Gauge"] - metric_types).empty?
62
+ end
63
+
64
+ def metric_types
65
+ types = []
66
+ @snapshot_rotation_mutex.synchronize do
67
+ types = @snapshot.metric_store.all.map { |t| t.class.to_s }
68
+ end
69
+ return types
70
+ end
71
+ end
72
+ end
73
+ end
@@ -94,6 +94,7 @@ module LogStash; module Config; module AST
94
94
  @outputs = []
95
95
  @periodic_flushers = []
96
96
  @shutdown_flushers = []
97
+ @generated_objects = {}
97
98
  CODE
98
99
 
99
100
  sections = recursive_select(LogStash::Config::AST::PluginSection)
@@ -137,7 +138,10 @@ module LogStash; module Config; module AST
137
138
  class PluginSection < Node
138
139
  # Global plugin numbering for the janky instance variable naming we use
139
140
  # like @filter_<name>_1
140
- @@i = 0
141
+ def initialize(*args)
142
+ super(*args)
143
+ @i = 0
144
+ end
141
145
 
142
146
  # Generate ruby code to initialize all the plugins.
143
147
  def compile_initializer
@@ -147,31 +151,31 @@ module LogStash; module Config; module AST
147
151
 
148
152
 
149
153
  code << <<-CODE
150
- #{name} = #{plugin.compile_initializer}
151
- @#{plugin.plugin_type}s << #{name}
154
+ @generated_objects[:#{name}] = #{plugin.compile_initializer}
155
+ @#{plugin.plugin_type}s << @generated_objects[:#{name}]
152
156
  CODE
153
157
 
154
158
  # The flush method for this filter.
155
159
  if plugin.plugin_type == "filter"
156
160
 
157
161
  code << <<-CODE
158
- #{name}_flush = lambda do |options, &block|
159
- @logger.debug? && @logger.debug(\"Flushing\", :plugin => #{name})
162
+ @generated_objects[:#{name}_flush] = lambda do |options, &block|
163
+ @logger.debug? && @logger.debug(\"Flushing\", :plugin => @generated_objects[:#{name}])
160
164
 
161
- events = #{name}.flush(options)
165
+ events = @generated_objects[:#{name}].flush(options)
162
166
 
163
167
  return if events.nil? || events.empty?
164
168
 
165
- @logger.debug? && @logger.debug(\"Flushing\", :plugin => #{name}, :events => events)
169
+ @logger.debug? && @logger.debug(\"Flushing\", :plugin => @generated_objects[:#{name}], :events => events)
166
170
 
167
171
  #{plugin.compile_starting_here.gsub(/^/, " ")}
168
172
 
169
173
  events.each{|e| block.call(e)}
170
174
  end
171
175
 
172
- if #{name}.respond_to?(:flush)
173
- @periodic_flushers << #{name}_flush if #{name}.periodic_flush
174
- @shutdown_flushers << #{name}_flush
176
+ if @generated_objects[:#{name}].respond_to?(:flush)
177
+ @periodic_flushers << @generated_objects[:#{name}_flush] if @generated_objects[:#{name}].periodic_flush
178
+ @shutdown_flushers << @generated_objects[:#{name}_flush]
175
179
  end
176
180
  CODE
177
181
 
@@ -192,9 +196,10 @@ module LogStash; module Config; module AST
192
196
 
193
197
  plugins.each do |plugin|
194
198
  # Unique number for every plugin.
195
- @@i += 1
199
+ @i += 1
196
200
  # store things as ivars, like @filter_grok_3
197
- var = "@#{plugin.plugin_type}_#{plugin.plugin_name}_#{@@i}"
201
+ var = :"#{plugin.plugin_type}_#{plugin.plugin_name}_#{@i}"
202
+ # puts("var=#{var.inspect}")
198
203
  @variables[plugin] = var
199
204
  end
200
205
  return @variables
@@ -236,13 +241,13 @@ module LogStash; module Config; module AST
236
241
  def compile
237
242
  case plugin_type
238
243
  when "input"
239
- return "start_input(#{variable_name})"
244
+ return "start_input(@generated_objects[:#{variable_name}])"
240
245
  when "filter"
241
246
  return <<-CODE
242
- events = #{variable_name}.multi_filter(events)
247
+ events = @generated_objects[:#{variable_name}].multi_filter(events)
243
248
  CODE
244
249
  when "output"
245
- return "targeted_outputs << #{variable_name}\n"
250
+ return "targeted_outputs << @generated_objects[:#{variable_name}]\n"
246
251
  when "codec"
247
252
  settings = attributes.recursive_select(Attribute).collect(&:compile).reject(&:empty?)
248
253
  attributes_code = "LogStash::Util.hash_merge_many(#{settings.map { |c| "{ #{c} }" }.join(", ")})"
@@ -391,7 +396,7 @@ module LogStash; module Config; module AST
391
396
  if type == "filter"
392
397
  i = LogStash::Config::AST.defered_conditionals_index += 1
393
398
  source = <<-CODE
394
- define_singleton_method :cond_func_#{i} do |input_events|
399
+ @generated_objects[:cond_func_#{i}] = lambda do |input_events|
395
400
  result = []
396
401
  input_events.each do |event|
397
402
  events = [event]
@@ -405,7 +410,7 @@ module LogStash; module Config; module AST
405
410
  LogStash::Config::AST.defered_conditionals << source
406
411
 
407
412
  <<-CODE
408
- events = cond_func_#{i}(events)
413
+ events = @generated_objects[:cond_func_#{i}].call(events)
409
414
  CODE
410
415
  else # Output
411
416
  <<-CODE
@@ -512,7 +517,7 @@ module LogStash; module Config; module AST
512
517
  end
513
518
  class Selector < RValue
514
519
  def compile
515
- return "event[#{text_value.inspect}]"
520
+ return "event.get(#{text_value.inspect})"
516
521
  end
517
522
  end
518
523
  class SelectorElement < Node; end
@@ -1,9 +1,9 @@
1
1
  require "logstash/config/defaults"
2
2
 
3
3
  module LogStash; module Config; class Loader
4
- def initialize(logger, debug_config=false)
4
+ def initialize(logger)
5
5
  @logger = logger
6
- @debug_config = debug_config
6
+ @config_debug = LogStash::SETTINGS.get_value("config.debug")
7
7
  end
8
8
 
9
9
  def format_config(config_path, config_string)
@@ -70,7 +70,7 @@ module LogStash; module Config; class Loader
70
70
  encoding_issue_files << file
71
71
  end
72
72
  config << cfg + "\n"
73
- if @debug_config
73
+ if @config_debug
74
74
  @logger.debug? && @logger.debug("\nThe following is the content of a file", :config_file => file.to_s)
75
75
  @logger.debug? && @logger.debug("\n" + cfg + "\n\n")
76
76
  end
@@ -78,7 +78,7 @@ module LogStash; module Config; class Loader
78
78
  if encoding_issue_files.any?
79
79
  fail("The following config files contains non-ascii characters but are not UTF-8 encoded #{encoding_issue_files}")
80
80
  end
81
- if @debug_config
81
+ if @config_debug
82
82
  @logger.debug? && @logger.debug("\nThe following is the merged configuration")
83
83
  @logger.debug? && @logger.debug("\n" + config + "\n\n")
84
84
  end
@@ -39,7 +39,6 @@ module LogStash::Config::Mixin
39
39
  PLUGIN_VERSION_1_0_0 = LogStash::Util::PluginVersion.new(1, 0, 0)
40
40
  PLUGIN_VERSION_0_9_0 = LogStash::Util::PluginVersion.new(0, 9, 0)
41
41
 
42
- ALLOW_ENV_FLAG = "__ALLOW_ENV__"
43
42
  ENV_PLACEHOLDER_REGEX = /\$\{(?<name>\w+)(\:(?<default>[^}]*))?\}/
44
43
 
45
44
  # This method is called when someone does 'include LogStash::Config'
@@ -49,14 +48,6 @@ module LogStash::Config::Mixin
49
48
  end
50
49
 
51
50
  def config_init(params)
52
- # HACK(talevy): https://github.com/elastic/logstash/issues/4958
53
- # Currently, the regular plugins params argument is hijacked
54
- # to pass along the `allow_env` configuration variable. This was done as to
55
- # not change the method signature of Plugin. This also makes it difficul to
56
- # reason about at the same time. ALLOW_ENV_FLAG is a special param that users
57
- # are now forbidden to set in their configuration definitions.
58
- allow_env = params.delete(LogStash::Config::Mixin::ALLOW_ENV_FLAG) { false }
59
-
60
51
  # Validation will modify the values inside params if necessary.
61
52
  # For example: converting a string to a number, etc.
62
53
 
@@ -112,20 +103,18 @@ module LogStash::Config::Mixin
112
103
  end
113
104
 
114
105
  # Resolve environment variables references
115
- if allow_env
116
- params.each do |name, value|
117
- if (value.is_a?(Hash))
118
- value.each do |valueHashKey, valueHashValue|
119
- value[valueHashKey.to_s] = replace_env_placeholders(valueHashValue)
106
+ params.each do |name, value|
107
+ if (value.is_a?(Hash))
108
+ value.each do |valueHashKey, valueHashValue|
109
+ value[valueHashKey.to_s] = replace_env_placeholders(valueHashValue)
110
+ end
111
+ else
112
+ if (value.is_a?(Array))
113
+ value.each_index do |valueArrayIndex|
114
+ value[valueArrayIndex] = replace_env_placeholders(value[valueArrayIndex])
120
115
  end
121
116
  else
122
- if (value.is_a?(Array))
123
- value.each_index do |valueArrayIndex|
124
- value[valueArrayIndex] = replace_env_placeholders(value[valueArrayIndex])
125
- end
126
- else
127
- params[name.to_s] = replace_env_placeholders(value)
128
- end
117
+ params[name.to_s] = replace_env_placeholders(value)
129
118
  end
130
119
  end
131
120
  end