mirror of
https://github.com/fluent/fluentd-ui.git
synced 2025-08-11 08:47:06 +02:00
Add Fluentd::Agent::Common#parse_config
Signed-off-by: Kenji Okimoto <okimoto@clear-code.com>
This commit is contained in:
parent
7615eaeb0b
commit
5a31d9b9d0
@ -18,6 +18,8 @@
|
|||||||
# - https://github.com/treasure-data/omnibus-td-agent/blob/master/templates/etc/systemd/td-agent.service.erb#L14
|
# - https://github.com/treasure-data/omnibus-td-agent/blob/master/templates/etc/systemd/td-agent.service.erb#L14
|
||||||
# fluentd: /etc/fluent/fluent.conf (created by fluentd -s)
|
# fluentd: /etc/fluent/fluent.conf (created by fluentd -s)
|
||||||
|
|
||||||
|
require "strscan"
|
||||||
|
|
||||||
class Fluentd
|
class Fluentd
|
||||||
class Agent
|
class Agent
|
||||||
module Common
|
module Common
|
||||||
@ -142,6 +144,39 @@ class Fluentd
|
|||||||
FileUtils.rm(file) if File.exist? file
|
FileUtils.rm(file) if File.exist? file
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def parse_config(config_content)
|
||||||
|
scanner = StringScanner.new(config_content)
|
||||||
|
contents = Hash.new {|h, k| h[k] = [] }
|
||||||
|
until scanner.eos? do
|
||||||
|
started = scanner.pos
|
||||||
|
header = scanner.scan_until(/^<(source|filter|match|label)/)
|
||||||
|
section_type = scanner[1]
|
||||||
|
break unless header
|
||||||
|
case section_type
|
||||||
|
when "source", "filter", "match"
|
||||||
|
current_source = header + scanner.scan_until(%r{^</(?:source|filter|match)>})
|
||||||
|
contents[section_type] << { pos: started, content: current_source.strip }
|
||||||
|
when "label"
|
||||||
|
scanner.scan(/ ([^\s]+?)>/)
|
||||||
|
label = scanner[1]
|
||||||
|
sections = Hash.new {|h, k| h[k] = [] }
|
||||||
|
loop do
|
||||||
|
break if scanner.match?(%r{\s+?</label>})
|
||||||
|
section_pos = scanner.pos
|
||||||
|
section_header = scanner.scan_until(/^\s*<(filter|match)/)
|
||||||
|
section_type = scanner[1]
|
||||||
|
section_source = section_header + scanner.scan_until(%r{^\s*</(?:filter|match)>})
|
||||||
|
sections[section_type] << { pos: section_pos ,content: section_source.sub(/\n/, "")}
|
||||||
|
end
|
||||||
|
scanner.scan_until(%r{^</label>})
|
||||||
|
contents["label:#{label}"] << { pos: started, sections: sections }
|
||||||
|
else
|
||||||
|
raise TypeError, "Unknown section: #{started}: #{section_type}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
contents
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
170
test/models/fluentd/agent_common_test.rb
Normal file
170
test/models/fluentd/agent_common_test.rb
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
require "test_helper"
|
||||||
|
|
||||||
|
class Fluentd
|
||||||
|
class TestAgentCommon < ActiveSupport::TestCase
|
||||||
|
class DummyAgent
|
||||||
|
include ::Fluentd::Agent::Common
|
||||||
|
end
|
||||||
|
|
||||||
|
setup do
|
||||||
|
@agent = DummyAgent.new
|
||||||
|
end
|
||||||
|
|
||||||
|
sub_test_case "#parse_config" do
|
||||||
|
test "empty" do
|
||||||
|
actual = @agent.__send__(:parse_config, "")
|
||||||
|
assert_equal({}, actual)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "simple" do
|
||||||
|
actual = @agent.__send__(:parse_config, fixture_content("config/simple.conf"))
|
||||||
|
source_section_content = <<-CONFIG.strip_heredoc.chomp
|
||||||
|
<source>
|
||||||
|
@type dummy
|
||||||
|
tag dummy
|
||||||
|
</source>
|
||||||
|
CONFIG
|
||||||
|
filter_section_content = <<-CONFIG.strip_heredoc.chomp
|
||||||
|
<filter dummy>
|
||||||
|
@type stdout
|
||||||
|
</filter>
|
||||||
|
CONFIG
|
||||||
|
match_section_content = <<-CONFIG.strip_heredoc.chomp
|
||||||
|
<match dummy>
|
||||||
|
@type stdout
|
||||||
|
</match>
|
||||||
|
CONFIG
|
||||||
|
expected = {
|
||||||
|
"source" => [
|
||||||
|
{ pos: 0, content: source_section_content }
|
||||||
|
],
|
||||||
|
"filter" => [
|
||||||
|
{ pos: 44, content: filter_section_content }
|
||||||
|
],
|
||||||
|
"match" => [
|
||||||
|
{ pos: 84, content: match_section_content }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
assert_equal(expected, actual)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "simple label" do
|
||||||
|
actual = @agent.__send__(:parse_config, fixture_content("config/label.conf"))
|
||||||
|
source_section_content = <<-CONFIG.strip_heredoc.chomp
|
||||||
|
<source>
|
||||||
|
@type dummy
|
||||||
|
tag dummy
|
||||||
|
@label @INPUT
|
||||||
|
</source>
|
||||||
|
CONFIG
|
||||||
|
filter_section_content = <<-CONFIG.chomp
|
||||||
|
<filter dummy>
|
||||||
|
@type stdout
|
||||||
|
</filter>
|
||||||
|
CONFIG
|
||||||
|
match_section_content = <<-CONFIG.chomp
|
||||||
|
<match dummy>
|
||||||
|
@type stdout
|
||||||
|
</match>
|
||||||
|
CONFIG
|
||||||
|
sections = {
|
||||||
|
"filter" => [
|
||||||
|
{ pos: 75, content: filter_section_content}
|
||||||
|
],
|
||||||
|
"match" => [
|
||||||
|
{ pos: 121, content: match_section_content}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
expected = {
|
||||||
|
"source" => [
|
||||||
|
{ pos: 0, content: source_section_content }
|
||||||
|
],
|
||||||
|
"label:@INPUT" => [
|
||||||
|
{ pos: 60, sections: sections }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
assert_equal(expected, actual)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "multiple labels" do
|
||||||
|
actual = @agent.__send__(:parse_config, fixture_content("config/multi-label.conf"))
|
||||||
|
source_section_content1 = <<-CONFIG.strip_heredoc.chomp
|
||||||
|
<source>
|
||||||
|
@type dummy
|
||||||
|
tag dummy1
|
||||||
|
@label @INPUT
|
||||||
|
</source>
|
||||||
|
CONFIG
|
||||||
|
source_section_content2 = <<-CONFIG.strip_heredoc.chomp
|
||||||
|
<source>
|
||||||
|
@type dummy
|
||||||
|
tag dummy2
|
||||||
|
@label @INPUT
|
||||||
|
</source>
|
||||||
|
CONFIG
|
||||||
|
filter_section_content = <<-CONFIG.chomp
|
||||||
|
<filter dummy1>
|
||||||
|
@type stdout
|
||||||
|
</filter>
|
||||||
|
CONFIG
|
||||||
|
match_section_content = <<-CONFIG.chomp
|
||||||
|
<match dummy1>
|
||||||
|
@type relabel
|
||||||
|
@label @MAIN
|
||||||
|
</match>
|
||||||
|
CONFIG
|
||||||
|
input_sections = {
|
||||||
|
"filter" => [
|
||||||
|
{ pos: 140, content: filter_section_content }
|
||||||
|
],
|
||||||
|
"match" => [
|
||||||
|
{ pos: 187, content: match_section_content }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
filter_secion_content1 = <<-CONFIG.chomp
|
||||||
|
<filter dummy1>
|
||||||
|
@type stdout
|
||||||
|
</filter>
|
||||||
|
CONFIG
|
||||||
|
filter_secion_content2 = <<-CONFIG.chomp
|
||||||
|
<filter dummy2>
|
||||||
|
@type stdout
|
||||||
|
</filter>
|
||||||
|
CONFIG
|
||||||
|
match_secion_content1 = <<-CONFIG.chomp
|
||||||
|
<match dummy1>
|
||||||
|
@type stdout
|
||||||
|
</match>
|
||||||
|
CONFIG
|
||||||
|
match_secion_content2 = <<-CONFIG.chomp
|
||||||
|
<match dummy2>
|
||||||
|
@type stdout
|
||||||
|
</match>
|
||||||
|
CONFIG
|
||||||
|
main_sections = {
|
||||||
|
"filter" => [
|
||||||
|
{ pos: 274, content: filter_secion_content1 },
|
||||||
|
{ pos: 321, content: filter_secion_content2 }
|
||||||
|
],
|
||||||
|
"match" => [
|
||||||
|
{ pos: 368, content: match_secion_content1 },
|
||||||
|
{ pos: 413, content: match_secion_content2 }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
expected = {
|
||||||
|
"source" => [
|
||||||
|
{ pos: 0, content: source_section_content1 },
|
||||||
|
{ pos: 61, content: source_section_content2 },
|
||||||
|
],
|
||||||
|
"label:@INPUT" => [
|
||||||
|
{ pos: 124, sections: input_sections }
|
||||||
|
],
|
||||||
|
"label:@MAIN" => [
|
||||||
|
{ pos: 259, sections: main_sections }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
assert_equal(expected, actual)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -18,6 +18,10 @@ module FixturePath
|
|||||||
def fixture_path(fixture_name)
|
def fixture_path(fixture_name)
|
||||||
Rails.root.join("test/fixtures", fixture_name).to_s
|
Rails.root.join("test/fixtures", fixture_name).to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def fixture_content(fixture_name)
|
||||||
|
Rails.root.join("test/fixtures", fixture_name).read
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class ActiveSupport::TestCase
|
class ActiveSupport::TestCase
|
||||||
|
Loading…
Reference in New Issue
Block a user