fluentd 0.14.0 → 0.14.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of fluentd might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/example/copy_roundrobin.conf +39 -0
- data/example/filter_stdout.conf +5 -5
- data/example/in_forward.conf +2 -2
- data/example/in_http.conf +2 -2
- data/example/in_syslog.conf +2 -2
- data/example/in_tail.conf +2 -2
- data/example/in_tcp.conf +2 -2
- data/example/in_udp.conf +2 -2
- data/example/out_buffered_null.conf +32 -0
- data/example/out_copy.conf +4 -4
- data/example/out_file.conf +2 -2
- data/example/out_forward.conf +2 -2
- data/example/v0_12_filter.conf +8 -8
- data/fluentd.gemspec +1 -1
- data/lib/fluent/command/fluentd.rb +6 -1
- data/lib/fluent/compat/handle_tag_name_mixin.rb +53 -0
- data/lib/fluent/compat/input.rb +1 -0
- data/lib/fluent/compat/output.rb +1 -0
- data/lib/fluent/compat/record_filter_mixin.rb +34 -0
- data/lib/fluent/compat/set_tag_key_mixin.rb +50 -0
- data/lib/fluent/compat/set_time_key_mixin.rb +69 -0
- data/lib/fluent/compat/type_converter.rb +90 -0
- data/lib/fluent/config/configure_proxy.rb +24 -4
- data/lib/fluent/config/dsl.rb +18 -1
- data/lib/fluent/config/v1_parser.rb +3 -2
- data/lib/fluent/configurable.rb +1 -1
- data/lib/fluent/event.rb +37 -9
- data/lib/fluent/mixin.rb +12 -286
- data/lib/fluent/plugin/buffer.rb +2 -2
- data/lib/fluent/plugin/in_dummy.rb +5 -1
- data/lib/fluent/plugin/in_gc_stat.rb +7 -37
- data/lib/fluent/plugin/in_http.rb +2 -0
- data/lib/fluent/plugin/{in_stream.rb → in_unix.rb} +0 -0
- data/lib/fluent/plugin/out_buffered_stdout.rb +60 -0
- data/lib/fluent/plugin/out_copy.rb +8 -51
- data/lib/fluent/plugin/out_null.rb +5 -5
- data/lib/fluent/plugin/out_relabel.rb +5 -5
- data/lib/fluent/plugin/out_roundrobin.rb +13 -40
- data/lib/fluent/plugin/output.rb +9 -0
- data/lib/fluent/plugin_helper.rb +2 -0
- data/lib/fluent/plugin_helper/formatter.rb +138 -0
- data/lib/fluent/plugin_helper/inject.rb +112 -0
- data/lib/fluent/plugin_helper/parser.rb +138 -0
- data/lib/fluent/plugin_helper/storage.rb +64 -50
- data/lib/fluent/process.rb +6 -1
- data/lib/fluent/registry.rb +1 -1
- data/lib/fluent/supervisor.rb +20 -2
- data/lib/fluent/test.rb +30 -5
- data/lib/fluent/test/base.rb +2 -66
- data/lib/fluent/test/driver/base.rb +3 -0
- data/lib/fluent/test/driver/base_owned.rb +106 -0
- data/lib/fluent/test/driver/formatter.rb +30 -0
- data/lib/fluent/test/driver/multi_output.rb +52 -0
- data/lib/fluent/test/driver/owner.rb +32 -0
- data/lib/fluent/test/driver/parser.rb +30 -0
- data/lib/fluent/test/helpers.rb +54 -0
- data/lib/fluent/test/log.rb +73 -0
- data/lib/fluent/time.rb +71 -0
- data/lib/fluent/version.rb +1 -1
- data/test/compat/test_parser.rb +82 -0
- data/test/config/test_configure_proxy.rb +15 -0
- data/test/config/test_dsl.rb +180 -2
- data/test/helper.rb +2 -24
- data/test/plugin/test_in_gc_stat.rb +6 -6
- data/test/plugin/test_in_http.rb +49 -32
- data/test/plugin/{test_in_stream.rb → test_in_unix.rb} +1 -1
- data/test/plugin/test_out_buffered_stdout.rb +108 -0
- data/test/plugin/test_out_copy.rb +88 -127
- data/test/plugin/test_out_null.rb +29 -0
- data/test/plugin/test_out_relabel.rb +28 -0
- data/test/plugin/test_out_roundrobin.rb +35 -29
- data/test/plugin/test_out_stdout.rb +4 -4
- data/test/plugin/test_output_as_buffered.rb +51 -0
- data/test/plugin/test_output_as_buffered_secondary.rb +13 -0
- data/test/plugin/test_parser_apache.rb +38 -0
- data/test/plugin/test_parser_apache2.rb +38 -0
- data/test/plugin/test_parser_apache_error.rb +40 -0
- data/test/plugin/test_parser_base.rb +32 -0
- data/test/plugin/test_parser_csv.rb +94 -0
- data/test/plugin/test_parser_json.rb +107 -0
- data/test/plugin/test_parser_labeled_tsv.rb +129 -0
- data/test/plugin/test_parser_multiline.rb +100 -0
- data/test/plugin/test_parser_nginx.rb +42 -0
- data/test/plugin/test_parser_none.rb +53 -0
- data/test/plugin/test_parser_regexp.rb +110 -0
- data/test/plugin/test_parser_syslog.rb +66 -0
- data/test/plugin/test_parser_time.rb +46 -0
- data/test/plugin/test_parser_tsv.rb +125 -0
- data/test/plugin_helper/test_child_process.rb +11 -2
- data/test/plugin_helper/test_formatter.rb +212 -0
- data/test/plugin_helper/test_inject.rb +388 -0
- data/test/plugin_helper/test_parser.rb +223 -0
- data/test/plugin_helper/test_retry_state.rb +40 -40
- data/test/plugin_helper/test_storage.rb +77 -10
- data/test/scripts/fluent/plugin/out_test.rb +22 -17
- data/test/scripts/fluent/plugin/out_test2.rb +80 -0
- data/test/test_event.rb +57 -0
- data/test/test_formatter.rb +0 -178
- data/test/test_output.rb +2 -152
- data/test/test_root_agent.rb +3 -2
- data/test/test_supervisor.rb +93 -26
- data/test/test_time_formatter.rb +186 -0
- metadata +69 -7
- data/test/test_parser.rb +0 -1087
@@ -0,0 +1,32 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'fluent/plugin/base'
|
18
|
+
require 'fluent/plugin_id'
|
19
|
+
require 'fluent/log'
|
20
|
+
require 'fluent/plugin_helper'
|
21
|
+
|
22
|
+
module Fluent
|
23
|
+
module Test
|
24
|
+
module Driver
|
25
|
+
class Owner < Fluent::Plugin::Base
|
26
|
+
include PluginId
|
27
|
+
include PluginLoggerMixin
|
28
|
+
include PluginHelper::Mixin
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'fluent/test/driver/base_owned'
|
18
|
+
|
19
|
+
module Fluent
|
20
|
+
module Test
|
21
|
+
module Driver
|
22
|
+
class Parser < BaseOwned
|
23
|
+
def initialize(klass, **kwargs, &block)
|
24
|
+
super
|
25
|
+
@section_name = "parse"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'fluent/config/element'
|
18
|
+
require 'fluent/msgpack_factory'
|
19
|
+
require 'fluent/time'
|
20
|
+
|
21
|
+
module Fluent
|
22
|
+
module Test
|
23
|
+
module Helpers
|
24
|
+
def config_element(name = 'test', argument = '', params = {}, elements = [])
|
25
|
+
Fluent::Config::Element.new(name, argument, params, elements)
|
26
|
+
end
|
27
|
+
|
28
|
+
def event_time(str=nil, format: nil)
|
29
|
+
if str
|
30
|
+
if format
|
31
|
+
Fluent::EventTime.from_time(Time.strptime(str, format))
|
32
|
+
else
|
33
|
+
Fluent::EventTime.parse(str)
|
34
|
+
end
|
35
|
+
else
|
36
|
+
Fluent::EventTime.now
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def msgpack(type)
|
41
|
+
case type
|
42
|
+
when :factory
|
43
|
+
Fluent::MessagePackFactory.factory
|
44
|
+
when :packer
|
45
|
+
Fluent::MessagePackFactory.packer
|
46
|
+
when :unpacker
|
47
|
+
Fluent::MessagePackFactory.unpacker
|
48
|
+
else
|
49
|
+
raise ArgumentError, "unknown msgpack object type '#{type}'"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'serverengine'
|
18
|
+
require 'fluent/log'
|
19
|
+
|
20
|
+
module Fluent
|
21
|
+
module Test
|
22
|
+
class DummyLogDevice
|
23
|
+
attr_reader :logs
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
@logs = []
|
27
|
+
end
|
28
|
+
|
29
|
+
def reset
|
30
|
+
@logs = []
|
31
|
+
end
|
32
|
+
|
33
|
+
def tty?
|
34
|
+
false
|
35
|
+
end
|
36
|
+
|
37
|
+
def puts(*args)
|
38
|
+
args.each{ |arg| write(arg + "\n") }
|
39
|
+
end
|
40
|
+
|
41
|
+
def write(message)
|
42
|
+
@logs.push message
|
43
|
+
end
|
44
|
+
|
45
|
+
def flush
|
46
|
+
true
|
47
|
+
end
|
48
|
+
|
49
|
+
def close
|
50
|
+
true
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class TestLogger < Fluent::PluginLogger
|
55
|
+
def initialize
|
56
|
+
@logdev = DummyLogDevice.new
|
57
|
+
dl_opts = {}
|
58
|
+
dl_opts[:log_level] = ServerEngine::DaemonLogger::INFO
|
59
|
+
logger = ServerEngine::DaemonLogger.new(@logdev, dl_opts)
|
60
|
+
log = Fluent::Log.new(logger)
|
61
|
+
super(log)
|
62
|
+
end
|
63
|
+
|
64
|
+
def reset
|
65
|
+
@logdev.reset
|
66
|
+
end
|
67
|
+
|
68
|
+
def logs
|
69
|
+
@logdev.logs
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/fluent/time.rb
CHANGED
@@ -16,6 +16,7 @@
|
|
16
16
|
|
17
17
|
require 'time'
|
18
18
|
require 'msgpack'
|
19
|
+
require 'fluent/timezone'
|
19
20
|
|
20
21
|
module Fluent
|
21
22
|
class EventTime
|
@@ -101,4 +102,74 @@ module Fluent
|
|
101
102
|
@sec.send(name, *args, &block)
|
102
103
|
end
|
103
104
|
end
|
105
|
+
|
106
|
+
class TimeFormatter
|
107
|
+
def initialize(format, localtime, timezone = nil)
|
108
|
+
@tc1 = 0
|
109
|
+
@tc1_str = nil
|
110
|
+
@tc2 = 0
|
111
|
+
@tc2_str = nil
|
112
|
+
|
113
|
+
if format && format =~ /(^|[^%])(%%)*%L|(^|[^%])(%%)*%\d*N/
|
114
|
+
define_singleton_method(:format, method(:format_with_subsec))
|
115
|
+
define_singleton_method(:call, method(:format_with_subsec))
|
116
|
+
else
|
117
|
+
define_singleton_method(:format, method(:format_without_subsec))
|
118
|
+
define_singleton_method(:call, method(:format_with_subsec))
|
119
|
+
end
|
120
|
+
|
121
|
+
formatter = Fluent::Timezone.formatter(timezone, format)
|
122
|
+
@format_nocache = case
|
123
|
+
when formatter then formatter
|
124
|
+
when format && localtime then ->(time){ Time.at(time).strftime(format) }
|
125
|
+
when format then ->(time){ Time.at(time).utc.strftime(format) }
|
126
|
+
when localtime then ->(time){ Time.at(time).iso8601 }
|
127
|
+
else ->(time){ Time.at(time).utc.iso8601 }
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def format_without_subsec(time)
|
132
|
+
if @tc1 == time
|
133
|
+
return @tc1_str
|
134
|
+
elsif @tc2 == time
|
135
|
+
return @tc2_str
|
136
|
+
else
|
137
|
+
str = format_nocache(time)
|
138
|
+
if @tc1 < @tc2
|
139
|
+
@tc1 = time
|
140
|
+
@tc1_str = str
|
141
|
+
else
|
142
|
+
@tc2 = time
|
143
|
+
@tc2_str = str
|
144
|
+
end
|
145
|
+
return str
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def format_with_subsec(time)
|
150
|
+
if Fluent::EventTime.eq?(@tc1, time)
|
151
|
+
return @tc1_str
|
152
|
+
elsif Fluent::EventTime.eq?(@tc2, time)
|
153
|
+
return @tc2_str
|
154
|
+
else
|
155
|
+
str = format_nocache(time)
|
156
|
+
if @tc1 < @tc2
|
157
|
+
@tc1 = time
|
158
|
+
@tc1_str = str
|
159
|
+
else
|
160
|
+
@tc2 = time
|
161
|
+
@tc2_str = str
|
162
|
+
end
|
163
|
+
return str
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
## Dynamically defined in #initialize
|
168
|
+
# def format(time)
|
169
|
+
# end
|
170
|
+
|
171
|
+
def format_nocache(time)
|
172
|
+
@format_nocache.call(time)
|
173
|
+
end
|
174
|
+
end
|
104
175
|
end
|
data/lib/fluent/version.rb
CHANGED
@@ -0,0 +1,82 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
require 'fluent/plugin/parser'
|
3
|
+
|
4
|
+
class TextParserTest < ::Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
Fluent::Test.setup
|
7
|
+
end
|
8
|
+
|
9
|
+
class MultiEventTestParser < ::Fluent::Parser
|
10
|
+
include Fluent::Configurable
|
11
|
+
|
12
|
+
def parse(text)
|
13
|
+
2.times { |i|
|
14
|
+
record = {}
|
15
|
+
record['message'] = text
|
16
|
+
record['number'] = i
|
17
|
+
yield Fluent::Engine.now, record
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Fluent::TextParser.register_template('multi_event_test', Proc.new { MultiEventTestParser.new })
|
23
|
+
|
24
|
+
def test_lookup_unknown_format
|
25
|
+
assert_raise Fluent::ConfigError do
|
26
|
+
Fluent::Plugin.new_parser('unknown')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
data('register_formatter' => 'known', 'register_template' => 'known_old')
|
31
|
+
def test_lookup_known_parser(data)
|
32
|
+
$LOAD_PATH.unshift(File.join(File.expand_path(File.dirname(__FILE__)), '..', 'scripts'))
|
33
|
+
assert_nothing_raised Fluent::ConfigError do
|
34
|
+
Fluent::Plugin.new_parser(data)
|
35
|
+
end
|
36
|
+
$LOAD_PATH.shift
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_parse_with_return
|
40
|
+
parser = Fluent::TextParser.new
|
41
|
+
parser.configure('format' => 'none')
|
42
|
+
_time, record = parser.parse('log message!')
|
43
|
+
assert_equal({'message' => 'log message!'}, record)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_parse_with_block
|
47
|
+
parser = Fluent::TextParser.new
|
48
|
+
parser.configure('format' => 'none')
|
49
|
+
parser.parse('log message!') { |time, record|
|
50
|
+
assert_equal({'message' => 'log message!'}, record)
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_multi_event_parser
|
55
|
+
parser = Fluent::TextParser.new
|
56
|
+
parser.configure('format' => 'multi_event_test')
|
57
|
+
i = 0
|
58
|
+
parser.parse('log message!') { |time, record|
|
59
|
+
assert_equal('log message!', record['message'])
|
60
|
+
assert_equal(i, record['number'])
|
61
|
+
i += 1
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_setting_estimate_current_event_value
|
66
|
+
p1 = Fluent::TextParser.new
|
67
|
+
assert_nil p1.estimate_current_event
|
68
|
+
assert_nil p1.parser
|
69
|
+
|
70
|
+
p1.configure('format' => 'none')
|
71
|
+
assert_equal true, p1.parser.estimate_current_event
|
72
|
+
|
73
|
+
p2 = Fluent::TextParser.new
|
74
|
+
assert_nil p2.estimate_current_event
|
75
|
+
assert_nil p2.parser
|
76
|
+
|
77
|
+
p2.estimate_current_event = false
|
78
|
+
|
79
|
+
p2.configure('format' => 'none')
|
80
|
+
assert_equal false, p2.parser.estimate_current_event
|
81
|
+
end
|
82
|
+
end
|
@@ -17,6 +17,7 @@ module Fluent::Config
|
|
17
17
|
assert_equal(:section, proxy.name)
|
18
18
|
assert_nil(proxy.param_name)
|
19
19
|
assert_equal(:section, proxy.variable_name)
|
20
|
+
assert_false(proxy.root?)
|
20
21
|
assert_nil(proxy.init)
|
21
22
|
assert_nil(proxy.required)
|
22
23
|
assert_false(proxy.required?)
|
@@ -94,6 +95,20 @@ module Fluent::Config
|
|
94
95
|
assert_false(proxy.multi?)
|
95
96
|
assert_equal :subsection, proxy.configured_in_section
|
96
97
|
end
|
98
|
+
|
99
|
+
test "does overwrite name of proxy for root sections which are used for plugins" do
|
100
|
+
# latest plugin class shows actual plugin implementation
|
101
|
+
p1 = Fluent::Config::ConfigureProxy.new('Fluent::Plugin::MyP1'.to_sym, root: true, required: true, multi: false, type_lookup: @type_lookup)
|
102
|
+
p1.config_param :key1, :integer
|
103
|
+
|
104
|
+
p2 = Fluent::Config::ConfigureProxy.new('Fluent::Plugin::MyP2'.to_sym, root: true, required: true, multi: false, type_lookup: @type_lookup)
|
105
|
+
p2.config_param :key2, :string, default: "value2"
|
106
|
+
|
107
|
+
merged = p1.merge(p2)
|
108
|
+
|
109
|
+
assert_equal 'Fluent::Plugin::MyP2'.to_sym, merged.name
|
110
|
+
assert_true merged.root?
|
111
|
+
end
|
97
112
|
end
|
98
113
|
|
99
114
|
sub_test_case '#overwrite_defaults' do
|
data/test/config/test_dsl.rb
CHANGED
@@ -2,6 +2,66 @@ require_relative '../helper'
|
|
2
2
|
require 'fluent/config/element'
|
3
3
|
require "fluent/config/dsl"
|
4
4
|
|
5
|
+
TMP_DIR = File.dirname(__FILE__) + "/tmp/config_dsl#{ENV['TEST_ENV_NUMBER']}"
|
6
|
+
def write_config(path, data)
|
7
|
+
FileUtils.mkdir_p(File.dirname(path))
|
8
|
+
File.open(path, "w") {|f| f.write data }
|
9
|
+
end
|
10
|
+
|
11
|
+
def prepare_config1
|
12
|
+
write_config "#{TMP_DIR}/config_test_1.conf", %[
|
13
|
+
k1 root_config
|
14
|
+
include dir/config_test_2.conf #
|
15
|
+
@include #{TMP_DIR}/config_test_4.conf
|
16
|
+
include file://#{TMP_DIR}/config_test_5.conf
|
17
|
+
@include config.d/*.conf
|
18
|
+
]
|
19
|
+
write_config "#{TMP_DIR}/dir/config_test_2.conf", %[
|
20
|
+
k2 relative_path_include
|
21
|
+
@include ../config_test_3.conf
|
22
|
+
]
|
23
|
+
write_config "#{TMP_DIR}/config_test_3.conf", %[
|
24
|
+
k3 relative_include_in_included_file
|
25
|
+
]
|
26
|
+
write_config "#{TMP_DIR}/config_test_4.conf", %[
|
27
|
+
k4 absolute_path_include
|
28
|
+
]
|
29
|
+
write_config "#{TMP_DIR}/config_test_5.conf", %[
|
30
|
+
k5 uri_include
|
31
|
+
]
|
32
|
+
write_config "#{TMP_DIR}/config.d/config_test_6.conf", %[
|
33
|
+
k6 wildcard_include_1
|
34
|
+
<elem1 name>
|
35
|
+
include normal_parameter
|
36
|
+
</elem1>
|
37
|
+
]
|
38
|
+
write_config "#{TMP_DIR}/config.d/config_test_7.conf", %[
|
39
|
+
k7 wildcard_include_2
|
40
|
+
]
|
41
|
+
write_config "#{TMP_DIR}/config.d/config_test_8.conf", %[
|
42
|
+
<elem2 name>
|
43
|
+
@include ../dir/config_test_9.conf
|
44
|
+
</elem2>
|
45
|
+
]
|
46
|
+
write_config "#{TMP_DIR}/dir/config_test_9.conf", %[
|
47
|
+
k9 embeded
|
48
|
+
<elem3 name>
|
49
|
+
nested nested_value
|
50
|
+
include hoge
|
51
|
+
</elem3>
|
52
|
+
]
|
53
|
+
write_config "#{TMP_DIR}/config.d/00_config_test_8.conf", %[
|
54
|
+
k8 wildcard_include_3
|
55
|
+
<elem4 name>
|
56
|
+
include normal_parameter
|
57
|
+
</elem4>
|
58
|
+
]
|
59
|
+
end
|
60
|
+
|
61
|
+
def prepare_config2
|
62
|
+
write_config "#{TMP_DIR}/config_test_1.rb", DSL_CONFIG_EXAMPLE
|
63
|
+
end
|
64
|
+
|
5
65
|
DSL_CONFIG_EXAMPLE = %q[
|
6
66
|
worker {
|
7
67
|
hostname = "myhostname"
|
@@ -57,6 +117,14 @@ source {
|
|
57
117
|
}
|
58
118
|
]
|
59
119
|
|
120
|
+
DSL_CONFIG_EXAMPLE_FOR_INCLUDE_CONF = %q[
|
121
|
+
include "#{TMP_DIR}/config_test_1.conf"
|
122
|
+
]
|
123
|
+
|
124
|
+
DSL_CONFIG_EXAMPLE_FOR_INCLUDE_RB = %q[
|
125
|
+
include "#{TMP_DIR}/config_test_1.rb"
|
126
|
+
]
|
127
|
+
|
60
128
|
DSL_CONFIG_RETURNS_NON_ELEMENT = %q[
|
61
129
|
worker {
|
62
130
|
}
|
@@ -74,6 +142,9 @@ match('aa','bb'){
|
|
74
142
|
DSL_CONFIG_WRONG_SYNTAX3 = %q[
|
75
143
|
match('aa','bb')
|
76
144
|
]
|
145
|
+
DSL_CONFIG_WRONG_SYNTAX4 = %q[
|
146
|
+
include
|
147
|
+
]
|
77
148
|
|
78
149
|
module Fluent::Config
|
79
150
|
class TestDSLParser < ::Test::Unit::TestCase
|
@@ -158,6 +229,112 @@ module Fluent::Config
|
|
158
229
|
end
|
159
230
|
end
|
160
231
|
|
232
|
+
sub_test_case 'with include conf' do
|
233
|
+
def setup
|
234
|
+
prepare_config1
|
235
|
+
@root = Fluent::Config::DSL::Parser.parse(DSL_CONFIG_EXAMPLE_FOR_INCLUDE_CONF, 'dsl_config_for_include.conf')
|
236
|
+
end
|
237
|
+
test 'include config' do
|
238
|
+
assert_equal('root_config', @root['k1'])
|
239
|
+
assert_equal('relative_path_include', @root['k2'])
|
240
|
+
assert_equal('relative_include_in_included_file', @root['k3'])
|
241
|
+
assert_equal('absolute_path_include', @root['k4'])
|
242
|
+
assert_equal('uri_include', @root['k5'])
|
243
|
+
assert_equal('wildcard_include_1', @root['k6'])
|
244
|
+
assert_equal('wildcard_include_2', @root['k7'])
|
245
|
+
assert_equal('wildcard_include_3', @root['k8'])
|
246
|
+
assert_equal([
|
247
|
+
'k1',
|
248
|
+
'k2',
|
249
|
+
'k3',
|
250
|
+
'k4',
|
251
|
+
'k5',
|
252
|
+
'k8', # Because of the file name this comes first.
|
253
|
+
'k6',
|
254
|
+
'k7',
|
255
|
+
], @root.keys)
|
256
|
+
|
257
|
+
elem1 = @root.elements.find { |e| e.name == 'elem1' }
|
258
|
+
assert(elem1)
|
259
|
+
assert_equal('name', elem1.arg)
|
260
|
+
assert_equal('normal_parameter', elem1['include'])
|
261
|
+
|
262
|
+
elem2 = @root.elements.find { |e| e.name == 'elem2' }
|
263
|
+
assert(elem2)
|
264
|
+
assert_equal('name', elem2.arg)
|
265
|
+
assert_equal('embeded', elem2['k9'])
|
266
|
+
assert_not_include(elem2, 'include')
|
267
|
+
|
268
|
+
elem3 = elem2.elements.find { |e| e.name == 'elem3' }
|
269
|
+
assert(elem3)
|
270
|
+
assert_equal('nested_value', elem3['nested'])
|
271
|
+
assert_equal('hoge', elem3['include'])
|
272
|
+
end
|
273
|
+
|
274
|
+
# TODO: Add uri based include spec
|
275
|
+
end
|
276
|
+
|
277
|
+
sub_test_case 'with include rb' do
|
278
|
+
def setup
|
279
|
+
prepare_config2
|
280
|
+
@root = Fluent::Config::DSL::Parser.parse(DSL_CONFIG_EXAMPLE_FOR_INCLUDE_RB, 'dsl_config_for_include.rb')
|
281
|
+
end
|
282
|
+
sub_test_case '.parse' do
|
283
|
+
test 'makes root element' do
|
284
|
+
assert_equal('ROOT', @root.name)
|
285
|
+
assert_predicate(@root.arg, :empty?)
|
286
|
+
assert_equal(0, @root.keys.size)
|
287
|
+
end
|
288
|
+
|
289
|
+
test 'makes worker element for worker tag' do
|
290
|
+
assert_equal(1, @root.elements.size)
|
291
|
+
|
292
|
+
worker = @root.elements.first
|
293
|
+
assert_equal('worker', worker.name)
|
294
|
+
assert_predicate(worker.arg, :empty?)
|
295
|
+
assert_equal(0, worker.keys.size)
|
296
|
+
assert_equal(10, worker.elements.size)
|
297
|
+
end
|
298
|
+
|
299
|
+
test 'makes subsections for blocks, with variable substitution' do
|
300
|
+
ele4 = @root.elements.first.elements[4]
|
301
|
+
|
302
|
+
assert_equal('source', ele4.name)
|
303
|
+
assert_predicate(ele4.arg, :empty?)
|
304
|
+
assert_equal(2, ele4.keys.size)
|
305
|
+
assert_equal('tail', ele4['type'])
|
306
|
+
assert_equal("/var/log/httpd/access.part4.log", ele4['path'])
|
307
|
+
end
|
308
|
+
|
309
|
+
test 'makes user-defined sections with blocks' do
|
310
|
+
filter0 = @root.elements.first.elements[4].elements.first
|
311
|
+
|
312
|
+
assert_equal('filter', filter0.name)
|
313
|
+
assert_equal('bar.**', filter0.arg)
|
314
|
+
assert_equal('hoge', filter0['type'])
|
315
|
+
assert_equal('moge', filter0['val1'])
|
316
|
+
assert_equal(JSON.dump(['foo', 'bar', 'baz']), filter0['val2'])
|
317
|
+
assert_equal('10', filter0['val3'])
|
318
|
+
assert_equal('hoge', filter0['id'])
|
319
|
+
|
320
|
+
assert_equal(2, filter0.elements.size)
|
321
|
+
assert_equal('subsection', filter0.elements[0].name)
|
322
|
+
assert_equal('bar', filter0.elements[0]['foo'])
|
323
|
+
assert_equal('subsection', filter0.elements[1].name)
|
324
|
+
assert_equal('baz', filter0.elements[1]['foo'])
|
325
|
+
end
|
326
|
+
|
327
|
+
test 'makes values with user-assigned variable substitutions' do
|
328
|
+
match0 = @root.elements.first.elements[4].elements.last
|
329
|
+
|
330
|
+
assert_equal('match', match0.name)
|
331
|
+
assert_equal('{foo,bar}.**', match0.arg)
|
332
|
+
assert_equal('file', match0['type'])
|
333
|
+
assert_equal('/var/log/httpd/access.myhostname.4.log', match0['path'])
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
161
338
|
sub_test_case 'with configuration that returns non element on top' do
|
162
339
|
sub_test_case '.parse' do
|
163
340
|
test 'does not crash' do
|
@@ -170,8 +347,9 @@ module Fluent::Config
|
|
170
347
|
sub_test_case '.parse' do
|
171
348
|
test 'raises ArgumentError correctly' do
|
172
349
|
assert_raise(ArgumentError) { Fluent::Config::DSL::Parser.parse(DSL_CONFIG_WRONG_SYNTAX1, 'dsl_config_wrong_syntax1') }
|
173
|
-
assert_raise(ArgumentError) { Fluent::Config::DSL::Parser.parse(DSL_CONFIG_WRONG_SYNTAX2, '
|
174
|
-
assert_raise(ArgumentError) { Fluent::Config::DSL::Parser.parse(DSL_CONFIG_WRONG_SYNTAX3, '
|
350
|
+
assert_raise(ArgumentError) { Fluent::Config::DSL::Parser.parse(DSL_CONFIG_WRONG_SYNTAX2, 'dsl_config_wrong_syntax2') }
|
351
|
+
assert_raise(ArgumentError) { Fluent::Config::DSL::Parser.parse(DSL_CONFIG_WRONG_SYNTAX3, 'dsl_config_wrong_syntax3') }
|
352
|
+
assert_raise(ArgumentError) { Fluent::Config::DSL::Parser.parse(DSL_CONFIG_WRONG_SYNTAX4, 'dsl_config_wrong_syntax4') }
|
175
353
|
end
|
176
354
|
end
|
177
355
|
end
|