mirror of
https://github.com/elastic/logstash.git
synced 2025-04-23 22:27:21 -04:00
fix a few issues with pipeline source loading
- allow empty config.string - move all config autocompletion logic to the ConfigStringLoader - gracefully handle absense of files in path.config - ensure original_settings are restored in multi_local source after PipelineConfig creation Fixes #7866
This commit is contained in:
parent
c5e25cf6fa
commit
cb2f01b4b6
5 changed files with 38 additions and 28 deletions
|
@ -41,7 +41,7 @@ module LogStash module Config module Source
|
|||
end
|
||||
|
||||
def config_string?
|
||||
!(config_string.nil? || config_string.empty?)
|
||||
!config_string.nil?
|
||||
end
|
||||
|
||||
def config_path_setting
|
||||
|
|
|
@ -18,8 +18,27 @@ module LogStash module Config module Source
|
|||
#
|
||||
class Local < Base
|
||||
class ConfigStringLoader
|
||||
INPUT_BLOCK_RE = /input *{/
|
||||
OUTPUT_BLOCK_RE = /output *{/
|
||||
EMPTY_RE = /^\s*$/
|
||||
|
||||
def self.read(config_string)
|
||||
[org.logstash.common.SourceWithMetadata.new("string", "config_string", 0, 0, config_string)]
|
||||
config_parts = [org.logstash.common.SourceWithMetadata.new("string", "config_string", 0, 0, config_string)]
|
||||
|
||||
# Make sure we have an input and at least 1 output
|
||||
# if its not the case we will add stdin and stdout
|
||||
# this is for backward compatibility reason
|
||||
if !INPUT_BLOCK_RE.match(config_string)
|
||||
config_parts << org.logstash.common.SourceWithMetadata.new(self.class.name, "default input", 0, 0, LogStash::Config::Defaults.input)
|
||||
|
||||
end
|
||||
|
||||
# include a default stdout output if no outputs given
|
||||
if !OUTPUT_BLOCK_RE.match(config_string)
|
||||
config_parts << org.logstash.common.SourceWithMetadata.new(self.class.name, "default output", 0, 0, LogStash::Config::Defaults.output)
|
||||
end
|
||||
|
||||
config_parts
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -135,8 +154,6 @@ module LogStash module Config module Source
|
|||
|
||||
PIPELINE_ID = LogStash::SETTINGS.get("pipeline.id").to_sym
|
||||
HTTP_RE = /^http(s)?/
|
||||
INPUT_BLOCK_RE = /input *{/
|
||||
OUTPUT_BLOCK_RE = /output *{/
|
||||
|
||||
def pipeline_configs
|
||||
if config_conflict?
|
||||
|
@ -178,9 +195,7 @@ module LogStash module Config module Source
|
|||
[]
|
||||
end
|
||||
|
||||
return if config_parts.empty?
|
||||
|
||||
add_missing_default_inputs_or_outputs(config_parts) if config_string?
|
||||
return [] if config_parts.empty?
|
||||
|
||||
[PipelineConfig.new(self.class, @settings.get("pipeline.id").to_sym, config_parts, @settings)]
|
||||
end
|
||||
|
@ -189,20 +204,6 @@ module LogStash module Config module Source
|
|||
config_reload_automatic? && !config_path? && config_string?
|
||||
end
|
||||
|
||||
# Make sure we have an input and at least 1 output
|
||||
# if its not the case we will add stdin and stdout
|
||||
# this is for backward compatibility reason
|
||||
def add_missing_default_inputs_or_outputs(config_parts)
|
||||
if !config_parts.any? { |part| INPUT_BLOCK_RE.match(part.text) }
|
||||
config_parts << org.logstash.common.SourceWithMetadata.new(self.class.name, "default input", 0, 0, LogStash::Config::Defaults.input)
|
||||
end
|
||||
|
||||
# include a default stdout output if no outputs given
|
||||
if !config_parts.any? { |part| OUTPUT_BLOCK_RE.match(part.text) }
|
||||
config_parts << org.logstash.common.SourceWithMetadata.new(self.class.name, "default output", 0, 0, LogStash::Config::Defaults.output)
|
||||
end
|
||||
end
|
||||
|
||||
def local_config?
|
||||
return false unless config_path?
|
||||
|
||||
|
|
|
@ -19,13 +19,15 @@ module LogStash module Config module Source
|
|||
::LogStash::PipelineSettings.from_settings(@original_settings.clone).merge(pipeline_settings)
|
||||
end
|
||||
detect_duplicate_pipelines(pipelines_settings)
|
||||
pipelines_settings.map do |pipeline_settings|
|
||||
pipeline_configs = pipelines_settings.map do |pipeline_settings|
|
||||
@settings = pipeline_settings
|
||||
# this relies on instance variable @settings and the parent class' pipeline_configs
|
||||
# method. The alternative is to refactor most of the Local source methods to accept
|
||||
# a settings object instead of relying on @settings.
|
||||
local_pipeline_configs # create a PipelineConfig object based on @settings
|
||||
end.flatten
|
||||
@settings = @original_settings
|
||||
pipeline_configs
|
||||
end
|
||||
|
||||
def match?
|
||||
|
|
|
@ -60,6 +60,10 @@ public class SourceWithMetadata implements HashableWithSource {
|
|||
return false;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
if (!(this.getText() instanceof String)) {
|
||||
badAttributes.add(this.getText());
|
||||
}
|
||||
|
||||
if (!badAttributes.isEmpty()){
|
||||
String message = "Missing attributes in SourceWithMetadata: (" + badAttributes + ") "
|
||||
+ this.toString();
|
||||
|
@ -72,7 +76,7 @@ public class SourceWithMetadata implements HashableWithSource {
|
|||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Objects.hash(attributes().toArray());
|
||||
return Objects.hash(hashableAttributes().toArray());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
@ -81,11 +85,16 @@ public class SourceWithMetadata implements HashableWithSource {
|
|||
|
||||
@Override
|
||||
public String hashSource() {
|
||||
return attributes().stream().map(Object::toString).collect(Collectors.joining("|"));
|
||||
return hashableAttributes().stream().map(Object::toString).collect(Collectors.joining("|"));
|
||||
}
|
||||
|
||||
// Fields checked for being not null and non empty String
|
||||
private Collection<Object> attributes() {
|
||||
return Arrays.asList(this.getId(), this.getProtocol(), this.getLine(), this.getColumn());
|
||||
}
|
||||
|
||||
// Fields used in the hashSource and hashCode methods to ensure uniqueness
|
||||
private Collection<Object> attributes() {
|
||||
private Collection<Object> hashableAttributes() {
|
||||
return Arrays.asList(this.getId(), this.getProtocol(), this.getLine(), this.getColumn(), this.getText());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,10 +40,8 @@ public class SourceWithMetadataTest {
|
|||
new ParameterGroup("proto", "path", 1, 1, null),
|
||||
new ParameterGroup("", "path", 1, 1, "foo"),
|
||||
new ParameterGroup("proto", "", 1, 1, "foo"),
|
||||
new ParameterGroup("proto", "path", 1, 1, ""),
|
||||
new ParameterGroup(" ", "path", 1, 1, "foo"),
|
||||
new ParameterGroup("proto", " ", 1, 1, "foo"),
|
||||
new ParameterGroup("proto", "path", 1, 1, " ")
|
||||
new ParameterGroup("proto", " ", 1, 1, "foo")
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue