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,24 @@
1
+ # encoding: utf-8
2
+ require "logstash/instrument/metric_type/counter"
3
+ require "logstash/instrument/metric_type/mean"
4
+ require "logstash/instrument/metric_type/gauge"
5
+
6
+ module LogStash module Instrument
7
+ module MetricType
8
+ METRIC_TYPE_LIST = {
9
+ :counter => LogStash::Instrument::MetricType::Counter,
10
+ :mean => LogStash::Instrument::MetricType::Mean,
11
+ :gauge => LogStash::Instrument::MetricType::Gauge
12
+ }.freeze
13
+
14
+ # Use the string to generate a concrete class for this metrics
15
+ #
16
+ # @param [String] The name of the class
17
+ # @param [Array] Namespaces list
18
+ # @param [String] The metric key
19
+ # @raise [NameError] If the class is not found
20
+ def self.create(type, namespaces, key)
21
+ METRIC_TYPE_LIST[type].new(namespaces, key)
22
+ end
23
+ end
24
+ end; end
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+ require "logstash/event"
3
+ require "logstash/util"
4
+
5
+ module LogStash module Instrument module MetricType
6
+ class Base
7
+ attr_reader :namespaces, :key
8
+
9
+ def initialize(namespaces, key)
10
+ @namespaces = namespaces
11
+ @key = key
12
+ end
13
+
14
+ def inspect
15
+ "#{self.class.name} - namespaces: #{namespaces} key: #{key} value: #{value}"
16
+ end
17
+
18
+ def to_hash
19
+ {
20
+ "namespaces" => namespaces,
21
+ "key" => key,
22
+ "type" => type,
23
+ "value" => value
24
+ }
25
+ end
26
+
27
+ def to_json_data
28
+ value
29
+ end
30
+
31
+ def type
32
+ @type ||= LogStash::Util.class_name(self).downcase
33
+ end
34
+ end
35
+ end; end; end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ require "logstash/instrument/metric_type/base"
3
+ require "concurrent"
4
+
5
+ module LogStash module Instrument module MetricType
6
+ class Counter < Base
7
+ def initialize(namespaces, key, value = 0)
8
+ super(namespaces, key)
9
+
10
+ @counter = Concurrent::AtomicFixnum.new(value)
11
+ end
12
+
13
+ def increment(value = 1)
14
+ @counter.increment(value)
15
+ end
16
+
17
+ def decrement(value = 1)
18
+ @counter.decrement(value)
19
+ end
20
+
21
+ def execute(action, value = 1)
22
+ @counter.send(action, value)
23
+ end
24
+
25
+ def value
26
+ @counter.value
27
+ end
28
+ end
29
+ end; end; end
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+ require "logstash/instrument/metric_type/base"
3
+ require "concurrent/atomic_reference/mutex_atomic"
4
+ require "logstash/json"
5
+
6
+ module LogStash module Instrument module MetricType
7
+ class Gauge < Base
8
+ def initialize(namespaces, key)
9
+ super(namespaces, key)
10
+
11
+ @gauge = Concurrent::MutexAtomicReference.new()
12
+ end
13
+
14
+ def execute(action, value = nil)
15
+ @gauge.set(value)
16
+ end
17
+
18
+ def value
19
+ @gauge.get
20
+ end
21
+ end
22
+ end; end; end
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+ require "logstash/instrument/metric_type/base"
3
+ require "concurrent"
4
+
5
+ module LogStash module Instrument module MetricType
6
+ class Mean < Base
7
+ def initialize(namespaces, key)
8
+ super(namespaces, key)
9
+
10
+ @counter = Concurrent::AtomicFixnum.new
11
+ @sum = Concurrent::AtomicFixnum.new
12
+ end
13
+
14
+ def increment(value = 1)
15
+ @counter.increment
16
+ @sum.increment(value)
17
+ end
18
+
19
+ def decrement(value = 1)
20
+ @counter.decrement
21
+ @sum.decrement(value)
22
+ end
23
+
24
+ def mean
25
+ if @counter > 0
26
+ @sum.value / @counter.value
27
+ else
28
+ 0
29
+ end
30
+ end
31
+ alias_method :value, :mean
32
+ end
33
+ end; end; end
@@ -0,0 +1,54 @@
1
+ # encoding: utf-8
2
+ require "logstash/instrument/metric"
3
+
4
+ module LogStash module Instrument
5
+ # This class acts a a proxy between the metric library and the user calls.
6
+ #
7
+ # This is the class that plugins authors will use to interact with the `MetricStore`
8
+ # It has the same public interface as `Metric` class but doesnt require to send
9
+ # the namespace on every call.
10
+ #
11
+ # @see Logstash::Instrument::Metric
12
+ class NamespacedMetric
13
+ attr_reader :namespace_name
14
+ # Create metric with a specific namespace
15
+ #
16
+ # @param metric [LogStash::Instrument::Metric] The metric instance to proxy
17
+ # @param namespace [Array] The namespace to use
18
+ def initialize(metric, namespace_name)
19
+ @metric = metric
20
+ @namespace_name = Array(namespace_name)
21
+ end
22
+
23
+ def increment(key, value = 1)
24
+ @metric.increment(namespace_name, key, value)
25
+ end
26
+
27
+ def decrement(namespace, key, value = 1)
28
+ @metric.decrement(namespace_name, key, value)
29
+ end
30
+
31
+ def gauge(key, value)
32
+ @metric.gauge(namespace_name, key, value)
33
+ end
34
+
35
+ def report_time(key, duration)
36
+ @metric.report_time(namespace_name, key, duration)
37
+ end
38
+
39
+ def time(key, &block)
40
+ @metric.time(namespace_name, key, &block)
41
+ end
42
+
43
+ def collector
44
+ @metric.collector
45
+ end
46
+
47
+ def namespace(name)
48
+ NamespacedMetric.new(metric, namespace_name.concat(Array(name)))
49
+ end
50
+
51
+ private
52
+ attr_reader :metric
53
+ end
54
+ end; end
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ require "logstash/instrument/metric"
2
3
 
