logstash-core 5.0.0.alpha3.snapshot5-java → 5.0.0.alpha3.snapshot6-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/logstash-core/version.rb +1 -1
- data/lib/logstash/api/{lib/helpers/app_helpers.rb → app_helpers.rb} +0 -0
- data/lib/logstash/api/command_factory.rb +34 -0
- data/lib/logstash/api/commands/base.rb +25 -0
- data/lib/logstash/api/commands/stats.rb +105 -0
- data/lib/logstash/api/commands/system/basicinfo_command.rb +23 -0
- data/lib/logstash/api/commands/system/plugins_command.rb +35 -0
- data/lib/logstash/api/modules/base.rb +41 -0
- data/lib/logstash/api/modules/node.rb +24 -0
- data/lib/logstash/api/modules/node_stats.rb +59 -0
- data/lib/logstash/api/modules/plugins.rb +15 -0
- data/lib/logstash/api/modules/root.rb +15 -0
- data/lib/logstash/api/modules/stats.rb +63 -0
- data/lib/logstash/api/rack_app.rb +33 -0
- data/lib/logstash/api/service.rb +73 -0
- data/lib/logstash/instrument/metric_store.rb +11 -1
- data/lib/logstash/instrument/periodic_poller/base.rb +2 -0
- data/lib/logstash/instrument/periodic_poller/jvm.rb +47 -2
- data/lib/logstash/util/thread_dump.rb +55 -0
- data/lib/logstash/version.rb +1 -1
- data/lib/logstash/webserver.rb +15 -49
- data/locales/en.yml +5 -5
- data/logstash-core.gemspec +3 -3
- data/spec/api/lib/api/node_spec.rb +2 -2
- data/spec/api/lib/api/node_stats_spec.rb +32 -57
- data/spec/api/lib/api/plugins_spec.rb +2 -2
- data/spec/api/lib/api/root_spec.rb +2 -2
- data/spec/api/lib/api/support/resource_dsl_methods.rb +47 -0
- data/spec/api/lib/commands/stats.rb +47 -0
- data/spec/api/spec_helper.rb +2 -5
- data/spec/logstash/agent_spec.rb +1 -1
- data/spec/logstash/instrument/periodic_poller/jvm_spec.rb +45 -0
- metadata +30 -38
- data/lib/logstash/api/init.ru +0 -31
- data/lib/logstash/api/lib/app.rb +0 -40
- data/lib/logstash/api/lib/app/command.rb +0 -29
- data/lib/logstash/api/lib/app/command_factory.rb +0 -29
- data/lib/logstash/api/lib/app/commands/stats/events_command.rb +0 -13
- data/lib/logstash/api/lib/app/commands/stats/hotthreads_command.rb +0 -120
- data/lib/logstash/api/lib/app/commands/stats/memory_command.rb +0 -25
- data/lib/logstash/api/lib/app/commands/system/basicinfo_command.rb +0 -15
- data/lib/logstash/api/lib/app/commands/system/plugins_command.rb +0 -28
- data/lib/logstash/api/lib/app/modules/node.rb +0 -25
- data/lib/logstash/api/lib/app/modules/node_stats.rb +0 -51
- data/lib/logstash/api/lib/app/modules/plugins.rb +0 -15
- data/lib/logstash/api/lib/app/modules/stats.rb +0 -21
- data/lib/logstash/api/lib/app/root.rb +0 -13
- data/lib/logstash/api/lib/app/service.rb +0 -61
- data/lib/logstash/api/lib/app/stats.rb +0 -56
- data/spec/api/lib/api/stats_spec.rb +0 -19
- data/spec/api/lib/commands/events_spec.rb +0 -17
- data/spec/api/lib/commands/jvm_spec.rb +0 -45
@@ -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
|
@@ -86,7 +86,7 @@ module LogStash module Instrument
|
|
86
86
|
|
87
87
|
# Similar to `get_with_path` but use symbols instead of string
|
88
88
|
#
|
89
|
-
# @param [Array<Symbol>
|
89
|
+
# @param [Array<Symbol>]
|
90
90
|
# @return [Hash]
|
91
91
|
def get(*key_paths)
|
92
92
|
# Normalize the symbols access
|
@@ -100,6 +100,16 @@ module LogStash module Instrument
|
|
100
100
|
new_hash
|
101
101
|
end
|
102
102
|
|
103
|
+
# Retrieve values like `get`, but don't return them fully nested.
|
104
|
+
# This means that if you call `get_shallow(:foo, :bar)` the result will not
|
105
|
+
# be nested inside of `{:foo {:bar => values}`.
|
106
|
+
#
|
107
|
+
# @param [Array<Symbol>]
|
108
|
+
# @return [Hash]
|
109
|
+
def get_shallow(*key_paths)
|
110
|
+
key_paths.reduce(get(*key_paths)) {|acc, p| acc[p]}
|
111
|
+
end
|
112
|
+
|
103
113
|
# Return all the individuals Metric,
|
104
114
|
# This call mimic a Enum's each if a block is provided
|
105
115
|
#
|
@@ -37,6 +37,8 @@ module LogStash module Instrument module PeriodicPoller
|
|
37
37
|
logger.debug("PeriodicPoller: Starting",
|
38
38
|
:polling_interval => @options[:polling_interval],
|
39
39
|
:polling_timeout => @options[:polling_timeout]) if logger.debug?
|
40
|
+
|
41
|
+
collect # Collect data right away if possible
|
40
42
|
@task.execute
|
41
43
|
end
|
42
44
|
|
@@ -1,6 +1,15 @@
|
|
1
|
+
|
1
2
|
# encoding: utf-8
|
2
3
|
require "logstash/instrument/periodic_poller/base"
|
3
|
-
require '
|
4
|
+
require 'jrmonitor'
|
5
|
+
|
6
|
+
java_import 'java.lang.management.ManagementFactory'
|
7
|
+
java_import 'java.lang.management.OperatingSystemMXBean'
|
8
|
+
java_import 'com.sun.management.UnixOperatingSystemMXBean'
|
9
|
+
java_import 'javax.management.MBeanServer'
|
10
|
+
java_import 'javax.management.ObjectName'
|
11
|
+
java_import 'javax.management.AttributeList'
|
12
|
+
java_import 'javax.naming.directory.Attribute'
|
4
13
|
|
5
14
|
module LogStash module Instrument module PeriodicPoller
|
6
15
|
class JVM < Base
|
@@ -13,14 +22,50 @@ module LogStash module Instrument module PeriodicPoller
|
|
13
22
|
end
|
14
23
|
|
15
24
|
def collect
|
16
|
-
raw = JRMonitor.memory.generate
|
25
|
+
raw = JRMonitor.memory.generate
|
17
26
|
collect_heap_metrics(raw)
|
18
27
|
collect_non_heap_metrics(raw)
|
19
28
|
collect_pools_metrics(raw)
|
29
|
+
collect_threads_metrics
|
30
|
+
collect_process_metrics
|
20
31
|
end
|
21
32
|
|
22
33
|
private
|
23
34
|
|
35
|
+
def collect_threads_metrics
|
36
|
+
threads = JRMonitor.threads.generate
|
37
|
+
|
38
|
+
current = threads.count
|
39
|
+
if @peak_threads.nil? || @peak_threads < current
|
40
|
+
@peak_threads = current
|
41
|
+
end
|
42
|
+
|
43
|
+
metric.gauge([:jvm, :threads], :count, threads.count)
|
44
|
+
metric.gauge([:jvm, :threads], :peak_count, @peak_threads)
|
45
|
+
end
|
46
|
+
|
47
|
+
def collect_process_metrics
|
48
|
+
process_metrics = JRMonitor.process.generate
|
49
|
+
|
50
|
+
path = [:jvm, :process]
|
51
|
+
|
52
|
+
|
53
|
+
open_fds = process_metrics["open_file_descriptors"]
|
54
|
+
if @peak_open_fds.nil? || open_fds > @peak_open_fds
|
55
|
+
@peak_open_fds = open_fds
|
56
|
+
end
|
57
|
+
metric.gauge(path, :open_file_descriptors, open_fds)
|
58
|
+
metric.gauge(path, :peak_open_file_descriptors, @peak_open_fds)
|
59
|
+
metric.gauge(path, :max_file_descriptors, process_metrics["max_file_descriptors"])
|
60
|
+
|
61
|
+
cpu_path = path + [:cpu]
|
62
|
+
cpu_metrics = process_metrics["cpu"]
|
63
|
+
metric.gauge(cpu_path, :percent, cpu_metrics["process_percent"])
|
64
|
+
metric.gauge(cpu_path, :total_in_millis, cpu_metrics["total_in_millis"])
|
65
|
+
|
66
|
+
metric.gauge(path + [:mem], :total_virtual_in_bytes, process_metrics["mem"]["total_virtual_in_bytes"])
|
67
|
+
end
|
68
|
+
|
24
69
|
def collect_heap_metrics(data)
|
25
70
|
heap = aggregate_information_for(data["heap"].values)
|
26
71
|
heap[:used_percent] = (heap[:used_in_bytes] / heap[:max_in_bytes].to_f)*100.0
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module LogStash
|
3
|
+
module Util
|
4
|
+
class ThreadDump
|
5
|
+
SKIPPED_THREADS = [ "Finalizer", "Reference Handler", "Signal Dispatcher" ].freeze
|
6
|
+
THREADS_COUNT_DEFAULT = 3.freeze
|
7
|
+
IGNORE_IDLE_THREADS_DEFAULT = true.freeze
|
8
|
+
|
9
|
+
attr_reader :top_count, :ignore, :dump
|
10
|
+
|
11
|
+
def initialize(options={})
|
12
|
+
@options = options
|
13
|
+
@dump = options.fetch(:dump, JRMonitor.threads.generate({}))
|
14
|
+
@top_count = options.fetch(:threads, THREADS_COUNT_DEFAULT)
|
15
|
+
@ignore = options.fetch(:ignore_idle_threads, IGNORE_IDLE_THREADS_DEFAULT)
|
16
|
+
end
|
17
|
+
|
18
|
+
def each(&block)
|
19
|
+
i=0
|
20
|
+
dump.each_pair do |thread_name, _hash|
|
21
|
+
break if i >= top_count
|
22
|
+
if ignore
|
23
|
+
next if idle_thread?(thread_name, _hash)
|
24
|
+
end
|
25
|
+
block.call(thread_name, _hash)
|
26
|
+
i += 1
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def idle_thread?(thread_name, data)
|
31
|
+
idle = false
|
32
|
+
if SKIPPED_THREADS.include?(thread_name)
|
33
|
+
# these are likely JVM dependent
|
34
|
+
idle = true
|
35
|
+
elsif thread_name.match(/Ruby-\d+-JIT-\d+/)
|
36
|
+
# This are internal JRuby JIT threads,
|
37
|
+
# see java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor for details.
|
38
|
+
idle = true
|
39
|
+
elsif thread_name.match(/pool-\d+-thread-\d+/)
|
40
|
+
# This are threads used by the internal JRuby implementation to dispatch
|
41
|
+
# calls and tasks, see prg.jruby.internal.runtime.methods.DynamicMethod.call
|
42
|
+
idle = true
|
43
|
+
else
|
44
|
+
data["thread.stacktrace"].each do |trace|
|
45
|
+
if trace.start_with?("java.util.concurrent.ThreadPoolExecutor.getTask")
|
46
|
+
idle = true
|
47
|
+
break
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
idle
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/logstash/version.rb
CHANGED
data/lib/logstash/webserver.rb
CHANGED
@@ -1,16 +1,15 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require "puma"
|
3
|
-
require "puma/
|
4
|
-
require "
|
5
|
-
require "
|
6
|
-
require "
|
3
|
+
require "puma/server"
|
4
|
+
require "sinatra"
|
5
|
+
require "rack"
|
6
|
+
require "logstash/api/rack_app"
|
7
7
|
|
8
8
|
module LogStash
|
9
9
|
class WebServer
|
10
|
-
|
11
10
|
extend Forwardable
|
12
11
|
|
13
|
-
attr_reader :logger, :status, :config, :options, :cli_options, :runner, :binder, :events
|
12
|
+
attr_reader :logger, :status, :config, :options, :cli_options, :runner, :binder, :events, :http_host, :http_port
|
14
13
|
|
15
14
|
def_delegator :@runner, :stats
|
16
15
|
|
@@ -19,8 +18,8 @@ module LogStash
|
|
19
18
|
|
20
19
|
def initialize(logger, options={})
|
21
20
|
@logger = logger
|
22
|
-
http_host = options[:http_host] || DEFAULT_HOST
|
23
|
-
http_port = options[:http_port] || DEFAULT_PORT
|
21
|
+
@http_host = options[:http_host] || DEFAULT_HOST
|
22
|
+
@http_port = options[:http_port] || DEFAULT_PORT
|
24
23
|
@options = {}
|
25
24
|
@cli_options = options.merge({ :rackup => ::File.join(::File.dirname(__FILE__), "api", "init.ru"),
|
26
25
|
:binds => ["tcp://#{http_host}:#{http_port}"],
|
@@ -31,24 +30,17 @@ module LogStash
|
|
31
30
|
:queue_requests => false
|
32
31
|
})
|
33
32
|
@status = nil
|
34
|
-
|
35
|
-
parse_options
|
36
|
-
|
37
|
-
@runner = nil
|
38
|
-
@events = ::Puma::Events.strings
|
39
|
-
@binder = ::Puma::Binder.new(@events)
|
40
|
-
@binder.import_from_env
|
41
|
-
|
42
|
-
set_environment
|
43
33
|
end
|
44
34
|
|
45
35
|
def run
|
46
36
|
log "=== puma start: #{Time.now} ==="
|
47
37
|
|
48
|
-
|
49
|
-
|
50
|
-
@
|
51
|
-
|
38
|
+
stop # Just in case
|
39
|
+
|
40
|
+
@server = ::Puma::Server.new(LogStash::Api::RackApp.app)
|
41
|
+
@server.add_tcp_listener(http_host, http_port)
|
42
|
+
|
43
|
+
@server.run.join
|
52
44
|
end
|
53
45
|
|
54
46
|
def log(str)
|
@@ -58,7 +50,7 @@ module LogStash
|
|
58
50
|
def error(str)
|
59
51
|
logger.error(str)
|
60
52
|
end
|
61
|
-
|
53
|
+
|
62
54
|
# Empty method, this method is required because of the puma usage we make through
|
63
55
|
# the Single interface, https://github.com/puma/puma/blob/master/lib/puma/single.rb#L82
|
64
56
|
# for more details. This can always be implemented when we want to keep track of this
|
@@ -66,33 +58,7 @@ module LogStash
|
|
66
58
|
def write_state; end
|
67
59
|
|
68
60
|
def stop(options={})
|
69
|
-
|
70
|
-
|
71
|
-
if graceful
|
72
|
-
@runner.stop_blocked
|
73
|
-
else
|
74
|
-
@runner.stop
|
75
|
-
end rescue nil
|
76
|
-
|
77
|
-
@status = :stop
|
78
|
-
log "=== puma shutdown: #{Time.now} ==="
|
79
|
-
end
|
80
|
-
|
81
|
-
private
|
82
|
-
|
83
|
-
def env
|
84
|
-
@options[:debug] ? "development" : "production"
|
85
|
-
end
|
86
|
-
|
87
|
-
def set_environment
|
88
|
-
@options[:environment] = env
|
89
|
-
ENV['RACK_ENV'] = env
|
90
|
-
end
|
91
|
-
|
92
|
-
def parse_options
|
93
|
-
@config = ::Puma::Configuration.new(cli_options)
|
94
|
-
@config.load
|
95
|
-
@options = @config.options
|
61
|
+
@server.stop(true) if @server
|
96
62
|
end
|
97
63
|
end
|
98
64
|
end
|
data/locales/en.yml
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# YAML notes
|
2
2
|
# |- means 'scalar block' useful for formatted text
|
3
|
-
# > means 'scalar block' but it chomps all newlines. Useful
|
3
|
+
# > means 'scalar block' but it chomps all newlines. Useful
|
4
4
|
# for unformatted text.
|
5
5
|
en:
|
6
6
|
oops: |-
|
@@ -76,7 +76,7 @@ en:
|
|
76
76
|
hot_threads:
|
77
77
|
title: |-
|
78
78
|
::: {%{hostname}}
|
79
|
-
|
79
|
+
Hot threads at %{time}, busiestThreads=%{top_count}:
|
80
80
|
thread_title: |-
|
81
81
|
%{percent_of_cpu_time} % of cpu usage by %{thread_state} thread named '%{thread_name}'
|
82
82
|
runner:
|
@@ -141,18 +141,18 @@ en:
|
|
141
141
|
after %{after}
|
142
142
|
invalid_plugin_register: >-
|
143
143
|
Cannot register %{plugin} %{type} plugin.
|
144
|
-
The error reported is:
|
144
|
+
The error reported is:
|
145
145
|
%{error}
|
146
146
|
plugin_path_missing: >-
|
147
147
|
You specified a plugin path that does not exist: %{path}
|
148
148
|
no_plugins_found: |-
|
149
149
|
Could not find any plugins in "%{path}"
|
150
|
-
I tried to find files matching the following, but found none:
|
150
|
+
I tried to find files matching the following, but found none:
|
151
151
|
%{plugin_glob}
|
152
152
|
log_file_failed: |-
|
153
153
|
Failed to open %{path} for writing: %{error}
|
154
154
|
|
155
|
-
This is often a permissions issue, or the wrong
|
155
|
+
This is often a permissions issue, or the wrong
|
156
156
|
path was specified?
|
157
157
|
flag:
|
158
158
|
# Note: Wrap these at 55 chars so they display nicely when clamp emits
|
data/logstash-core.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.require_paths = ["lib"]
|
18
18
|
gem.version = LOGSTASH_CORE_VERSION.gsub(/-/, '.')
|
19
19
|
|
20
|
-
gem.add_runtime_dependency "logstash-core-event-java", "5.0.0.alpha3.
|
20
|
+
gem.add_runtime_dependency "logstash-core-event-java", "5.0.0.alpha3.snapshot6"
|
21
21
|
|
22
22
|
gem.add_runtime_dependency "cabin", "~> 0.8.0" #(Apache 2.0 license)
|
23
23
|
gem.add_runtime_dependency "pry", "~> 0.10.1" #(Ruby license)
|
@@ -27,10 +27,10 @@ Gem::Specification.new do |gem|
|
|
27
27
|
gem.add_runtime_dependency "gems", "~> 0.8.3" #(MIT license)
|
28
28
|
gem.add_runtime_dependency "concurrent-ruby", "1.0.0"
|
29
29
|
gem.add_runtime_dependency "sinatra", '~> 1.4', '>= 1.4.6'
|
30
|
-
gem.add_runtime_dependency 'puma', '~>
|
30
|
+
gem.add_runtime_dependency 'puma', '~> 3.4.0'
|
31
31
|
gem.add_runtime_dependency "jruby-openssl", "0.9.16" # >= 0.9.13 Required to support TLSv1.2
|
32
32
|
gem.add_runtime_dependency "chronic_duration", "0.10.6"
|
33
|
-
gem.add_runtime_dependency "
|
33
|
+
gem.add_runtime_dependency "jrmonitor", '~> 0.4.2'
|
34
34
|
|
35
35
|
# TODO(sissel): Treetop 1.5.x doesn't seem to work well, but I haven't
|
36
36
|
# investigated what the cause might be. -Jordan
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require_relative "../../spec_helper"
|
3
3
|
require "sinatra"
|
4
|
-
require "
|
4
|
+
require "logstash/api/modules/node"
|
5
5
|
require "logstash/json"
|
6
6
|
|
7
|
-
describe LogStash::Api::Node do
|
7
|
+
describe LogStash::Api::Modules::Node do
|
8
8
|
|
9
9
|
include Rack::Test::Methods
|
10
10
|
|