logstash-core 6.0.0.alpha2-java → 6.0.0.beta1-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|