logstash-core 2.4.1-java → 5.0.0.alpha1-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 (95) hide show
  1. checksums.yaml +4 -4
  2. data/lib/logstash-core/version.rb +1 -1
  3. data/lib/logstash/agent.rb +124 -411
  4. data/lib/logstash/api/init.ru +31 -0
  5. data/lib/logstash/api/lib/app.rb +40 -0
  6. data/lib/logstash/api/lib/app/command.rb +29 -0
  7. data/lib/logstash/api/lib/app/command_factory.rb +29 -0
  8. data/lib/logstash/api/lib/app/commands/stats/events_command.rb +13 -0
  9. data/lib/logstash/api/lib/app/commands/stats/hotthreads_command.rb +120 -0
  10. data/lib/logstash/api/lib/app/commands/stats/memory_command.rb +25 -0
  11. data/lib/logstash/api/lib/app/commands/system/basicinfo_command.rb +15 -0
  12. data/lib/logstash/api/lib/app/commands/system/plugins_command.rb +28 -0
  13. data/lib/logstash/api/lib/app/modules/node.rb +25 -0
  14. data/lib/logstash/api/lib/app/modules/node_stats.rb +51 -0
  15. data/lib/logstash/api/lib/app/modules/plugins.rb +15 -0
  16. data/lib/logstash/api/lib/app/modules/stats.rb +21 -0
  17. data/lib/logstash/api/lib/app/root.rb +13 -0
  18. data/lib/logstash/api/lib/app/service.rb +61 -0
  19. data/lib/logstash/api/lib/app/stats.rb +56 -0
  20. data/lib/logstash/api/lib/helpers/app_helpers.rb +23 -0
  21. data/lib/logstash/codecs/base.rb +1 -29
  22. data/lib/logstash/config/config_ast.rb +18 -31
  23. data/lib/logstash/config/loader.rb +3 -5
  24. data/lib/logstash/config/mixin.rb +25 -64
  25. data/lib/logstash/filter_delegator.rb +65 -0
  26. data/lib/logstash/inputs/base.rb +1 -1
  27. data/lib/logstash/inputs/metrics.rb +47 -0
  28. data/lib/logstash/instrument/collector.rb +109 -0
  29. data/lib/logstash/instrument/metric.rb +102 -0
  30. data/lib/logstash/instrument/metric_store.rb +228 -0
  31. data/lib/logstash/instrument/metric_type.rb +24 -0
  32. data/lib/logstash/instrument/metric_type/base.rb +35 -0
  33. data/lib/logstash/instrument/metric_type/counter.rb +29 -0
  34. data/lib/logstash/instrument/metric_type/gauge.rb +22 -0
  35. data/lib/logstash/instrument/metric_type/mean.rb +33 -0
  36. data/lib/logstash/instrument/namespaced_metric.rb +54 -0
  37. data/lib/logstash/instrument/null_metric.rb +4 -3
  38. data/lib/logstash/instrument/periodic_poller/base.rb +57 -0
  39. data/lib/logstash/instrument/periodic_poller/jvm.rb +92 -0
  40. data/lib/logstash/instrument/periodic_poller/os.rb +13 -0
  41. data/lib/logstash/instrument/periodic_poller/periodic_poller_observer.rb +19 -0
  42. data/lib/logstash/instrument/periodic_pollers.rb +26 -0
  43. data/lib/logstash/instrument/snapshot.rb +16 -0
  44. data/lib/logstash/json.rb +2 -3
  45. data/lib/logstash/namespace.rb +1 -0
  46. data/lib/logstash/output_delegator.rb +16 -3
  47. data/lib/logstash/outputs/base.rb +1 -32
  48. data/lib/logstash/pipeline.rb +67 -8
  49. data/lib/logstash/plugin.rb +57 -19
  50. data/lib/logstash/runner.rb +348 -84
  51. data/lib/logstash/util.rb +9 -0
  52. data/lib/logstash/util/duration_formatter.rb +15 -0
  53. data/lib/logstash/util/java_version.rb +2 -4
  54. data/lib/logstash/util/loggable.rb +29 -0
  55. data/lib/logstash/version.rb +1 -1
  56. data/lib/logstash/webserver.rb +98 -0
  57. data/locales/en.yml +42 -24
  58. data/logstash-core.gemspec +9 -6
  59. data/spec/api/lib/api/node_spec.rb +64 -0
  60. data/spec/api/lib/api/node_stats_spec.rb +68 -0
  61. data/spec/api/lib/api/plugins_spec.rb +57 -0
  62. data/spec/api/lib/api/root_spec.rb +20 -0
  63. data/spec/api/lib/api/stats_spec.rb +19 -0
  64. data/spec/api/lib/commands/events_spec.rb +17 -0
  65. data/spec/api/lib/commands/jvm_spec.rb +45 -0
  66. data/spec/api/spec_helper.rb +128 -0
  67. data/spec/logstash/agent_spec.rb +62 -169
  68. data/spec/logstash/config/config_ast_spec.rb +2 -47
  69. data/spec/logstash/config/mixin_spec.rb +0 -157
  70. data/spec/logstash/filter_delegator_spec.rb +143 -0
  71. data/spec/logstash/inputs/metrics_spec.rb +52 -0
  72. data/spec/logstash/instrument/collector_spec.rb +49 -0
  73. data/spec/logstash/instrument/metric_spec.rb +110 -0
  74. data/spec/logstash/instrument/metric_store_spec.rb +163 -0
  75. data/spec/logstash/instrument/metric_type/counter_spec.rb +40 -0
  76. data/spec/logstash/instrument/metric_type/gauge_spec.rb +40 -0
  77. data/spec/logstash/instrument/namespaced_metric_spec.rb +25 -0
  78. data/spec/logstash/instrument/null_metric_spec.rb +9 -51
  79. data/spec/logstash/json_spec.rb +14 -0
  80. data/spec/logstash/output_delegator_spec.rb +6 -3
  81. data/spec/logstash/outputs/base_spec.rb +0 -107
  82. data/spec/logstash/pipeline_spec.rb +204 -33
  83. data/spec/logstash/plugin_spec.rb +80 -15
  84. data/spec/logstash/runner_spec.rb +134 -38
  85. data/spec/logstash/shutdown_watcher_spec.rb +0 -1
  86. data/spec/logstash/util/duration_formatter_spec.rb +11 -0
  87. data/spec/logstash/util/java_version_spec.rb +10 -2
  88. data/spec/logstash/util_spec.rb +28 -0
  89. data/spec/support/matchers.rb +30 -0
  90. metadata +154 -20
  91. data/lib/logstash/logging/json.rb +0 -21
  92. data/lib/logstash/special_agent.rb +0 -8
  93. data/lib/logstash/util/safe_uri.rb +0 -50
  94. data/spec/logstash/codecs/base_spec.rb +0 -74
  95. data/spec/static/i18n_spec.rb +0 -25
