logstash-core 6.0.0.alpha2-java → 6.0.0.beta1-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/gemspec_jars.rb +6 -4
- data/lib/logstash-core/logstash-core.jar +0 -0
- data/lib/logstash-core/logstash-core.rb +2 -2
- data/lib/logstash-core/version.rb +1 -1
- data/lib/logstash-core_jars.rb +14 -10
- data/lib/logstash/agent.rb +4 -2
- data/lib/logstash/api/commands/default_metadata.rb +1 -1
- data/lib/logstash/api/commands/hot_threads_reporter.rb +8 -2
- data/lib/logstash/api/commands/node.rb +2 -2
- data/lib/logstash/api/commands/stats.rb +2 -2
- data/lib/logstash/bootstrap_check/bad_ruby.rb +2 -2
- data/lib/logstash/bootstrap_check/default_config.rb +2 -3
- data/lib/logstash/compiler.rb +12 -12
- data/lib/logstash/compiler/lscl.rb +17 -7
- data/lib/logstash/compiler/treetop_monkeypatches.rb +1 -0
- data/lib/logstash/config/config_ast.rb +11 -1
- data/lib/logstash/config/mixin.rb +5 -0
- data/lib/logstash/config/modules_common.rb +101 -0
- data/lib/logstash/config/source/base.rb +75 -0
- data/lib/logstash/config/source/local.rb +52 -50
- data/lib/logstash/config/source/modules.rb +55 -0
- data/lib/logstash/config/source/multi_local.rb +54 -10
- data/lib/logstash/config/source_loader.rb +1 -0
- data/lib/logstash/config/string_escape.rb +27 -0
- data/lib/logstash/elasticsearch_client.rb +142 -0
- data/lib/logstash/environment.rb +5 -1
- data/lib/logstash/event.rb +0 -1
- data/lib/logstash/instrument/global_metrics.rb +13 -0
- data/lib/logstash/instrument/metric_store.rb +16 -13
- data/lib/logstash/instrument/metric_type/counter.rb +6 -18
- data/lib/logstash/instrument/metric_type/gauge.rb +6 -12
- data/lib/logstash/instrument/periodic_poller/dlq.rb +19 -0
- data/lib/logstash/instrument/periodic_pollers.rb +3 -1
- data/lib/logstash/logging/logger.rb +43 -14
- data/lib/logstash/modules/cli_parser.rb +74 -0
- data/lib/logstash/modules/elasticsearch_config.rb +22 -0
- data/lib/logstash/modules/elasticsearch_importer.rb +37 -0
- data/lib/logstash/modules/elasticsearch_resource.rb +10 -0
- data/lib/logstash/modules/file_reader.rb +36 -0
- data/lib/logstash/modules/kibana_base.rb +24 -0
- data/lib/logstash/modules/kibana_client.rb +122 -0
- data/lib/logstash/modules/kibana_config.rb +125 -0
- data/lib/logstash/modules/kibana_dashboards.rb +36 -0
- data/lib/logstash/modules/kibana_importer.rb +17 -0
- data/lib/logstash/modules/kibana_resource.rb +10 -0
- data/lib/logstash/modules/kibana_settings.rb +40 -0
- data/lib/logstash/modules/logstash_config.rb +120 -0
- data/lib/logstash/modules/resource_base.rb +38 -0
- data/lib/logstash/modules/scaffold.rb +50 -0
- data/lib/logstash/modules/settings_merger.rb +23 -0
- data/lib/logstash/modules/util.rb +17 -0
- data/lib/logstash/namespace.rb +1 -0
- data/lib/logstash/pipeline.rb +66 -27
- data/lib/logstash/pipeline_settings.rb +1 -0
- data/lib/logstash/plugins/registry.rb +1 -0
- data/lib/logstash/runner.rb +47 -3
- data/lib/logstash/settings.rb +20 -1
- data/lib/logstash/util/dead_letter_queue_manager.rb +1 -1
- data/lib/logstash/util/safe_uri.rb +146 -11
- data/lib/logstash/util/thread_dump.rb +4 -3
- data/lib/logstash/util/wrapped_acked_queue.rb +28 -24
- data/lib/logstash/util/wrapped_synchronous_queue.rb +19 -20
- data/lib/logstash/version.rb +1 -1
- data/locales/en.yml +56 -1
- data/logstash-core.gemspec +6 -4
- data/spec/logstash/agent/converge_spec.rb +2 -2
- data/spec/logstash/agent_spec.rb +11 -3
- data/spec/logstash/api/modules/logging_spec.rb +13 -7
- data/spec/logstash/api/modules/node_plugins_spec.rb +23 -5
- data/spec/logstash/api/modules/node_spec.rb +17 -15
- data/spec/logstash/api/modules/node_stats_spec.rb +0 -1
- data/spec/logstash/api/modules/plugins_spec.rb +40 -9
- data/spec/logstash/api/modules/root_spec.rb +0 -1
- data/spec/logstash/api/rack_app_spec.rb +2 -1
- data/spec/logstash/compiler/compiler_spec.rb +54 -7
- data/spec/logstash/config/config_ast_spec.rb +47 -8
- data/spec/logstash/config/mixin_spec.rb +14 -2
- data/spec/logstash/config/pipeline_config_spec.rb +7 -7
- data/spec/logstash/config/source/local_spec.rb +5 -2
- data/spec/logstash/config/source/multi_local_spec.rb +56 -10
- data/spec/logstash/config/source_loader_spec.rb +1 -1
- data/spec/logstash/config/string_escape_spec.rb +24 -0
- data/spec/logstash/event_spec.rb +9 -0
- data/spec/logstash/filters/base_spec.rb +1 -1
- data/spec/logstash/instrument/metric_store_spec.rb +2 -3
- data/spec/logstash/instrument/metric_type/counter_spec.rb +0 -12
- data/spec/logstash/instrument/metric_type/gauge_spec.rb +1 -8
- 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 +0 -9
- data/spec/logstash/legacy_ruby_timestamp_spec.rb +19 -14
- data/spec/logstash/modules/cli_parser_spec.rb +129 -0
- data/spec/logstash/modules/logstash_config_spec.rb +56 -0
- data/spec/logstash/modules/scaffold_spec.rb +239 -0
- data/spec/logstash/pipeline_dlq_commit_spec.rb +1 -1
- data/spec/logstash/pipeline_spec.rb +87 -20
- data/spec/logstash/runner_spec.rb +122 -5
- data/spec/logstash/setting_spec.rb +2 -2
- data/spec/logstash/settings/splittable_string_array_spec.rb +51 -0
- data/spec/logstash/timestamp_spec.rb +8 -2
- data/spec/logstash/util/safe_uri_spec.rb +16 -0
- data/spec/logstash/util/wrapped_acked_queue_spec.rb +63 -0
- data/spec/logstash/util/wrapped_synchronous_queue_spec.rb +0 -22
- data/spec/support/helpers.rb +1 -1
- data/spec/support/matchers.rb +21 -4
- metadata +102 -19
- data/lib/logstash/instrument/metric_type/base.rb +0 -31
- data/lib/logstash/program.rb +0 -14
- data/lib/logstash/string_interpolation.rb +0 -18
@@ -1,8 +1,11 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module LogStash module Config module Source
|
3
3
|
class Base
|
4
|
+
attr_reader :conflict_messages
|
5
|
+
|
4
6
|
def initialize(settings)
|
5
7
|
@settings = settings
|
8
|
+
@conflict_messages = []
|
6
9
|
end
|
7
10
|
|
8
11
|
def pipeline_configs
|
@@ -12,5 +15,77 @@ module LogStash module Config module Source
|
|
12
15
|
def match?
|
13
16
|
raise NotImplementedError, "`match?` must be implemented!"
|
14
17
|
end
|
18
|
+
|
19
|
+
def config_conflict?
|
20
|
+
raise NotImplementedError, "`config_conflict?` must be implemented!"
|
21
|
+
end
|
22
|
+
|
23
|
+
def config_reload_automatic_setting
|
24
|
+
@settings.get_setting("config.reload.automatic")
|
25
|
+
end
|
26
|
+
|
27
|
+
def config_reload_automatic
|
28
|
+
config_reload_automatic_setting.value
|
29
|
+
end
|
30
|
+
|
31
|
+
def config_reload_automatic?
|
32
|
+
config_reload_automatic_setting.set?
|
33
|
+
end
|
34
|
+
|
35
|
+
def config_string_setting
|
36
|
+
@settings.get_setting("config.string")
|
37
|
+
end
|
38
|
+
|
39
|
+
def config_string
|
40
|
+
config_string_setting.value
|
41
|
+
end
|
42
|
+
|
43
|
+
def config_string?
|
44
|
+
!config_string.nil?
|
45
|
+
end
|
46
|
+
|
47
|
+
def config_path_setting
|
48
|
+
@settings.get_setting("path.config")
|
49
|
+
end
|
50
|
+
|
51
|
+
def config_path
|
52
|
+
config_path_setting.value
|
53
|
+
end
|
54
|
+
|
55
|
+
def config_path?
|
56
|
+
!(config_path.nil? || config_path.empty?)
|
57
|
+
end
|
58
|
+
|
59
|
+
def modules_cli_setting
|
60
|
+
@settings.get_setting("modules.cli")
|
61
|
+
end
|
62
|
+
|
63
|
+
def modules_cli
|
64
|
+
modules_cli_setting.value
|
65
|
+
end
|
66
|
+
|
67
|
+
def modules_cli?
|
68
|
+
!(modules_cli.nil? || modules_cli.empty?)
|
69
|
+
end
|
70
|
+
|
71
|
+
def modules_setting
|
72
|
+
@settings.get_setting("modules")
|
73
|
+
end
|
74
|
+
|
75
|
+
def modules
|
76
|
+
modules_setting.value
|
77
|
+
end
|
78
|
+
|
79
|
+
def modules?
|
80
|
+
!(modules.nil? || modules.empty?)
|
81
|
+
end
|
82
|
+
|
83
|
+
def both_module_configs?
|
84
|
+
modules_cli? && modules?
|
85
|
+
end
|
86
|
+
|
87
|
+
def modules_defined?
|
88
|
+
modules_cli? || modules?
|
89
|
+
end
|
15
90
|
end
|
16
91
|
end end end
|
@@ -18,8 +18,27 @@ module LogStash module Config module Source
|
|
18
18
|
#
|
19
19
|
class Local < Base
|
20
20
|
class ConfigStringLoader
|
21
|
+
INPUT_BLOCK_RE = /input *{/
|
22
|
+
OUTPUT_BLOCK_RE = /output *{/
|
23
|
+
EMPTY_RE = /^\s*$/
|
24
|
+
|
21
25
|
def self.read(config_string)
|
22
|
-
[org.logstash.common.SourceWithMetadata.new("string", "config_string", config_string)]
|
26
|
+
config_parts = [org.logstash.common.SourceWithMetadata.new("string", "config_string", 0, 0, config_string)]
|
27
|
+
|
28
|
+
# Make sure we have an input and at least 1 output
|
29
|
+
# if its not the case we will add stdin and stdout
|
30
|
+
# this is for backward compatibility reason
|
31
|
+
if !INPUT_BLOCK_RE.match(config_string)
|
32
|
+
config_parts << org.logstash.common.SourceWithMetadata.new(self.class.name, "default input", 0, 0, LogStash::Config::Defaults.input)
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
# include a default stdout output if no outputs given
|
37
|
+
if !OUTPUT_BLOCK_RE.match(config_string)
|
38
|
+
config_parts << org.logstash.common.SourceWithMetadata.new(self.class.name, "default output", 0, 0, LogStash::Config::Defaults.output)
|
39
|
+
end
|
40
|
+
|
41
|
+
config_parts
|
23
42
|
end
|
24
43
|
end
|
25
44
|
|
@@ -53,8 +72,8 @@ module LogStash module Config module Source
|
|
53
72
|
|
54
73
|
config_string = ::File.read(file)
|
55
74
|
|
56
|
-
if valid_encoding?
|
57
|
-
part = org.logstash.common.SourceWithMetadata.new("file", file, config_string)
|
75
|
+
if config_string.valid_encoding?
|
76
|
+
part = org.logstash.common.SourceWithMetadata.new("file", file, 0, 0, config_string)
|
58
77
|
config_parts << part
|
59
78
|
else
|
60
79
|
encoding_issue_files << file
|
@@ -101,10 +120,6 @@ module LogStash module Config module Source
|
|
101
120
|
all_files - get_matched_files
|
102
121
|
end
|
103
122
|
|
104
|
-
def valid_encoding?(content)
|
105
|
-
content.ascii_only? && content.valid_encoding?
|
106
|
-
end
|
107
|
-
|
108
123
|
def temporary_file?(filepath)
|
109
124
|
filepath.match(TEMPORARY_FILE_RE)
|
110
125
|
end
|
@@ -121,7 +136,7 @@ module LogStash module Config module Source
|
|
121
136
|
# since we have fetching config we wont follow any redirection.
|
122
137
|
case response.code.to_i
|
123
138
|
when 200
|
124
|
-
[org.logstash.common.SourceWithMetadata.new(uri.scheme, uri.to_s, response.body)]
|
139
|
+
[org.logstash.common.SourceWithMetadata.new(uri.scheme, uri.to_s, 0, 0, response.body)]
|
125
140
|
when 302
|
126
141
|
raise LogStash::ConfigLoadingError, I18n.t("logstash.runner.configuration.fetch-failed", :path => uri.to_s, :message => "We don't follow redirection for remote configuration")
|
127
142
|
when 404
|
@@ -139,17 +154,37 @@ module LogStash module Config module Source
|
|
139
154
|
|
140
155
|
PIPELINE_ID = LogStash::SETTINGS.get("pipeline.id").to_sym
|
141
156
|
HTTP_RE = /^http(s)?/
|
142
|
-
INPUT_BLOCK_RE = /input *{/
|
143
|
-
OUTPUT_BLOCK_RE = /output *{/
|
144
157
|
|
145
158
|
def pipeline_configs
|
159
|
+
if config_conflict?
|
160
|
+
raise ConfigurationError, @conflict_messages.join(", ")
|
161
|
+
end
|
162
|
+
local_pipeline_configs
|
163
|
+
end
|
164
|
+
|
165
|
+
def match?
|
166
|
+
# see basic settings predicates and getters defined in the base class
|
167
|
+
(config_string? || config_path?) && !(modules_cli? || modules?) && !automatic_reload_with_config_string?
|
168
|
+
end
|
146
169
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
170
|
+
def config_conflict?
|
171
|
+
@conflict_messages.clear
|
172
|
+
|
173
|
+
# Check if configuration auto-reload is used that -f is specified
|
174
|
+
if automatic_reload_with_config_string?
|
175
|
+
@conflict_messages << I18n.t("logstash.runner.reload-with-config-string")
|
176
|
+
end
|
177
|
+
# Check if both -f and -e are present
|
178
|
+
if config_string? && config_path?
|
179
|
+
@conflict_messages << I18n.t("logstash.runner.config-string-path-exclusive")
|
151
180
|
end
|
152
181
|
|
182
|
+
@conflict_messages.any?
|
183
|
+
end
|
184
|
+
|
185
|
+
private
|
186
|
+
|
187
|
+
def local_pipeline_configs
|
153
188
|
config_parts = if config_string?
|
154
189
|
ConfigStringLoader.read(config_string)
|
155
190
|
elsif local_config?
|
@@ -160,46 +195,13 @@ module LogStash module Config module Source
|
|
160
195
|
[]
|
161
196
|
end
|
162
197
|
|
163
|
-
return if config_parts.empty?
|
164
|
-
|
165
|
-
add_missing_default_inputs_or_outputs(config_parts) if config_string?
|
198
|
+
return [] if config_parts.empty?
|
166
199
|
|
167
200
|
[PipelineConfig.new(self.class, @settings.get("pipeline.id").to_sym, config_parts, @settings)]
|
168
201
|
end
|
169
202
|
|
170
|
-
def
|
171
|
-
|
172
|
-
end
|
173
|
-
|
174
|
-
private
|
175
|
-
# Make sure we have an input and at least 1 output
|
176
|
-
# if its not the case we will add stdin and stdout
|
177
|
-
# this is for backward compatibility reason
|
178
|
-
def add_missing_default_inputs_or_outputs(config_parts)
|
179
|
-
if !config_parts.any? { |part| INPUT_BLOCK_RE.match(part.text) }
|
180
|
-
config_parts << org.logstash.common.SourceWithMetadata.new(self.class.name, "default input", LogStash::Config::Defaults.input)
|
181
|
-
end
|
182
|
-
|
183
|
-
# include a default stdout output if no outputs given
|
184
|
-
if !config_parts.any? { |part| OUTPUT_BLOCK_RE.match(part.text) }
|
185
|
-
config_parts << org.logstash.common.SourceWithMetadata.new(self.class.name, "default output", LogStash::Config::Defaults.output)
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
def config_string
|
190
|
-
@settings.get("config.string")
|
191
|
-
end
|
192
|
-
|
193
|
-
def config_string?
|
194
|
-
!config_string.nil?
|
195
|
-
end
|
196
|
-
|
197
|
-
def config_path
|
198
|
-
@settings.get("path.config")
|
199
|
-
end
|
200
|
-
|
201
|
-
def config_path?
|
202
|
-
!config_path.nil? && !config_path.empty?
|
203
|
+
def automatic_reload_with_config_string?
|
204
|
+
config_reload_automatic? && !config_path? && config_string?
|
203
205
|
end
|
204
206
|
|
205
207
|
def local_config?
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/config/source/base"
|
3
|
+
require "logstash/config/modules_common"
|
4
|
+
require "logstash/config/pipeline_config"
|
5
|
+
require "logstash/util/loggable"
|
6
|
+
require "logstash/errors"
|
7
|
+
|
8
|
+
module LogStash module Config module Source
|
9
|
+
class Modules < Base
|
10
|
+
include LogStash::Util::Loggable
|
11
|
+
def pipeline_configs
|
12
|
+
if config_conflict? # double check
|
13
|
+
raise ConfigurationError, @conflict_messages.join(", ")
|
14
|
+
end
|
15
|
+
|
16
|
+
pipelines = LogStash::Config::ModulesCommon.pipeline_configs(@settings)
|
17
|
+
pipelines.map do |hash|
|
18
|
+
PipelineConfig.new(self, hash["pipeline_id"].to_sym,
|
19
|
+
org.logstash.common.SourceWithMetadata.new("module", hash["alt_name"], 0, 0, hash["config_string"]),
|
20
|
+
hash["settings"])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def match?
|
25
|
+
# see basic settings predicates and getters defined in the base class
|
26
|
+
(modules_cli? || modules?) && !(config_string? || config_path?) && !automatic_reload_with_modules?
|
27
|
+
end
|
28
|
+
|
29
|
+
def config_conflict?
|
30
|
+
@conflict_messages.clear
|
31
|
+
# Make note that if modules are configured in both cli and logstash.yml that cli module
|
32
|
+
# settings will overwrite the logstash.yml modules settings
|
33
|
+
if modules_cli? && modules?
|
34
|
+
logger.info(I18n.t("logstash.runner.cli-module-override"))
|
35
|
+
end
|
36
|
+
|
37
|
+
if automatic_reload_with_modules?
|
38
|
+
@conflict_messages << I18n.t("logstash.runner.reload-with-modules")
|
39
|
+
end
|
40
|
+
|
41
|
+
# Check if config (-f or -e) and modules are configured
|
42
|
+
if (modules_cli? || modules?) && (config_string? || config_path?)
|
43
|
+
@conflict_messages << I18n.t("logstash.runner.config-module-exclusive")
|
44
|
+
end
|
45
|
+
|
46
|
+
@conflict_messages.any?
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def automatic_reload_with_modules?
|
52
|
+
(modules_cli? || modules?) && config_reload_automatic?
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end end end
|
@@ -10,6 +10,7 @@ module LogStash module Config module Source
|
|
10
10
|
def initialize(settings)
|
11
11
|
@original_settings = settings
|
12
12
|
super(settings)
|
13
|
+
@match_warning_done = false
|
13
14
|
end
|
14
15
|
|
15
16
|
def pipeline_configs
|
@@ -18,28 +19,48 @@ module LogStash module Config module Source
|
|
18
19
|
::LogStash::PipelineSettings.from_settings(@original_settings.clone).merge(pipeline_settings)
|
19
20
|
end
|
20
21
|
detect_duplicate_pipelines(pipelines_settings)
|
21
|
-
pipelines_settings.map do |pipeline_settings|
|
22
|
+
pipeline_configs = pipelines_settings.map do |pipeline_settings|
|
22
23
|
@settings = pipeline_settings
|
23
24
|
# this relies on instance variable @settings and the parent class' pipeline_configs
|
24
25
|
# method. The alternative is to refactor most of the Local source methods to accept
|
25
26
|
# a settings object instead of relying on @settings.
|
26
|
-
|
27
|
+
local_pipeline_configs # create a PipelineConfig object based on @settings
|
27
28
|
end.flatten
|
29
|
+
@settings = @original_settings
|
30
|
+
pipeline_configs
|
28
31
|
end
|
29
32
|
|
30
33
|
def match?
|
31
|
-
|
32
|
-
|
33
|
-
return
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
34
|
+
detect_pipelines if !@detect_pipelines_called
|
35
|
+
# see basic settings predicates and getters defined in the base class
|
36
|
+
return !(invalid_pipelines_detected? || modules_cli? || modules? || config_string? || config_path?)
|
37
|
+
end
|
38
|
+
|
39
|
+
def invalid_pipelines_detected?
|
40
|
+
!@detected_marker || @detected_marker.is_a?(Class)
|
41
|
+
end
|
42
|
+
|
43
|
+
def config_conflict?
|
44
|
+
detect_pipelines if !@detect_pipelines_called
|
45
|
+
@conflict_messages.clear
|
46
|
+
# are there any auto-reload conflicts?
|
47
|
+
if !(modules_cli? || modules? || config_string? || config_path?)
|
48
|
+
if @detected_marker.nil?
|
49
|
+
@conflict_messages << I18n.t("logstash.runner.config-pipelines-failed-read", :path => pipelines_yaml_location)
|
50
|
+
elsif @detected_marker == false
|
51
|
+
@conflict_messages << I18n.t("logstash.runner.config-pipelines-empty", :path => pipelines_yaml_location)
|
52
|
+
elsif @detected_marker.is_a?(Class)
|
53
|
+
@conflict_messages << I18n.t("logstash.runner.config-pipelines-invalid", :invalid_class => @detected_marker, :path => pipelines_yaml_location)
|
54
|
+
end
|
55
|
+
else
|
56
|
+
do_warning? && logger.warn("Ignoring the 'pipelines.yml' file because modules or command line options are specified")
|
38
57
|
end
|
39
|
-
|
58
|
+
@conflict_messages.any?
|
40
59
|
end
|
41
60
|
|
42
61
|
def retrieve_yaml_pipelines
|
62
|
+
# by now, either the config_conflict? or the match? should have ruled out any config problems
|
63
|
+
# but we don't rely on this, we can still get IO errors or
|
43
64
|
result = read_pipelines_from_yaml(pipelines_yaml_location)
|
44
65
|
case result
|
45
66
|
when Array
|
@@ -68,5 +89,28 @@ module LogStash module Config module Source
|
|
68
89
|
raise ConfigurationError.new("Pipelines YAML file contains duplicate pipeline ids: #{duplicate_ids.inspect}. Location: #{pipelines_yaml_location}")
|
69
90
|
end
|
70
91
|
end
|
92
|
+
|
93
|
+
def detect_pipelines
|
94
|
+
result = read_pipelines_from_yaml(pipelines_yaml_location) rescue nil
|
95
|
+
if result.is_a?(Array)
|
96
|
+
@detected_marker = true
|
97
|
+
elsif result.nil?
|
98
|
+
@detected_marker = nil
|
99
|
+
elsif !result
|
100
|
+
@detected_marker = false
|
101
|
+
else
|
102
|
+
@detected_marker = result.class
|
103
|
+
end
|
104
|
+
@detect_pipelines_called = true
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def do_warning?
|
110
|
+
if !(done = true && @match_warning_done)
|
111
|
+
@match_warning_done = true
|
112
|
+
end
|
113
|
+
!done
|
114
|
+
end
|
71
115
|
end
|
72
116
|
end end end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module LogStash; module Config; module StringEscape
|
4
|
+
class << self
|
5
|
+
def process_escapes(input)
|
6
|
+
input.gsub(/\\./) do |value|
|
7
|
+
process(value)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
def process(value)
|
13
|
+
case value[1]
|
14
|
+
when '"', "'", "\\"
|
15
|
+
value[1]
|
16
|
+
when "n"
|
17
|
+
"\n"
|
18
|
+
when "r"
|
19
|
+
"\r"
|
20
|
+
when "t"
|
21
|
+
"\t"
|
22
|
+
else
|
23
|
+
value
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end end end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/namespace"
|
3
|
+
require "logstash/logging"
|
4
|
+
require "elasticsearch"
|
5
|
+
require "elasticsearch/transport/transport/http/manticore"
|
6
|
+
|
7
|
+
module LogStash class ElasticsearchClient
|
8
|
+
include LogStash::Util::Loggable
|
9
|
+
|
10
|
+
class Response
|
11
|
+
# duplicated here from Elasticsearch::Transport::Transport::Response
|
12
|
+
# to create a normalised response across different client IMPL
|
13
|
+
attr_reader :status, :body, :headers
|
14
|
+
def initialize(status, body, headers={})
|
15
|
+
@status, @body, @headers = status, body, headers
|
16
|
+
@body = body.force_encoding('UTF-8') if body.respond_to?(:force_encoding)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.build(settings)
|
21
|
+
new(RubyClient.new(settings, logger))
|
22
|
+
end
|
23
|
+
|
24
|
+
class RubyClient
|
25
|
+
def initialize(settings, logger)
|
26
|
+
@settings = settings
|
27
|
+
@logger = logger
|
28
|
+
@client_args = client_args
|
29
|
+
|
30
|
+
ssl_options = {}
|
31
|
+
|
32
|
+
if @settings["var.elasticsearch.ssl.enabled"] == "true"
|
33
|
+
ssl_options[:verify] = @settings.fetch("var.elasticsearch.ssl.verification_mode", true)
|
34
|
+
ssl_options[:ca_file] = @settings.fetch("var.elasticsearch.ssl.certificate_authority", nil)
|
35
|
+
ssl_options[:client_cert] = @settings.fetch("var.elasticsearch.ssl.certificate", nil)
|
36
|
+
ssl_options[:client_key] = @settings.fetch("var.elasticsearch.ssl.key", nil)
|
37
|
+
end
|
38
|
+
|
39
|
+
@client_args[:ssl] = ssl_options
|
40
|
+
|
41
|
+
username = @settings["var.elasticsearch.username"]
|
42
|
+
password = @settings["var.elasticsearch.password"]
|
43
|
+
if username
|
44
|
+
@client_args[:transport_options] = { :headers => { "Authorization" => 'Basic ' + Base64.encode64( "#{username}:#{password}" ).chomp } }
|
45
|
+
end
|
46
|
+
|
47
|
+
@client = Elasticsearch::Client.new(@client_args)
|
48
|
+
end
|
49
|
+
|
50
|
+
def can_connect?
|
51
|
+
begin
|
52
|
+
head(SecureRandom.hex(32).prepend('_'))
|
53
|
+
rescue Elasticsearch::Transport::Transport::Errors::BadRequest
|
54
|
+
true
|
55
|
+
rescue Manticore::SocketException
|
56
|
+
false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def host_settings
|
61
|
+
@client_args[:hosts]
|
62
|
+
end
|
63
|
+
|
64
|
+
def delete(path)
|
65
|
+
begin
|
66
|
+
normalize_response(@client.perform_request('DELETE', path, {}, nil))
|
67
|
+
rescue Exception => e
|
68
|
+
if e.class.to_s =~ /NotFound/ || e.message =~ /Not\s*Found|404/i
|
69
|
+
Response.new(404, "", {})
|
70
|
+
else
|
71
|
+
raise e
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def put(path, content)
|
77
|
+
normalize_response(@client.perform_request('PUT', path, {}, content))
|
78
|
+
end
|
79
|
+
|
80
|
+
def head(path)
|
81
|
+
begin
|
82
|
+
normalize_response(@client.perform_request('HEAD', path, {}, nil))
|
83
|
+
rescue Exception => e
|
84
|
+
if is_404_error?(e)
|
85
|
+
Response.new(404, "", {})
|
86
|
+
else
|
87
|
+
raise e
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def is_404_error?(error)
|
95
|
+
error.class.to_s =~ /NotFound/ || error.message =~ /Not\s*Found|404/i
|
96
|
+
end
|
97
|
+
|
98
|
+
def normalize_response(response)
|
99
|
+
Response.new(response.status, response.body, response.headers)
|
100
|
+
end
|
101
|
+
|
102
|
+
def client_args
|
103
|
+
{
|
104
|
+
:transport_class => Elasticsearch::Transport::Transport::HTTP::Manticore,
|
105
|
+
:hosts => [*unpack_hosts],
|
106
|
+
# :logger => @logger, # silence the client logging
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
110
|
+
def unpack_hosts
|
111
|
+
setting = @settings.fetch("var.elasticsearch.hosts", "localhost:9200")
|
112
|
+
if setting.is_a?(String)
|
113
|
+
return setting.split(',').map(&:strip)
|
114
|
+
end
|
115
|
+
setting
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def initialize(client)
|
120
|
+
@client = client
|
121
|
+
end
|
122
|
+
|
123
|
+
def delete(path)
|
124
|
+
@client.delete(path)
|
125
|
+
end
|
126
|
+
|
127
|
+
def put(path, content)
|
128
|
+
@client.put(path, content)
|
129
|
+
end
|
130
|
+
|
131
|
+
def head(path)
|
132
|
+
@client.head(path)
|
133
|
+
end
|
134
|
+
|
135
|
+
def can_connect?
|
136
|
+
@client.can_connect?
|
137
|
+
end
|
138
|
+
|
139
|
+
def host_settings
|
140
|
+
@client.host_settings
|
141
|
+
end
|
142
|
+
end end
|