3
4
  module LogStash module Instrument
4
5
  # This class is used in the context when we disable the metric collection
@@ -10,7 +11,7 @@ module LogStash module Instrument
10
11
  def increment(key, value = 1)
11
12
  end
12
13
 
13
- def decrement(key, value = 1)
14
+ def decrement(namespace, key, value = 1)
14
15
  end
15
16
 
16
17
  def gauge(key, value)
@@ -21,7 +22,7 @@ module LogStash module Instrument
21
22
 
22
23
  # We have to manually redefine this method since it can return an
23
24
  # object this object also has to be implemented as a NullObject
24
- def time(key, &block)
25
+ def time(key)
25
26
  if block_given?
26
27
  yield
27
28
  else
@@ -29,7 +30,7 @@ module LogStash module Instrument
29
30
  end
30
31
  end
31
32
 
32
- def namespace(name)
33
+ def namespace(key)
33
34
  self.class.new
34
35
  end
35
36
 
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+ require "logstash/util/loggable"
3
+ require "logstash/util"
4
+ require "concurrent"
5
+
6
+ module LogStash module Instrument module PeriodicPoller
7
+ class Base
8
+ include LogStash::Util::Loggable
9
+
10
+ DEFAULT_OPTIONS = {
11
+ :polling_interval => 1,
12
+ :polling_timeout => 60
13
+ }
14
+
15
+ public
16
+ def initialize(metric, options = {})
17
+ @metric = metric
18
+ @options = DEFAULT_OPTIONS.merge(options)
19
+ configure_task
20
+ end
21
+
22
+ def update(time, result, exception)
23
+ return unless exception
24
+
25
+ logger.error("PeriodicPoller: exception",
26
+ :poller => self,
27
+ :result => result,
28
+ :exception => exception,
29
+ :executed_at => time)
30
+ end
31
+
32
+ def collect
33
+ raise NotImplementedError, "#{self.class.name} need to implement `#collect`"
34
+ end
35
+
36
+ def start
37
+ logger.debug("PeriodicPoller: Starting",
38
+ :polling_interval => @options[:polling_interval],
39
+ :polling_timeout => @options[:polling_timeout]) if logger.debug?
40
+ @task.execute
41
+ end
42
+
43
+ def stop
44
+ logger.debug("PeriodicPoller: Stopping")
45
+ @task.shutdown
46
+ end
47
+
48
+ protected
49
+ def configure_task
50
+ @task = Concurrent::TimerTask.new { collect }
51
+ @task.execution_interval = @options[:polling_interval]
52
+ @task.timeout_interval = @options[:polling_timeout]
53
+ @task.add_observer(self)
54
+ end
55
+ end
56
+ end
57
+ end; end
@@ -0,0 +1,92 @@
1
+ # encoding: utf-8
2
+ require "logstash/instrument/periodic_poller/base"
3
+ require 'monitoring'
4
+
5
+ module LogStash module Instrument module PeriodicPoller
6
+ class JVM < Base
7
+
8
+ attr_reader :metric
9
+
10
+ def initialize(metric, options = {})
11
+ super(metric, options)
12
+ @metric = metric
13
+ end
14
+
15
+ def collect
16
+ raw = JRMonitor.memory.generate
17
+ collect_heap_metrics(raw)
18
+ collect_non_heap_metrics(raw)
19
+ collect_pools_metrics(raw)
20
+ end
21
+
22
+ private
23
+
24
+ def collect_heap_metrics(data)
25
+ heap = aggregate_information_for(data["heap"].values)
26
+ heap[:used_percent] = (heap[:used_in_bytes] / heap[:max_in_bytes].to_f)*100.0
27
+
28
+ heap.each_pair do |key, value|
29
+ metric.gauge([:jvm, :memory, :heap], key, value.to_i)
30
+ end
31
+ end
32
+
33
+ def collect_non_heap_metrics(data)
34
+ non_heap = aggregate_information_for(data["non_heap"].values)
35
+ non_heap.each_pair do |key, value|
36
+ metric.gauge([:jvm, :memory, :non_heap],key, value.to_i)
37
+ end
38
+ end
39
+
40
+ def collect_pools_metrics(data)
41
+ metrics = build_pools_metrics(data)
42
+ metrics.each_pair do |key, hash|
43
+ hash.each_pair do |p,v|
44
+ metric.gauge([:jvm, :memory, :pools, key.to_sym], p, v)
45
+ end
46
+ end
47
+ end
48
+
49
+ def build_pools_metrics(data)
50
+ heap = data["heap"]
51
+ old = {}
52
+ old = old.merge!(heap["CMS Old Gen"]) if heap.has_key?("CMS Old Gen")
53
+ old = old.merge!(heap["PS Old Gen"]) if heap.has_key?("PS Old Gen")
54
+ young = {}
55
+ young = young.merge!(heap["Par Eden Space"]) if heap.has_key?("Par Eden Space")
56
+ young = young.merge!(heap["PS Eden Space"]) if heap.has_key?("PS Eden Space")
57
+ survivor = {}
58
+ survivor = survivor.merge!(heap["Par Survivor Space"]) if heap.has_key?("Par Survivor Space")
59
+ survivor = survivor.merge!(heap["PS Survivor Space"]) if heap.has_key?("PS Survivor Space")
60
+ {
61
+ "young" => aggregate_information_for(young),
62
+ "old" => aggregate_information_for(old),
63
+ "survivor" => aggregate_information_for(survivor)
64
+ }
65
+ end
66
+
67
+ def aggregate_information_for(collection)
68
+ collection.reduce(default_information_accumulator) do |m,e|
69
+ e = { e[0] => e[1] } if e.is_a?(Array)
70
+ e.each_pair do |k,v|
71
+ m[:used_in_bytes] += v if k.include?("used")
72
+ m[:committed_in_bytes] += v if k.include?("committed")
73
+ m[:max_in_bytes] += v if k.include?("max")
74
+ m[:peak_max_in_bytes] += v if k.include?("peak.max")
75
+ m[:peak_used_in_bytes] += v if k.include?("peak.used")
76
+ end
77
+ m
78
+ end
79
+ end
80
+
81
+ def default_information_accumulator
82
+ {
83
+ :used_in_bytes => 0,
84
+ :committed_in_bytes => 0,
85
+ :max_in_bytes => 0,
86
+ :peak_used_in_bytes => 0,
87
+ :peak_max_in_bytes => 0
88
+ }
89
+ end
90
+
91
+ end
92
+ end; end; end
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+ require "logstash/instrument/periodic_poller/base"
3
+
4
+ module LogStash module Instrument module PeriodicPoller
5
+ class Os < Base
6
+ def initialize(metric, options = {})
7
+ super(metric, options)
8
+ end
9
+
10
+ def collect
11
+ end
12
+ end
13
+ end; end; end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+ module LogStash module Instrument module PeriodicPoller
3
+ class PeriodicPollerObserver
4
+ include LogStash::Util::Loggable
5
+
6
+ def initialize(poller)
7
+ @poller = poller
8
+ end
9
+
10
+ def update(time, result, exception)
11
+ if exception
12
+ logger.error("PeriodicPoller exception", :poller => @poller,
13
+ :result => result,
14
+ :exception => exception,
15
+ :executed_at => time)
16
+ end
17
+ end
18
+ end
19
+ end; end; end
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+ require "logstash/instrument/periodic_poller/os"
3
+ require "logstash/instrument/periodic_poller/jvm"
4
+
5
+ module LogStash module Instrument
6
+ # Each PeriodPoller manager his own thread to do the poller
7
+ # of the stats, this class encapsulate the starting and stopping of the poller
8
+ # if the unique timer uses too much resource we can refactor this behavior here.
9
+ class PeriodicPollers
10
+ attr_reader :metric
11
+
12
+ def initialize(metric)
13
+ @metric = metric
14
+ @periodic_pollers = [PeriodicPoller::Os.new(metric),
15
+ PeriodicPoller::JVM.new(metric)]
16
+ end
17
+
18
+ def start
19
+ @periodic_pollers.map(&:start)
20
+ end
21
+
22
+ def stop
23
+ @periodic_pollers.map(&:stop)
24
+ end
25
+ end
26
+ end; end