@@ -0,0 +1,31 @@
1
+ ROOT = File.expand_path(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift File.join(ROOT, 'lib')
3
+ Dir.glob('lib/**').each{ |d| $LOAD_PATH.unshift(File.join(ROOT, d)) }
4
+
5
+ require 'sinatra'
6
+ require 'app/root'
7
+ require 'app/modules/stats'
8
+ require 'app/modules/node'
9
+ require 'app/modules/node_stats'
10
+ require 'app/modules/plugins'
11
+
12
+ env = ENV["RACK_ENV"].to_sym
13
+ set :environment, env
14
+
15
+ set :service, LogStash::Api::Service.instance
16
+
17
+ configure do
18
+ enable :logging
19
+ end
20
+ run LogStash::Api::Root
21
+
22
+ namespaces = { "/_node" => LogStash::Api::Node,
23
+ "/_node/stats" => LogStash::Api::NodeStats,
24
+ "/_stats" => LogStash::Api::Stats,
25
+ "/_plugins" => LogStash::Api::Plugins }
26
+
27
+ namespaces.each_pair do |namespace, app|
28
+ map(namespace) do
29
+ run app
30
+ end
31
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+ require "cabin"
3
+ require "logstash/json"
4
+ require "helpers/app_helpers"
5
+ require "app/service"
6
+ require "app/command_factory"
7
+ require "logstash/util/loggable"
8
+
9
+ module LogStash::Api
10
+ class BaseApp < ::Sinatra::Application
11
+
12
+ attr_reader :factory
13
+
14
+ if settings.environment != :production
15
+ set :raise_errors, true
16
+ set :show_exceptions, :after_handler
17
+ end
18
+
19
+ include LogStash::Util::Loggable
20
+
21
+ helpers AppHelpers
22
+
23
+ def initialize(app=nil)
24
+ super(app)
25
+ @factory = CommandFactory.new(settings.service)
26
+ end
27
+
28
+ not_found do
29
+ status 404
30
+ as = params.has_key?("human") ? :string : :json
31
+ text = as == :string ? "" : {}
32
+ respond_with(text, :as => as)
33
+ end
34
+
35
+ error do
36
+ logger.error(env['sinatra.error'].message, :url => request.url, :ip => request.ip, :params => request.params)
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ require "app/service"
3
+
4
+ module LogStash::Api
5
+ class Command
6
+
7
+ attr_reader :service
8
+
9
+ def initialize(service = LogStash::Api::Service.instance)
10
+ @service = service
11
+ end
12
+
13
+ def run
14
+ raise "Not implemented"
15
+ end
16
+
17
+ def hostname
18
+ service.agent.node_name
19
+ end
20
+
21
+ def uptime
22
+ service.agent.uptime
23
+ end
24
+
25
+ def started_at
26
+ (LogStash::Agent::STARTED_AT.to_f * 1000.0).to_i
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ require "app/service"
3
+ require "app/commands/system/basicinfo_command"
4
+ require "app/commands/stats/events_command"
5
+ require "app/commands/stats/hotthreads_command"
6
+ require "app/commands/stats/memory_command"
7
+ require "app/commands/system/plugins_command"
8
+
9
+ module LogStash::Api
10
+ class CommandFactory
11
+
12
+ attr_reader :factory, :service
13
+
14
+ def initialize(service)
15
+ @service = service
16
+ @factory = {}.merge(
17
+ :system_basic_info => SystemBasicInfoCommand,
18
+ :events_command => StatsEventsCommand,
19
+ :hot_threads_command => HotThreadsCommand,
20
+ :memory_command => JvmMemoryCommand,
21
+ :plugins_command => PluginsCommand
22
+ )
23
+ end
24
+
25
+ def build(klass)
26
+ factory[klass].new(service)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+ require "app/command"
3
+
4
+ class LogStash::Api::StatsEventsCommand < LogStash::Api::Command
5
+
6
+ def run
7
+ #return whatever is comming out of the snapshot event, this obvoiusly
8
+ #need to be tailored to the right metrics for this command.
9
+ stats = LogStash::Json.load(service.get(:events_stats))
10
+ stats["stats"]["events"]
11
+ end
12
+
13
+ end
@@ -0,0 +1,120 @@
1
+ # encoding: utf-8
2
+ require "app/command"
3
+ require 'monitoring'
4
+ require "socket"
5
+
6
+ class LogStash::Api::HotThreadsCommand < LogStash::Api::Command
7
+
8
+ STACK_TRACES_SIZE_DEFAULT = 10.freeze
9
+
10
+ def run(options={})
11
+ filter = { :stacktrace_size => options.fetch(:stacktrace_size, STACK_TRACES_SIZE_DEFAULT) }
12
+ hash = JRMonitor.threads.generate(filter)
13
+ ThreadDump.new(hash, self, options)
14
+ end
15
+
16
+ private
17
+
18
+ class ThreadDump
19
+
20
+ SKIPPED_THREADS = [ "Finalizer", "Reference Handler", "Signal Dispatcher" ].freeze
21
+ THREADS_COUNT_DEFAULT = 3.freeze
22
+ IGNORE_IDLE_THREADS_DEFAULT = true.freeze
23
+
24
+ attr_reader :top_count, :ignore, :dump
25
+
26
+ def initialize(dump, cmd, options={})
27
+ @dump = dump
28
+ @options = options
29
+ @top_count = options.fetch(:threads, THREADS_COUNT_DEFAULT)
30
+ @ignore = options.fetch(:ignore_idle_threads, IGNORE_IDLE_THREADS_DEFAULT)
31
+ @cmd = cmd
32
+ end
33
+
34
+ def to_s
35
+ hash = to_hash
36
+ report = "#{I18n.t("logstash.web_api.hot_threads.title", :hostname => hash[:hostname], :time => hash[:time], :top_count => top_count )} \n"
37
+ hash[:threads].each do |thread|
38
+ thread_report = ""
39
+ thread_report = "\t #{I18n.t("logstash.web_api.hot_threads.thread_title", :percent_of_cpu_time => thread[:percent_of_cpu_time], :thread_state => thread[:state], :thread_name => thread[:name])} \n"
40
+ thread_report = "\t #{thread[:percent_of_cpu_time]} % of of cpu usage by #{thread[:state]} thread named '#{thread[:name]}'\n"
41
+ thread_report << "\t\t #{thread[:path]}\n" if thread[:path]
42
+ thread[:traces].split("\n").each do |trace|
43
+ thread_report << "#{trace}\n"
44
+ end
45
+ report << thread_report
46
+ end
47
+ report
48
+ end
49
+
50
+ def to_hash
51
+ hash = { :hostname => hostname, :time => Time.now.iso8601, :busiest_threads => top_count, :threads => [] }
52
+ each do |thread_name, _hash|
53
+ thread_name, thread_path = _hash["thread.name"].split(": ")
54
+ thread = { :name => thread_name,
55
+ :percent_of_cpu_time => cpu_time_as_percent(_hash),
56
+ :state => _hash["thread.state"]
57
+ }
58
+ thread[:path] = thread_path if thread_path
59
+ traces = ""
60
+ _hash["thread.stacktrace"].each do |trace|
61
+ traces << "\t\t#{trace}\n"
62
+ end
63
+ thread[:traces] = traces unless traces.empty?
64
+ hash[:threads] << thread
65
+ end
66
+ hash
67
+ end
68
+
69
+ private
70
+
71
+ def each(&block)
72
+ i=0
73
+ dump.each_pair do |thread_name, _hash|
74
+ break if i >= top_count
75
+ if ignore
76
+ next if idle_thread?(thread_name, _hash)
77
+ end
78
+ block.call(thread_name, _hash)
79
+ i += 1
80
+ end
81
+ end
82
+
83
+ def idle_thread?(thread_name, data)
84
+ idle = false
85
+ if SKIPPED_THREADS.include?(thread_name)
86
+ # these are likely JVM dependent
87
+ idle = true
88
+ elsif thread_name.match(/Ruby-\d+-JIT-\d+/)
89
+ # This are internal JRuby JIT threads,
90
+ # see java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor for details.
91
+ idle = true
92
+ elsif thread_name.match(/pool-\d+-thread-\d+/)
93
+ # This are threads used by the internal JRuby implementation to dispatch
94
+ # calls and tasks, see prg.jruby.internal.runtime.methods.DynamicMethod.call
95
+ idle = true
96
+ else
97
+ data["thread.stacktrace"].each do |trace|
98
+ if trace.start_with?("java.util.concurrent.ThreadPoolExecutor.getTask")
99
+ idle = true
100
+ break
101
+ end
102
+ end
103
+ end
104
+ idle
105
+ end
106
+
107
+ def hostname
108
+ @cmd.hostname
109
+ end
110
+
111
+ def cpu_time_as_percent(hash)
112
+ (((cpu_time(hash) / @cmd.uptime * 1.0)*10000).to_i)/100.0
113
+ end
114
+
115
+ def cpu_time(hash)
116
+ hash["cpu.time"] / 1000000.0
117
+ end
118
+ end
119
+
120
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ require "app/command"
3
+ require 'monitoring'
4
+
5
+ class LogStash::Api::JvmMemoryCommand < LogStash::Api::Command
6
+
7
+ def run
8
+ memory = LogStash::Json.load(service.get(:jvm_memory_stats))
9
+ {
10
+ :heap_used_in_bytes => memory["heap"]["used_in_bytes"],
11
+ :heap_used_percent => memory["heap"]["used_percent"],
12
+ :heap_committed_in_bytes => memory["heap"]["committed_in_bytes"],
13
+ :heap_max_in_bytes => memory["heap"]["max_in_bytes"],
14
+ :heap_used_in_bytes => memory["heap"]["used_in_bytes"],
15
+ :non_heap_used_in_bytes => memory["non_heap"]["used_in_bytes"],
16
+ :non_heap_committed_in_bytes => memory["non_heap"]["committed_in_bytes"],
17
+ :pools => memory["pools"].inject({}) do |acc, (type, hash)|
18
+ hash.delete("committed_in_bytes")
19
+ acc[type] = hash
20
+ acc
21
+ end
22
+ }
23
+ end
24
+
25
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+ require "app/command"
3
+ require "logstash/util/duration_formatter"
4
+
5
+ class LogStash::Api::SystemBasicInfoCommand < LogStash::Api::Command
6
+
7
+ def run
8
+ {
9
+ "hostname" => hostname,
10
+ "version" => {
11
+ "number" => LOGSTASH_VERSION
12
+ }
13
+ }
14
+ end
15
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ require "app/command"
3
+
4
+ class LogStash::Api::PluginsCommand < LogStash::Api::Command
5
+
6
+ def run
7
+ { :total => plugins.count, :plugins => plugins }
8
+ end
9
+
10
+ private
11
+
12
+ def plugins
13
+ @plugins ||= find_plugins_gem_specs.map do |spec|
14
+ { :name => spec.name, :version => spec.version.to_s }
15
+ end.sort_by do |spec|
16
+ spec[:name]
17
+ end
18
+ end
19
+
20
+ def find_plugins_gem_specs
21
+ @specs ||= Gem::Specification.find_all.select{|spec| logstash_plugin_gem_spec?(spec)}
22
+ end
23
+
24
+ def logstash_plugin_gem_spec?(spec)
25
+ spec.metadata && spec.metadata["logstash_plugin"] == "true"
26
+ end
27
+
28
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ require "app"
3
+
4
+ module LogStash::Api
5
+ class Node < BaseApp
6
+
7
+ helpers AppHelpers
8
+
9
+ # return hot threads information
10
+ get "/hot_threads" do
11
+ ignore_idle_threads = params["ignore_idle_threads"] || true
12
+
13
+ options = {
14
+ :ignore_idle_threads => as_boolean(ignore_idle_threads),
15
+ :human => params.has_key?("human")
16
+ }
17
+ options[:threads] = params["threads"].to_i if params.has_key?("threads")
18
+
19
+ command = factory.build(:hot_threads_command)
20
+ as = options[:human] ? :string : :json
21
+ respond_with(command.run(options), {:as => as})
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+ require "app"
3
+
4
+ module LogStash::Api
5
+ class NodeStats < BaseApp
6
+
7
+ helpers AppHelpers
8
+
9
+
10
+ # Global _stats resource where all information is
11
+ # retrieved and show
12
+ get "/" do
13
+ events_command = factory.build(:events_command)
14
+ payload = {
15
+ :events => events_command.run,
16
+ :jvm => jvm_payload
17
+ }
18
+
19
+ respond_with payload
20
+ end
21
+
22
+ # Show all events stats information
23
+ # (for ingested, emitted, dropped)
24
+ # - #events since startup
25
+ # - #data (bytes) since startup
26
+ # - events/s
27
+ # - bytes/s
28
+ # - dropped events/s
29
+ # - events in the pipeline
30
+ get "/events" do
31
+ command = factory.build(:events_command)
32
+ respond_with({ :events => command.run })
33
+ end
34
+
35
+ # return hot threads information
36
+ get "/jvm" do
37
+ respond_with jvm_payload
38
+ end
39
+
40
+ private
41
+
42
+ def jvm_payload
43
+ command = factory.build(:memory_command)
44
+ {
45
+ :timestamp => command.started_at,
46
+ :uptime_in_millis => command.uptime,
47
+ :mem => command.run
48
+ }
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+ require "app"
3
+
4
+ module LogStash::Api
5
+ class Plugins < BaseApp
6
+
7
+ helpers AppHelpers
8
+
9
+ get "/" do
10
+ command = factory.build(:plugins_command)
11
+ respond_with(command.run())
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+ require "app"
3
+
4
+ module LogStash::Api
5
+ class Stats < BaseApp
6
+
7
+ helpers AppHelpers
8
+
9
+ # return hot threads information
10
+ get "/jvm" do
11
+ command = factory.build(:memory_command)
12
+ jvm_payload = {
13
+ :timestamp => command.started_at,
14
+ :uptime_in_millis => command.uptime,
15
+ :mem => command.run
16
+ }
17
+ respond_with({:jvm => jvm_payload})
18
+ end
19
+
20
+ end
21
+ end