mirror of
https://github.com/elastic/logstash.git
synced 2025-04-24 06:37:19 -04:00
parent
7154f922f5
commit
00970ca9bc
5 changed files with 143 additions and 24 deletions
|
@ -1,4 +1,5 @@
|
|||
# encoding: utf-8
|
||||
require 'logstash/errors'
|
||||
require "treetop"
|
||||
class Treetop::Runtime::SyntaxNode
|
||||
def compile
|
||||
|
@ -28,6 +29,12 @@ class Treetop::Runtime::SyntaxNode
|
|||
return results
|
||||
end
|
||||
|
||||
# When Treetop parses the configuration file
|
||||
# it will generate a tree, the generated tree will contain
|
||||
# a few `Empty` nodes to represent the actual space/tab or newline in the file.
|
||||
# Some of theses node will point to our concrete class.
|
||||
# To fetch a specific types of object we need to follow each branch
|
||||
# and ignore the empty nodes.
|
||||
def recursive_select(klass)
|
||||
return recursive_inject { |e| e.is_a?(klass) }
|
||||
end
|
||||
|
@ -50,6 +57,7 @@ end
|
|||
|
||||
module LogStash; module Config; module AST
|
||||
class Node < Treetop::Runtime::SyntaxNode; end
|
||||
|
||||
class Config < Node
|
||||
def compile
|
||||
code = []
|
||||
|
@ -309,11 +317,36 @@ module LogStash; module Config; module AST
|
|||
end
|
||||
end
|
||||
class Hash < Value
|
||||
def validate!
|
||||
duplicate_values = find_duplicate_keys
|
||||
|
||||
if duplicate_values.size > 0
|
||||
raise ConfigurationError.new(
|
||||
I18n.t("logstash.agent.configuration.invalid_plugin_settings_duplicate_keys",
|
||||
:keys => duplicate_values.join(', '),
|
||||
:line => input.line_of(interval.first),
|
||||
:column => input.column_of(interval.first),
|
||||
:byte => interval.first + 1,
|
||||
:after => input[0..interval.first]
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def find_duplicate_keys
|
||||
values = recursive_select(HashEntry).collect { |hash_entry| hash_entry.name.text_value }
|
||||
values.find_all { |v| values.count(v) > 1 }.uniq
|
||||
end
|
||||
|
||||
def compile
|
||||
validate!
|
||||
return "{" << recursive_select(HashEntry).collect(&:compile).reject(&:empty?).join(", ") << "}"
|
||||
end
|
||||
end
|
||||
class HashEntries < Node; end
|
||||
|
||||
class HashEntries < Node
|
||||
end
|
||||
|
||||
class HashEntry < Node
|
||||
def compile
|
||||
return %Q(#{name.compile} => #{value.compile})
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
# encoding: utf-8
|
||||
# Autogenerated from a Treetop grammar. Edits may be lost.
|
||||
|
||||
|
||||
|
|
|
@ -95,6 +95,10 @@ en:
|
|||
}
|
||||
invalid_plugin_settings: >-
|
||||
Something is wrong with your configuration.
|
||||
invalid_plugin_settings_duplicate_keys: |-
|
||||
Duplicate keys found in your configuration: [%{keys}]
|
||||
At line: %{line}, column %{column} (byte %{byte})
|
||||
after %{after}
|
||||
invalid_plugin_register: >-
|
||||
Cannot register %{plugin} %{type} plugin.
|
||||
The error reported is:
|
||||
|
|
|
@ -1,31 +1,109 @@
|
|||
# encoding: utf-8
|
||||
# config syntax tests
|
||||
#
|
||||
|
||||
require "logstash/devutils/rspec/spec_helper"
|
||||
require "logstash/config/grammar"
|
||||
require "logstash/config/config_ast"
|
||||
require "logstash/errors"
|
||||
|
||||
describe LogStashConfigParser do
|
||||
it "should permit single-quoted attribute names" do
|
||||
parser = LogStashConfigParser.new
|
||||
config = parser.parse(%q(
|
||||
input {
|
||||
example {
|
||||
'foo' => 'bar'
|
||||
test => { 'bar' => 'baz' }
|
||||
}
|
||||
}
|
||||
))
|
||||
context '#parse' do
|
||||
context "valid configuration" do
|
||||
it "should permit single-quoted attribute names" do
|
||||
parser = LogStashConfigParser.new
|
||||
config = parser.parse(%q(
|
||||
input {
|
||||
example {
|
||||
'foo' => 'bar'
|
||||
test => { 'bar' => 'baz' }
|
||||
}
|
||||
}
|
||||
))
|
||||
|
||||
expect(config).not_to be_nil
|
||||
expect(config).not_to be_nil
|
||||
end
|
||||
|
||||
it "should permit empty plugin sections" do
|
||||
parser = LogStashConfigParser.new
|
||||
config = parser.parse(%q(
|
||||
filter {
|
||||
}
|
||||
))
|
||||
|
||||
expect(config).not_to be_nil
|
||||
end
|
||||
|
||||
it 'permits hash to contains array' do
|
||||
parser = LogStashConfigParser.new
|
||||
config = parser.parse(%q(
|
||||
input{
|
||||
example {
|
||||
match => {
|
||||
"message"=> ["pattern1", "pattern2", "pattern3"]
|
||||
}
|
||||
}
|
||||
}))
|
||||
expect(config).not_to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "should permit empty plugin sections" do
|
||||
parser = LogStashConfigParser.new
|
||||
config = parser.parse(%q(
|
||||
filter {
|
||||
}
|
||||
))
|
||||
context "#compile" do
|
||||
context "invalid configuration" do
|
||||
it "rejects duplicate hash key" do
|
||||
parser = LogStashConfigParser.new
|
||||
config = parser.parse(%q(
|
||||
input {
|
||||
example {
|
||||
match => {
|
||||
"message"=> "pattern1"
|
||||
"message"=> "pattern2"
|
||||
"message"=> "pattern3"
|
||||
}
|
||||
}
|
||||
}
|
||||
))
|
||||
|
||||
expect(config).not_to be_nil
|
||||
expect { config.compile }.to raise_error(LogStash::ConfigurationError, /Duplicate keys found in your configuration: \["message"\]/)
|
||||
end
|
||||
|
||||
it "rejects duplicate keys in nested hash" do
|
||||
parser = LogStashConfigParser.new
|
||||
config = parser.parse(%q(
|
||||
input {
|
||||
example {
|
||||
match => {
|
||||
"message"=> "pattern1"
|
||||
"more" => {
|
||||
"cool" => true
|
||||
"cool" => true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
))
|
||||
|
||||
expect { config.compile }.to raise_error(LogStash::ConfigurationError, /Duplicate keys found in your configuration: \["cool"\]/)
|
||||
end
|
||||
|
||||
it "rejects a key with multiple double quotes" do
|
||||
parser = LogStashConfigParser.new
|
||||
config = parser.parse(%q(
|
||||
input {
|
||||
example {
|
||||
match => {
|
||||
"message"=> "pattern1"
|
||||
""more"" => {
|
||||
"cool" => true
|
||||
"cool" => true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
))
|
||||
|
||||
expect(config).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,9 +5,10 @@ PATH
|
|||
cabin (>= 0.6.0)
|
||||
ci_reporter (= 1.9.3)
|
||||
clamp
|
||||
file-dependencies
|
||||
filesize
|
||||
ftw (~> 0.0.40)
|
||||
i18n (= 0.6.9)
|
||||
insist (= 1.0.0)
|
||||
jar-dependencies (= 0.1.2)
|
||||
jrjackson
|
||||
jruby-httpclient
|
||||
|
@ -45,6 +46,9 @@ GEM
|
|||
diff-lcs (1.2.5)
|
||||
equalizer (0.0.9)
|
||||
ffi (1.9.6-java)
|
||||
file-dependencies (0.1.4)
|
||||
minitar
|
||||
filesize (0.0.4)
|
||||
ftw (0.0.42)
|
||||
addressable
|
||||
backports (>= 2.6.2)
|
||||
|
@ -56,10 +60,11 @@ GEM
|
|||
ice_nine (0.11.1)
|
||||
insist (1.0.0)
|
||||
jar-dependencies (0.1.2)
|
||||
jrjackson (0.2.7)
|
||||
jrjackson (0.2.8)
|
||||
jruby-httpclient (1.1.1-java)
|
||||
logstash-devutils (0.0.6-java)
|
||||
logstash-devutils (0.0.7-java)
|
||||
gem_publisher
|
||||
insist (= 1.0.0)
|
||||
jar-dependencies
|
||||
minitar
|
||||
rake
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue