logstash-core 5.5.3-java → 5.6.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/logstash-core/logstash-core.jar +0 -0
- data/lib/logstash-core/version.rb +1 -1
- data/lib/logstash/api/commands/node.rb +2 -2
- data/lib/logstash/api/commands/stats.rb +2 -2
- data/lib/logstash/config/config_ast.rb +24 -1
- data/lib/logstash/config/modules_common.rb +47 -15
- data/lib/logstash/config/source/modules.rb +55 -0
- data/lib/logstash/config/string_escape.rb +27 -0
- data/lib/logstash/elasticsearch_client.rb +24 -2
- data/lib/logstash/environment.rb +2 -0
- data/lib/logstash/filter_delegator.rb +9 -6
- data/lib/logstash/instrument/collector.rb +7 -5
- data/lib/logstash/instrument/metric_store.rb +11 -11
- data/lib/logstash/instrument/namespaced_metric.rb +4 -0
- data/lib/logstash/instrument/namespaced_null_metric.rb +4 -0
- data/lib/logstash/instrument/null_metric.rb +10 -0
- data/lib/logstash/instrument/periodic_poller/dlq.rb +19 -0
- data/lib/logstash/instrument/periodic_pollers.rb +3 -1
- data/lib/logstash/instrument/wrapped_write_client.rb +33 -24
- data/lib/logstash/logging/logger.rb +26 -19
- data/lib/logstash/modules/{importer.rb → elasticsearch_importer.rb} +3 -3
- data/lib/logstash/modules/kibana_base.rb +24 -0
- data/lib/logstash/modules/kibana_client.rb +124 -0
- data/lib/logstash/modules/kibana_config.rb +29 -28
- data/lib/logstash/modules/kibana_dashboards.rb +36 -0
- data/lib/logstash/modules/kibana_importer.rb +17 -0
- data/lib/logstash/modules/kibana_settings.rb +40 -0
- data/lib/logstash/modules/logstash_config.rb +89 -17
- data/lib/logstash/modules/resource_base.rb +6 -5
- data/lib/logstash/modules/scaffold.rb +11 -3
- data/lib/logstash/modules/settings_merger.rb +23 -0
- data/lib/logstash/modules/util.rb +17 -0
- data/lib/logstash/output_delegator.rb +7 -5
- data/lib/logstash/pipeline.rb +34 -2
- data/lib/logstash/runner.rb +8 -13
- data/lib/logstash/settings.rb +20 -1
- data/lib/logstash/util/wrapped_acked_queue.rb +5 -24
- data/lib/logstash/util/wrapped_synchronous_queue.rb +14 -24
- data/lib/logstash/version.rb +1 -1
- data/locales/en.yml +11 -4
- data/spec/logstash/agent_spec.rb +19 -6
- data/spec/logstash/api/modules/node_spec.rb +2 -1
- data/spec/logstash/config/config_ast_spec.rb +47 -8
- data/spec/logstash/config/string_escape_spec.rb +24 -0
- data/spec/logstash/event_spec.rb +9 -0
- data/spec/logstash/filter_delegator_spec.rb +21 -7
- data/spec/logstash/instrument/periodic_poller/dlq_spec.rb +17 -0
- data/spec/logstash/instrument/periodic_poller/jvm_spec.rb +1 -1
- data/spec/logstash/legacy_ruby_event_spec.rb +4 -4
- data/spec/logstash/modules/logstash_config_spec.rb +56 -0
- data/spec/logstash/modules/scaffold_spec.rb +234 -0
- data/spec/logstash/output_delegator_spec.rb +15 -5
- data/spec/logstash/pipeline_spec.rb +76 -26
- data/spec/logstash/runner_spec.rb +46 -25
- data/spec/logstash/settings/splittable_string_array_spec.rb +51 -0
- data/spec/logstash/util/wrapped_synchronous_queue_spec.rb +0 -22
- metadata +22 -4
- data/lib/logstash/modules/kibana_base_resource.rb +0 -10
- data/lib/logstash/program.rb +0 -14
@@ -39,6 +39,10 @@ module LogStash module Instrument
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
+
def counter(_)
|
43
|
+
NullGauge
|
44
|
+
end
|
45
|
+
|
42
46
|
def namespace(name)
|
43
47
|
raise MetricNoNamespaceProvided if name.nil? || name.empty?
|
44
48
|
NamespacedNullMetric.new(self, name)
|
@@ -49,6 +53,12 @@ module LogStash module Instrument
|
|
49
53
|
end
|
50
54
|
|
51
55
|
private
|
56
|
+
|
57
|
+
class NullGauge
|
58
|
+
def self.increment(_)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
52
62
|
# Null implementation of the internal timer class
|
53
63
|
#
|
54
64
|
# @see LogStash::Instrument::TimedExecution`
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'logstash/instrument/periodic_poller/base'
|
3
|
+
|
4
|
+
module LogStash module Instrument module PeriodicPoller
|
5
|
+
class DeadLetterQueue < Base
|
6
|
+
def initialize(metric, agent, options = {})
|
7
|
+
super(metric, options)
|
8
|
+
@metric = metric
|
9
|
+
@agent = agent
|
10
|
+
end
|
11
|
+
|
12
|
+
def collect
|
13
|
+
_, pipeline = @agent.running_pipelines.first
|
14
|
+
unless pipeline.nil?
|
15
|
+
pipeline.collect_dlq_stats
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end end end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
require "logstash/instrument/periodic_poller/dlq"
|
2
3
|
require "logstash/instrument/periodic_poller/os"
|
3
4
|
require "logstash/instrument/periodic_poller/jvm"
|
4
5
|
require "logstash/instrument/periodic_poller/pq"
|
@@ -14,7 +15,8 @@ module LogStash module Instrument
|
|
14
15
|
@metric = metric
|
15
16
|
@periodic_pollers = [PeriodicPoller::Os.new(metric),
|
16
17
|
PeriodicPoller::JVM.new(metric),
|
17
|
-
PeriodicPoller::PersistentQueue.new(metric, queue_type, pipelines)
|
18
|
+
PeriodicPoller::PersistentQueue.new(metric, queue_type, pipelines),
|
19
|
+
PeriodicPoller::DeadLetterQueue.new(metric, pipelines)]
|
18
20
|
end
|
19
21
|
|
20
22
|
def start
|
@@ -10,7 +10,12 @@ module LogStash module Instrument
|
|
10
10
|
@events_metrics = metric.namespace([:stats, :events])
|
11
11
|
@pipeline_metrics = metric.namespace([:stats, :pipelines, pipeline_id, :events])
|
12
12
|
@plugin_events_metrics = metric.namespace([:stats, :pipelines, pipeline_id, :plugins, plugin_type, plugin.id.to_sym, :events])
|
13
|
-
|
13
|
+
@events_metrics_counter = @events_metrics.counter(:in)
|
14
|
+
@events_metrics_time = @events_metrics.counter(:queue_push_duration_in_millis)
|
15
|
+
@pipeline_metrics_counter = @pipeline_metrics.counter(:in)
|
16
|
+
@pipeline_metrics_time = @pipeline_metrics.counter(:queue_push_duration_in_millis)
|
17
|
+
@plugin_events_metrics_counter = @plugin_events_metrics.counter(:out)
|
18
|
+
@plugin_events_metrics_time = @plugin_events_metrics.counter(:queue_push_duration_in_millis)
|
14
19
|
define_initial_metrics_values
|
15
20
|
end
|
16
21
|
|
@@ -19,41 +24,45 @@ module LogStash module Instrument
|
|
19
24
|
end
|
20
25
|
|
21
26
|
def push(event)
|
22
|
-
|
27
|
+
increment_counters(1)
|
28
|
+
start_time = java.lang.System.current_time_millis
|
29
|
+
result = @write_client.push(event)
|
30
|
+
report_execution_time(start_time)
|
31
|
+
result
|
23
32
|
end
|
33
|
+
|
24
34
|
alias_method(:<<, :push)
|
25
35
|
|
26
36
|
def push_batch(batch)
|
27
|
-
|
37
|
+
increment_counters(batch.size)
|
38
|
+
start_time = java.lang.System.current_time_millis
|
39
|
+
result = @write_client.push_batch(batch)
|
40
|
+
report_execution_time(start_time)
|
41
|
+
result
|
28
42
|
end
|
29
43
|
|
30
44
|
private
|
31
|
-
def record_metric(size = 1)
|
32
|
-
@events_metrics.increment(:in, size)
|
33
|
-
@pipeline_metrics.increment(:in, size)
|
34
|
-
@plugin_events_metrics.increment(:out, size)
|
35
|
-
|
36
|
-
clock = @events_metrics.time(:queue_push_duration_in_millis)
|
37
45
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
@pipeline_metrics.report_time(:queue_push_duration_in_millis, execution_time)
|
44
|
-
@plugin_events_metrics.report_time(:queue_push_duration_in_millis, execution_time)
|
46
|
+
def increment_counters(size)
|
47
|
+
@events_metrics_counter.increment(size)
|
48
|
+
@pipeline_metrics_counter.increment(size)
|
49
|
+
@plugin_events_metrics_counter.increment(size)
|
50
|
+
end
|
45
51
|
|
46
|
-
|
52
|
+
def report_execution_time(start_time)
|
53
|
+
execution_time = java.lang.System.current_time_millis - start_time
|
54
|
+
@events_metrics_time.increment(execution_time)
|
55
|
+
@pipeline_metrics_time.increment(execution_time)
|
56
|
+
@plugin_events_metrics_time.increment(execution_time)
|
47
57
|
end
|
48
58
|
|
49
59
|
def define_initial_metrics_values
|
50
|
-
@
|
51
|
-
@
|
52
|
-
@
|
53
|
-
|
54
|
-
@
|
55
|
-
@
|
56
|
-
@plugin_events_metrics.report_time(:queue_push_duration_in_millis, 0)
|
60
|
+
@events_metrics_counter.increment(0)
|
61
|
+
@pipeline_metrics_counter.increment(0)
|
62
|
+
@plugin_events_metrics_counter.increment(0)
|
63
|
+
@events_metrics_time.increment(0)
|
64
|
+
@pipeline_metrics_time.increment(0)
|
65
|
+
@plugin_events_metrics_time.increment(0)
|
57
66
|
end
|
58
67
|
end
|
59
68
|
end end
|
@@ -8,10 +8,12 @@ module LogStash
|
|
8
8
|
java_import org.apache.logging.log4j.core.config.Configurator
|
9
9
|
java_import org.apache.logging.log4j.core.config.DefaultConfiguration
|
10
10
|
java_import org.apache.logging.log4j.core.config.LoggerConfig
|
11
|
+
java_import org.logstash.log.LogstashLoggerContextFactory
|
12
|
+
java_import org.apache.logging.log4j.core.LoggerContext
|
13
|
+
java_import java.net.URI
|
11
14
|
|
12
15
|
class Logger
|
13
16
|
@@config_mutex = Mutex.new
|
14
|
-
@@logging_context = nil
|
15
17
|
|
16
18
|
def initialize(name)
|
17
19
|
@logger = LogManager.getLogger(name)
|
@@ -71,45 +73,50 @@ module LogStash
|
|
71
73
|
raise ArgumentError, "invalid level[#{level}] for logger[#{path}]"
|
72
74
|
end
|
73
75
|
|
74
|
-
def self.
|
76
|
+
def self.reconfigure(config_location)
|
75
77
|
@@config_mutex.synchronize do
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
78
|
+
config_location_uri = URI.create(config_location)
|
79
|
+
file_path = config_location_uri.path
|
80
|
+
if ::File.exists?(file_path)
|
81
|
+
logs_location = java.lang.System.getProperty("ls.logs")
|
82
|
+
puts "Sending Logstash's logs to #{logs_location} which is now configured via log4j2.properties"
|
83
|
+
#reconfigure the default context to use our log4j2.properties file
|
84
|
+
get_logging_context.setConfigLocation(URI.create(config_location))
|
85
|
+
#ensure everyone agrees which context to use for the LogManager
|
86
|
+
context_factory = LogstashLoggerContextFactory.new(get_logging_context)
|
87
|
+
LogManager.setFactory(context_factory)
|
88
|
+
else
|
89
|
+
# fall back to default config
|
90
|
+
puts "Could not find log4j2 configuration at path #{file_path}. Using default config which logs errors to the console"
|
87
91
|
end
|
88
92
|
end
|
89
93
|
end
|
90
94
|
|
95
|
+
# until dev_utils/rspec/spec_helper is changed, we need to have both methods
|
96
|
+
singleton_class.send(:alias_method, :initialize, :reconfigure)
|
97
|
+
|
91
98
|
def self.get_logging_context
|
92
|
-
return
|
99
|
+
return LoggerContext.getContext(false)
|
93
100
|
end
|
94
101
|
|
95
|
-
# Clone of org.apache.logging.log4j.core.config.Configurator.setLevel(), but
|
102
|
+
# Clone of org.apache.logging.log4j.core.config.Configurator.setLevel(), but ensure the proper context is used
|
96
103
|
def self.set_level(_level, path)
|
97
|
-
configuration =
|
104
|
+
configuration = get_logging_context.getConfiguration()
|
98
105
|
level = Level.valueOf(_level)
|
99
106
|
if path.nil? || path.strip.empty?
|
100
107
|
root_logger = configuration.getRootLogger()
|
101
108
|
if root_logger.getLevel() != level
|
102
109
|
root_logger.setLevel(level)
|
103
|
-
|
110
|
+
get_logging_context.updateLoggers()
|
104
111
|
end
|
105
112
|
else
|
106
113
|
package_logger = configuration.getLoggerConfig(path)
|
107
114
|
if package_logger.name != path #no package logger found
|
108
115
|
configuration.addLogger(path, LoggerConfig.new(path, level, true))
|
109
|
-
|
116
|
+
get_logging_context.updateLoggers()
|
110
117
|
elsif package_logger.getLevel() != level
|
111
118
|
package_logger.setLevel(level)
|
112
|
-
|
119
|
+
get_logging_context.updateLoggers()
|
113
120
|
end
|
114
121
|
end
|
115
122
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
require "logstash/namespace"
|
3
3
|
require "logstash/logging"
|
4
4
|
|
5
|
-
module LogStash module Modules class
|
5
|
+
module LogStash module Modules class ElasticsearchImporter
|
6
6
|
include LogStash::Util::Loggable
|
7
7
|
|
8
8
|
def initialize(client)
|
@@ -11,7 +11,7 @@ module LogStash module Modules class Importer
|
|
11
11
|
|
12
12
|
def put(resource, overwrite = true)
|
13
13
|
path = resource.import_path
|
14
|
-
logger.
|
14
|
+
logger.debug("Attempting PUT", :url_path => path, :file_path => resource.content_path)
|
15
15
|
if !overwrite && content_exists?(path)
|
16
16
|
logger.debug("Found existing Elasticsearch resource.", :resource => path)
|
17
17
|
return
|
@@ -31,7 +31,7 @@ module LogStash module Modules class Importer
|
|
31
31
|
|
32
32
|
def content_exists?(path)
|
33
33
|
response = @client.head(path)
|
34
|
-
response.status >= 200 && response.status
|
34
|
+
response.status >= 200 && response.status < 300
|
35
35
|
end
|
36
36
|
|
37
37
|
end end end # class LogStash::Modules::Importer
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/namespace"
|
3
|
+
require "logstash/json"
|
4
|
+
|
5
|
+
module LogStash module Modules class KibanaBase
|
6
|
+
attr_reader :import_path, :content
|
7
|
+
|
8
|
+
def initialize(import_path, content)
|
9
|
+
@import_path, @content = import_path, content
|
10
|
+
end
|
11
|
+
|
12
|
+
def import(client)
|
13
|
+
raise NotImplementedError, "#{self.class.name} needs to implement `#import`"
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
import_path
|
18
|
+
end
|
19
|
+
|
20
|
+
def content_as_object
|
21
|
+
return content unless content.is_a?(String)
|
22
|
+
LogStash::Json.load(content) rescue nil
|
23
|
+
end
|
24
|
+
end end end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/namespace"
|
3
|
+
require "logstash/logging"
|
4
|
+
require "logstash/json"
|
5
|
+
require "manticore/client"
|
6
|
+
|
7
|
+
module LogStash module Modules class KibanaClient
|
8
|
+
include LogStash::Util::Loggable
|
9
|
+
|
10
|
+
class Response
|
11
|
+
# to create a custom response with body as an Object (Hash or Array)
|
12
|
+
attr_reader :status, :body, :headers
|
13
|
+
def initialize(status, body, headers={})
|
14
|
+
@status, @body, @headers = status, body, headers
|
15
|
+
@body = body.is_a?(String) ? LogStash::Json.load(body) : body
|
16
|
+
end
|
17
|
+
|
18
|
+
def succeeded?
|
19
|
+
@status >= 200 && @status < 300
|
20
|
+
end
|
21
|
+
|
22
|
+
def failed?
|
23
|
+
!succeeded?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_reader :version
|
28
|
+
|
29
|
+
def initialize(settings)
|
30
|
+
@settings = settings
|
31
|
+
|
32
|
+
client_options = {
|
33
|
+
request_timeout: 5,
|
34
|
+
connect_timeout: 5,
|
35
|
+
socket_timeout: 5,
|
36
|
+
pool_max: 10,
|
37
|
+
pool_max_per_route: 2
|
38
|
+
}
|
39
|
+
|
40
|
+
ssl_options = {}
|
41
|
+
|
42
|
+
if @settings["var.kibana.ssl.enabled"] == "true"
|
43
|
+
ssl_options[:verify] = @settings.fetch("var.kibana.ssl.verification_mode", "strict").to_sym
|
44
|
+
ssl_options[:ca_file] = @settings.fetch("var.kibana.ssl.certificate_authority", nil)
|
45
|
+
ssl_options[:client_cert] = @settings.fetch("var.kibana.ssl.certificate", nil)
|
46
|
+
ssl_options[:client_key] = @settings.fetch("var.kibana.ssl.key", nil)
|
47
|
+
end
|
48
|
+
|
49
|
+
client_options[:ssl] = ssl_options
|
50
|
+
|
51
|
+
@client = Manticore::Client.new(client_options)
|
52
|
+
@host = @settings.fetch("var.kibana.host", "localhost:5601")
|
53
|
+
username = @settings["var.kibana.username"]
|
54
|
+
password = @settings["var.kibana.password"]
|
55
|
+
|
56
|
+
@scheme = @settings.fetch("var.kibana.scheme", "http")
|
57
|
+
@http_options = {:headers => {'Content-Type' => 'application/json'}}
|
58
|
+
if username
|
59
|
+
@http_options[:headers]['Authorization'] = 'Basic ' + Base64.encode64( "#{username}:#{password}" ).chomp
|
60
|
+
end
|
61
|
+
|
62
|
+
# e.g. {"name":"Elastics-MacBook-Pro.local","version":{"number":"6.0.0-alpha3","build_hash":"41e69","build_number":15613,"build_snapshot":true}..}
|
63
|
+
@version = "0.0.0"
|
64
|
+
response = get("api/status")
|
65
|
+
if response.succeeded?
|
66
|
+
status = response.body
|
67
|
+
if status["version"].is_a?(Hash)
|
68
|
+
@version = status["version"]["number"]
|
69
|
+
if status["version"]["build_snapshot"]
|
70
|
+
@version.concat("-SNAPSHOT")
|
71
|
+
end
|
72
|
+
else
|
73
|
+
@version = status["version"]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
@http_options[:headers]['kbn-version'] = @version
|
77
|
+
end
|
78
|
+
|
79
|
+
def version_parts
|
80
|
+
@version.split(/\.|\-/)
|
81
|
+
end
|
82
|
+
|
83
|
+
def host_settings
|
84
|
+
"[\"#{@host}\"]"
|
85
|
+
end
|
86
|
+
|
87
|
+
def get(relative_path)
|
88
|
+
# e.g. api/kibana/settings
|
89
|
+
safely(:get, relative_path, @http_options)
|
90
|
+
end
|
91
|
+
|
92
|
+
# content will be converted to a json string
|
93
|
+
def post(relative_path, content, headers = nil)
|
94
|
+
|
95
|
+
body = content.is_a?(String) ? content : LogStash::Json.dump(content)
|
96
|
+
options = {:body => body}.merge(headers || @http_options)
|
97
|
+
safely(:post, relative_path, options)
|
98
|
+
end
|
99
|
+
|
100
|
+
def head(relative_path)
|
101
|
+
safely(:head, relative_path, @http_options)
|
102
|
+
end
|
103
|
+
|
104
|
+
def can_connect?
|
105
|
+
head("api/status").succeeded?
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def safely(method_sym, relative_path, options = {})
|
111
|
+
begin
|
112
|
+
resp = @client.http(method_sym, full_url(relative_path), options).call
|
113
|
+
Response.new(resp.code, resp.body, resp.headers)
|
114
|
+
rescue Manticore::ManticoreException => e
|
115
|
+
logger.error("Error when executing Kibana client request", :error => e)
|
116
|
+
body = {"statusCode" => 0, "error" => e.message}
|
117
|
+
Response.new(0, body, {})
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def full_url(relative)
|
122
|
+
"#{@scheme}://#{@host}/#{relative}"
|
123
|
+
end
|
124
|
+
end end end
|
@@ -3,22 +3,26 @@ require "logstash/namespace"
|
|
3
3
|
require "logstash/logging"
|
4
4
|
|
5
5
|
require_relative "file_reader"
|
6
|
+
require_relative "kibana_settings"
|
7
|
+
require_relative "kibana_dashboards"
|
6
8
|
require_relative "kibana_resource"
|
7
|
-
require_relative "kibana_base_resource"
|
8
9
|
|
9
10
|
module LogStash module Modules class KibanaConfig
|
10
11
|
include LogStash::Util::Loggable
|
11
12
|
|
12
13
|
ALLOWED_DIRECTORIES = ["search", "visualization"]
|
13
|
-
|
14
|
-
attr_reader :index_name
|
14
|
+
attr_reader :index_name # not used when importing via kibana but for BWC with ElastsearchConfig
|
15
15
|
|
16
16
|
# We name it `modul` here because `module` has meaning in Ruby.
|
17
17
|
def initialize(modul, settings)
|
18
18
|
@directory = ::File.join(modul.directory, "kibana")
|
19
19
|
@name = modul.module_name
|
20
20
|
@settings = settings
|
21
|
-
@index_name =
|
21
|
+
@index_name = "kibana"
|
22
|
+
@pattern_name = "#{@name}-*"
|
23
|
+
@kibana_settings = [
|
24
|
+
KibanaSettings::Setting.new("defaultIndex", @pattern_name)
|
25
|
+
]
|
22
26
|
end
|
23
27
|
|
24
28
|
def dashboards
|
@@ -30,21 +34,20 @@ module LogStash module Modules class KibanaConfig
|
|
30
34
|
end
|
31
35
|
|
32
36
|
def index_pattern
|
33
|
-
|
34
|
-
default_index_json = '{"defaultIndex": "#{pattern_name}"}'
|
35
|
-
default_index_content_id = @settings.fetch("index_pattern.kibana_version", "5.5.1")
|
36
|
-
[
|
37
|
-
KibanaResource.new(@index_name, "index-pattern", dynamic("index-pattern"),nil, pattern_name),
|
38
|
-
KibanaResource.new(@index_name, "config", nil, default_index_json, default_index_content_id)
|
39
|
-
]
|
37
|
+
[KibanaResource.new(@index_name, "index-pattern", dynamic("index-pattern"),nil, @pattern_name)]
|
40
38
|
end
|
41
39
|
|
42
40
|
def resources
|
43
41
|
list = index_pattern
|
44
42
|
dashboards.each do |board|
|
43
|
+
list << board
|
45
44
|
extract_panels_into(board, list)
|
46
45
|
end
|
47
|
-
list.concat(
|
46
|
+
list.concat(extract_saved_searches_into(list))
|
47
|
+
[
|
48
|
+
KibanaSettings.new("api/kibana/settings", @kibana_settings),
|
49
|
+
KibanaDashboards.new("api/kibana/dashboards/import", list)
|
50
|
+
]
|
48
51
|
end
|
49
52
|
|
50
53
|
private
|
@@ -54,9 +57,7 @@ module LogStash module Modules class KibanaConfig
|
|
54
57
|
end
|
55
58
|
|
56
59
|
def extract_panels_into(dashboard, list)
|
57
|
-
|
58
|
-
|
59
|
-
dash = FileReader.read_json(dashboard.content_path)
|
60
|
+
dash = dashboard.content_as_object
|
60
61
|
|
61
62
|
if !dash.is_a?(Hash)
|
62
63
|
logger.warn("Kibana dashboard JSON is not an Object", :module => @name)
|
@@ -85,20 +86,20 @@ module LogStash module Modules class KibanaConfig
|
|
85
86
|
logger.warn("panelJSON contained unknown type", :type => panel_type)
|
86
87
|
end
|
87
88
|
end
|
89
|
+
end
|
88
90
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
end
|
101
|
-
result
|
91
|
+
def extract_saved_searches_into(list)
|
92
|
+
result = [] # must not add to list while iterating
|
93
|
+
list.each do |resource|
|
94
|
+
content = resource.content_as_object
|
95
|
+
next if content.nil?
|
96
|
+
next unless content.keys.include?("savedSearchId")
|
97
|
+
saved_search = content["savedSearchId"]
|
98
|
+
next if saved_search.nil?
|
99
|
+
ss_resource = KibanaResource.new(@index_name, "search", dynamic("search", saved_search))
|
100
|
+
next if list.member?(ss_resource) || result.member?(ss_resource)
|
101
|
+
result << ss_resource
|
102
102
|
end
|
103
|
+
result
|
103
104
|
end
|
104
105
|
end end end
|