fluentd 0.12.0.pre.1 → 0.12.0.pre.2
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/.gitignore +1 -1
- data/.travis.yml +1 -0
- data/ChangeLog +21 -0
- data/README.md +10 -2
- data/Rakefile +4 -13
- data/example/v1_literal_example.conf +36 -0
- data/fluentd.gemspec +4 -1
- data/lib/fluent/buffer.rb +73 -46
- data/lib/fluent/command/fluentd.rb +7 -2
- data/lib/fluent/config/basic_parser.rb +5 -0
- data/lib/fluent/config/element.rb +2 -5
- data/lib/fluent/config/literal_parser.rb +26 -7
- data/lib/fluent/config/section.rb +2 -0
- data/lib/fluent/config/v1_parser.rb +9 -2
- data/lib/fluent/formatter.rb +2 -1
- data/lib/fluent/mixin.rb +22 -7
- data/lib/fluent/output.rb +17 -8
- data/lib/fluent/parser.rb +14 -3
- data/lib/fluent/plugin/buf_file.rb +30 -15
- data/lib/fluent/plugin/filter_grep.rb +69 -0
- data/lib/fluent/plugin/filter_record_transformer.rb +183 -0
- data/lib/fluent/plugin/in_exec.rb +6 -0
- data/lib/fluent/plugin/in_forward.rb +34 -4
- data/lib/fluent/plugin/in_http.rb +1 -1
- data/lib/fluent/plugin/out_exec.rb +1 -1
- data/lib/fluent/plugin/out_exec_filter.rb +8 -1
- data/lib/fluent/plugin/out_forward.rb +82 -4
- data/lib/fluent/supervisor.rb +1 -1
- data/lib/fluent/timezone.rb +131 -0
- data/lib/fluent/version.rb +1 -1
- data/test/config/assertions.rb +42 -0
- data/test/config/test_config_parser.rb +385 -0
- data/test/config/test_configurable.rb +530 -0
- data/test/config/test_configure_proxy.rb +99 -0
- data/test/config/test_dsl.rb +237 -0
- data/test/config/test_literal_parser.rb +293 -0
- data/test/config/test_section.rb +112 -0
- data/test/config/test_system_config.rb +49 -0
- data/test/helper.rb +25 -0
- data/test/plugin/test_buf_file.rb +604 -0
- data/test/plugin/test_buf_memory.rb +204 -0
- data/test/plugin/test_filter_grep.rb +124 -0
- data/test/plugin/test_filter_record_transformer.rb +251 -0
- data/test/plugin/test_in_exec.rb +1 -0
- data/test/plugin/test_in_forward.rb +205 -2
- data/test/plugin/test_in_gc_stat.rb +1 -0
- data/test/plugin/test_in_http.rb +58 -2
- data/test/plugin/test_in_object_space.rb +1 -0
- data/test/plugin/test_in_status.rb +1 -0
- data/test/plugin/test_in_stream.rb +1 -1
- data/test/plugin/test_in_syslog.rb +1 -1
- data/test/plugin/test_in_tail.rb +1 -0
- data/test/plugin/test_in_tcp.rb +1 -1
- data/test/plugin/test_in_udp.rb +1 -1
- data/test/plugin/test_out_copy.rb +1 -0
- data/test/plugin/test_out_exec.rb +1 -0
- data/test/plugin/test_out_exec_filter.rb +1 -0
- data/test/plugin/test_out_file.rb +36 -0
- data/test/plugin/test_out_forward.rb +279 -8
- data/test/plugin/test_out_roundrobin.rb +1 -0
- data/test/plugin/test_out_stdout.rb +1 -0
- data/test/plugin/test_out_stream.rb +1 -1
- data/test/test_buffer.rb +530 -0
- data/test/test_config.rb +1 -1
- data/test/test_configdsl.rb +1 -1
- data/test/test_formatter.rb +223 -0
- data/test/test_match.rb +1 -2
- data/test/test_mixin.rb +74 -2
- data/test/test_parser.rb +7 -1
- metadata +88 -35
- data/lib/fluent/plugin/buf_zfile.rb +0 -75
- data/spec/config/config_parser_spec.rb +0 -314
- data/spec/config/configurable_spec.rb +0 -524
- data/spec/config/configure_proxy_spec.rb +0 -96
- data/spec/config/dsl_spec.rb +0 -239
- data/spec/config/helper.rb +0 -49
- data/spec/config/literal_parser_spec.rb +0 -222
- data/spec/config/section_spec.rb +0 -97
- data/spec/config/system_config_spec.rb +0 -49
- data/spec/spec_helper.rb +0 -60
@@ -0,0 +1,204 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'helper'
|
3
|
+
require 'fluent/test'
|
4
|
+
require 'fluent/plugin/buf_memory'
|
5
|
+
|
6
|
+
require 'stringio'
|
7
|
+
require 'msgpack'
|
8
|
+
|
9
|
+
module FluentMemoryBufferTest
|
10
|
+
class MemoryBufferChunkTest < Test::Unit::TestCase
|
11
|
+
def test_init
|
12
|
+
chunk = Fluent::MemoryBufferChunk.new('key')
|
13
|
+
assert_equal 'key', chunk.key
|
14
|
+
assert_equal '', chunk.instance_eval{ @data }
|
15
|
+
assert_equal 'ASCII-8BIT', chunk.instance_eval{ @data }.encoding.to_s
|
16
|
+
assert chunk.unique_id # non nil
|
17
|
+
|
18
|
+
chunk2 = Fluent::MemoryBufferChunk.new('initdata', 'data')
|
19
|
+
assert_equal 'initdata', chunk2.key
|
20
|
+
assert_equal 'data', chunk2.instance_eval{ @data }
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_buffer_chunk_interface
|
24
|
+
chunk = Fluent::BufferChunk.new('key')
|
25
|
+
|
26
|
+
assert chunk.respond_to?(:empty?)
|
27
|
+
assert chunk.respond_to?(:<<)
|
28
|
+
assert chunk.respond_to?(:size)
|
29
|
+
assert chunk.respond_to?(:close)
|
30
|
+
assert chunk.respond_to?(:purge)
|
31
|
+
assert chunk.respond_to?(:read)
|
32
|
+
assert chunk.respond_to?(:open)
|
33
|
+
assert chunk.respond_to?(:write_to)
|
34
|
+
assert chunk.respond_to?(:msgpack_each)
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_empty?
|
38
|
+
chunk = Fluent::MemoryBufferChunk.new('key')
|
39
|
+
assert chunk.empty?
|
40
|
+
|
41
|
+
chunk.instance_eval{ @data = "non empty" }
|
42
|
+
assert !(chunk.empty?)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_append_data_and_size
|
46
|
+
chunk = Fluent::MemoryBufferChunk.new('key')
|
47
|
+
assert_equal '', chunk.instance_eval{ @data }
|
48
|
+
|
49
|
+
chunk << "foo bar baz\n".force_encoding('UTF-8')
|
50
|
+
assert_equal "foo bar baz\n", chunk.instance_eval{ @data }
|
51
|
+
assert_equal 'ASCII-8BIT', chunk.instance_eval{ @data }.encoding.to_s
|
52
|
+
|
53
|
+
assert_equal 12, chunk.size # bytesize
|
54
|
+
|
55
|
+
chunk << "日本語Japanese\n".force_encoding('UTF-8')
|
56
|
+
assert_equal "foo bar baz\n日本語Japanese\n".force_encoding('ASCII-8BIT'), chunk.instance_eval{ @data }
|
57
|
+
assert_equal 'ASCII-8BIT', chunk.instance_eval{ @data }.encoding.to_s
|
58
|
+
|
59
|
+
assert_equal 30, chunk.size # bytesize
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_close_and_purge_does_nothing
|
63
|
+
chunk = Fluent::MemoryBufferChunk.new('key', 'data')
|
64
|
+
chunk.close
|
65
|
+
chunk.close
|
66
|
+
chunk.close
|
67
|
+
chunk.close
|
68
|
+
chunk.purge
|
69
|
+
chunk.purge
|
70
|
+
chunk.purge
|
71
|
+
chunk.purge
|
72
|
+
assert_equal 'data', chunk.instance_eval{ @data }
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_read_just_returns_data
|
76
|
+
data = "data1\ndata2\n"
|
77
|
+
chunk = Fluent::MemoryBufferChunk.new('key', data)
|
78
|
+
assert_equal data, chunk.read
|
79
|
+
assert_equal data.object_id, chunk.read.object_id
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_open
|
83
|
+
# StringIO.open(@data, &block)
|
84
|
+
chunk = Fluent::MemoryBufferChunk.new('key', 'foo bar baz')
|
85
|
+
chunk.open do |io|
|
86
|
+
assert 'foo bar baz', io.read
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_write_to
|
91
|
+
chunk = Fluent::MemoryBufferChunk.new('key', 'foo bar baz')
|
92
|
+
dummy_dst = StringIO.new
|
93
|
+
chunk.write_to(dummy_dst)
|
94
|
+
assert_equal 'foo bar baz', dummy_dst.string
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_msgpack_each
|
98
|
+
d0 = MessagePack.pack([[1, "foo"], [2, "bar"], [3, "baz"]])
|
99
|
+
d1 = MessagePack.pack({"key1" => "value1", "key2" => "value2"})
|
100
|
+
d2 = MessagePack.pack("string1")
|
101
|
+
d3 = MessagePack.pack(1)
|
102
|
+
d4 = MessagePack.pack(nil)
|
103
|
+
chunk = Fluent::MemoryBufferChunk.new('key', d0 + d1 + d2 + d3 + d4)
|
104
|
+
|
105
|
+
store = []
|
106
|
+
chunk.msgpack_each do |data|
|
107
|
+
store << data
|
108
|
+
end
|
109
|
+
|
110
|
+
assert_equal 5, store.size
|
111
|
+
assert_equal [[1, "foo"], [2, "bar"], [3, "baz"]], store[0]
|
112
|
+
assert_equal({"key1" => "value1", "key2" => "value2"}, store[1])
|
113
|
+
assert_equal "string1", store[2]
|
114
|
+
assert_equal 1, store[3]
|
115
|
+
assert_equal nil, store[4]
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
class MemoryBufferTest < Test::Unit::TestCase
|
120
|
+
def test_init_configure
|
121
|
+
buf = Fluent::MemoryBuffer.new
|
122
|
+
|
123
|
+
buf.configure({})
|
124
|
+
assert buf.flush_at_shutdown
|
125
|
+
assert_equal 64, buf.buffer_queue_limit
|
126
|
+
end
|
127
|
+
|
128
|
+
class DummyOutput
|
129
|
+
attr_accessor :written
|
130
|
+
|
131
|
+
def write(chunk)
|
132
|
+
@written ||= []
|
133
|
+
@written.push chunk
|
134
|
+
"return value"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_before_shutdown
|
139
|
+
buf = Fluent::MemoryBuffer.new
|
140
|
+
buf.start
|
141
|
+
|
142
|
+
# before_shutdown flushes all chunks in @map and @queue
|
143
|
+
|
144
|
+
c1 = [ buf.new_chunk('k0'), buf.new_chunk('k1'), buf.new_chunk('k2'), buf.new_chunk('k3') ]
|
145
|
+
c2 = [ buf.new_chunk('q0'), buf.new_chunk('q1') ]
|
146
|
+
|
147
|
+
buf.instance_eval do
|
148
|
+
@map = {
|
149
|
+
'k0' => c1[0], 'k1' => c1[1], 'k2' => c1[2], 'k3' => c1[3],
|
150
|
+
'q0' => c2[0], 'q1' => c2[1]
|
151
|
+
}
|
152
|
+
end
|
153
|
+
c1[0] << "data1\ndata2\n"
|
154
|
+
c1[1] << "data1\ndata2\n"
|
155
|
+
c1[2] << "data1\ndata2\n"
|
156
|
+
# k3 chunk is empty!
|
157
|
+
|
158
|
+
c2[0] << "data1\ndata2\n"
|
159
|
+
c2[1] << "data1\ndata2\n"
|
160
|
+
buf.push('q0')
|
161
|
+
buf.push('q1')
|
162
|
+
|
163
|
+
buf.instance_eval do
|
164
|
+
@enqueue_hook_times = 0
|
165
|
+
def enqueue(chunk)
|
166
|
+
@enqueue_hook_times += 1
|
167
|
+
end
|
168
|
+
end
|
169
|
+
assert_equal 0, buf.instance_eval{ @enqueue_hook_times }
|
170
|
+
|
171
|
+
out = DummyOutput.new
|
172
|
+
assert_equal nil, out.written
|
173
|
+
|
174
|
+
buf.before_shutdown(out)
|
175
|
+
|
176
|
+
assert_equal 3, buf.instance_eval{ @enqueue_hook_times } # k0, k1, k2
|
177
|
+
assert_equal 5, out.written.size
|
178
|
+
assert_equal [c2[0], c2[1], c1[0], c1[1], c1[2]], out.written
|
179
|
+
end
|
180
|
+
|
181
|
+
def test_new_chunk
|
182
|
+
buf = Fluent::MemoryBuffer.new
|
183
|
+
chunk = buf.new_chunk('key')
|
184
|
+
assert_equal Fluent::MemoryBufferChunk, chunk.class
|
185
|
+
assert_equal 'key', chunk.key
|
186
|
+
assert chunk.empty?
|
187
|
+
end
|
188
|
+
|
189
|
+
def test_resume
|
190
|
+
buf = Fluent::MemoryBuffer.new
|
191
|
+
resumed_queue, resumed_store = buf.resume
|
192
|
+
assert resumed_queue.empty?
|
193
|
+
assert resumed_store.empty?
|
194
|
+
end
|
195
|
+
|
196
|
+
def test_enqueue_does_nothing # enqueue hook
|
197
|
+
buf = Fluent::MemoryBuffer.new
|
198
|
+
chunk = Fluent::MemoryBufferChunk.new('k', "data1\ndata2\n")
|
199
|
+
assert_equal "data1\ndata2\n", chunk.read
|
200
|
+
buf.enqueue(chunk)
|
201
|
+
assert_equal "data1\ndata2\n", chunk.read
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'fluent/test'
|
3
|
+
require 'fluent/plugin/filter_grep'
|
4
|
+
|
5
|
+
# TODO: Replace with FilterTestDriver
|
6
|
+
class GrepFilterTest < Test::Unit::TestCase
|
7
|
+
setup do
|
8
|
+
@filter = Fluent::GrepFilter.new
|
9
|
+
@time = Fluent::Engine.now
|
10
|
+
end
|
11
|
+
|
12
|
+
def configure(instance, conf, use_v1 = false)
|
13
|
+
config = if conf.is_a?(Fluent::Config::Element)
|
14
|
+
str
|
15
|
+
else
|
16
|
+
Fluent::Config.parse(conf, "(test)", "(test_dir)", use_v1)
|
17
|
+
end
|
18
|
+
instance.configure(config)
|
19
|
+
instance
|
20
|
+
end
|
21
|
+
|
22
|
+
sub_test_case 'configure' do
|
23
|
+
test 'check default' do
|
24
|
+
configure(@filter, '')
|
25
|
+
assert_empty(@filter.regexps)
|
26
|
+
assert_empty(@filter.excludes)
|
27
|
+
end
|
28
|
+
|
29
|
+
test "regexpN can contain a space" do
|
30
|
+
configure(@filter, %[regexp1 message foo])
|
31
|
+
assert_equal(Regexp.compile(/ foo/), @filter.regexps['message'])
|
32
|
+
end
|
33
|
+
|
34
|
+
test "excludeN can contain a space" do
|
35
|
+
configure(@filter, %[exclude1 message foo])
|
36
|
+
assert_equal(Regexp.compile(/ foo/), @filter.excludes['message'])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
sub_test_case 'filter_stream' do
|
41
|
+
def messages
|
42
|
+
[
|
43
|
+
"2013/01/13T07:02:11.124202 INFO GET /ping",
|
44
|
+
"2013/01/13T07:02:13.232645 WARN POST /auth",
|
45
|
+
"2013/01/13T07:02:21.542145 WARN GET /favicon.ico",
|
46
|
+
"2013/01/13T07:02:43.632145 WARN POST /login",
|
47
|
+
]
|
48
|
+
end
|
49
|
+
|
50
|
+
def emit(config, msgs)
|
51
|
+
es = Fluent::MultiEventStream.new
|
52
|
+
msgs.each { |msg|
|
53
|
+
es.add(@time, {'foo' => 'bar', 'message' => msg})
|
54
|
+
}
|
55
|
+
|
56
|
+
configure(@filter, config)
|
57
|
+
@filter.filter_stream('filter.test', es);
|
58
|
+
end
|
59
|
+
|
60
|
+
test 'empty config' do
|
61
|
+
es = emit('', messages)
|
62
|
+
assert_equal(4, es.instance_variable_get(:@record_array).size)
|
63
|
+
end
|
64
|
+
|
65
|
+
test 'regexpN' do
|
66
|
+
es = emit('regexp1 message WARN', messages)
|
67
|
+
assert_equal(3, es.instance_variable_get(:@record_array).size)
|
68
|
+
assert_block('only WARN logs') do
|
69
|
+
es.all? { |t, r|
|
70
|
+
!r['message'].include?('INFO')
|
71
|
+
}
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
test 'excludeN' do
|
76
|
+
es = emit('exclude1 message favicon', messages)
|
77
|
+
assert_equal(3, es.instance_variable_get(:@record_array).size)
|
78
|
+
assert_block('remove favicon logs') do
|
79
|
+
es.all? { |t, r|
|
80
|
+
!r['message'].include?('favicon')
|
81
|
+
}
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
sub_test_case 'with invalid sequence' do
|
86
|
+
def messages
|
87
|
+
[
|
88
|
+
"\xff".force_encoding('UTF-8'),
|
89
|
+
]
|
90
|
+
end
|
91
|
+
|
92
|
+
test "don't raise an exception" do
|
93
|
+
assert_nothing_raised {
|
94
|
+
emit(%[regexp1 message WARN], ["\xff".force_encoding('UTF-8')])
|
95
|
+
}
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
sub_test_case 'grep non-string jsonable values' do
|
101
|
+
def emit(msg, config = 'regexp1 message 0')
|
102
|
+
es = Fluent::MultiEventStream.new
|
103
|
+
es.add(@time, {'foo' => 'bar', 'message' => msg})
|
104
|
+
|
105
|
+
configure(@filter, config)
|
106
|
+
@filter.filter_stream('filter.test', es);
|
107
|
+
end
|
108
|
+
|
109
|
+
data(
|
110
|
+
'array' => ["0"],
|
111
|
+
'hash' => ["0" => "0"],
|
112
|
+
'integer' => 0,
|
113
|
+
'float' => 0.1)
|
114
|
+
test "value" do |data|
|
115
|
+
es = emit(data)
|
116
|
+
assert_equal(1, es.instance_variable_get(:@record_array).size)
|
117
|
+
end
|
118
|
+
|
119
|
+
test "value boolean" do
|
120
|
+
es = emit(true, %[regexp1 message true])
|
121
|
+
assert_equal(1, es.instance_variable_get(:@record_array).size)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,251 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
require 'timecop'
|
3
|
+
require 'fluent/test'
|
4
|
+
require 'fluent/plugin/filter_record_transformer'
|
5
|
+
|
6
|
+
# TODO: Replace with FilterTestDriver
|
7
|
+
class RecordTransformerFilterTest < Test::Unit::TestCase
|
8
|
+
setup do
|
9
|
+
@instance = Fluent::RecordTransformerFilter.new
|
10
|
+
@hostname = Socket.gethostname.chomp
|
11
|
+
@tag = 'test.tag'
|
12
|
+
@tag_parts = @tag.split('.')
|
13
|
+
@time = Time.utc(1,2,3,4,5,2010,nil,nil,nil,nil)
|
14
|
+
Timecop.freeze(@time)
|
15
|
+
end
|
16
|
+
|
17
|
+
teardown do
|
18
|
+
Timecop.return
|
19
|
+
end
|
20
|
+
|
21
|
+
def configure(instance, conf, use_v1 = false)
|
22
|
+
config = if conf.is_a?(Fluent::Config::Element)
|
23
|
+
str
|
24
|
+
else
|
25
|
+
Fluent::Config.parse(conf, "(test)", "(test_dir)", use_v1)
|
26
|
+
end
|
27
|
+
instance.configure(config)
|
28
|
+
instance
|
29
|
+
end
|
30
|
+
|
31
|
+
sub_test_case 'configure' do
|
32
|
+
test 'check default' do
|
33
|
+
assert_nothing_raised do
|
34
|
+
configure(@instance, '')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
test "keep_keys must be specified together with renew_record true" do
|
39
|
+
assert_raise(Fluent::ConfigError) do
|
40
|
+
configure(@instance, %[keep_keys a])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
sub_test_case "test options" do
|
46
|
+
def emit(config, msgs = [''])
|
47
|
+
es = Fluent::MultiEventStream.new
|
48
|
+
msgs.each do |msg|
|
49
|
+
es.add(@time, {'foo' => 'bar', 'message' => msg})
|
50
|
+
end
|
51
|
+
|
52
|
+
configure(@instance, config)
|
53
|
+
@instance.filter_stream(@tag, es)
|
54
|
+
end
|
55
|
+
|
56
|
+
CONFIG = %[
|
57
|
+
<record>
|
58
|
+
hostname ${hostname}
|
59
|
+
tag ${tag}
|
60
|
+
time ${time}
|
61
|
+
message ${hostname} ${tag_parts[-1]} ${message}
|
62
|
+
</record>
|
63
|
+
]
|
64
|
+
|
65
|
+
test 'typical usage' do
|
66
|
+
msgs = ['1', '2']
|
67
|
+
es = emit(CONFIG, msgs)
|
68
|
+
es.each_with_index do |(t, r), i|
|
69
|
+
assert_equal('bar', r['foo'])
|
70
|
+
assert_equal(@hostname, r['hostname'])
|
71
|
+
assert_equal(@tag, r['tag'])
|
72
|
+
assert_equal(@time.to_s, r['time'])
|
73
|
+
assert_equal("#{@hostname} #{@tag_parts[-1]} #{msgs[i]}", r['message'])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
test 'remove_keys' do
|
78
|
+
config = CONFIG + %[remove_keys foo,message]
|
79
|
+
es = emit(config)
|
80
|
+
es.each_with_index do |(t, r), i|
|
81
|
+
assert_not_include(r, 'foo')
|
82
|
+
assert_equal(@hostname, r['hostname'])
|
83
|
+
assert_equal(@tag, r['tag'])
|
84
|
+
assert_equal(@time.to_s, r['time'])
|
85
|
+
assert_not_include(r, 'message')
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
test 'renew_record' do
|
90
|
+
config = CONFIG + %[renew_record true]
|
91
|
+
msgs = ['1', '2']
|
92
|
+
es = emit(config, msgs)
|
93
|
+
es.each_with_index do |(t, r), i|
|
94
|
+
assert_not_include(r, 'foo')
|
95
|
+
assert_equal(@hostname, r['hostname'])
|
96
|
+
assert_equal(@tag, r['tag'])
|
97
|
+
assert_equal(@time.to_s, r['time'])
|
98
|
+
assert_equal("#{@hostname} #{@tag_parts[-1]} #{msgs[i]}", r['message'])
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
test 'keep_keys' do
|
103
|
+
config = %[renew_record true\nkeep_keys foo,message]
|
104
|
+
msgs = ['1', '2']
|
105
|
+
es = emit(config, msgs)
|
106
|
+
es.each_with_index do |(t, r), i|
|
107
|
+
assert_equal('bar', r['foo'])
|
108
|
+
assert_equal(msgs[i], r['message'])
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
test 'enable_ruby' do
|
113
|
+
config = %[
|
114
|
+
enable_ruby yes
|
115
|
+
<record>
|
116
|
+
message ${hostname} ${tag_parts.last} ${URI.encode(message)}
|
117
|
+
</record>
|
118
|
+
]
|
119
|
+
msgs = ['1', '2']
|
120
|
+
es = emit(config, msgs)
|
121
|
+
es.each_with_index do |(t, r), i|
|
122
|
+
assert_equal("#{@hostname} #{@tag_parts[-1]} #{msgs[i]}", r['message'])
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
sub_test_case 'test placeholders' do
|
128
|
+
def emit(config, msgs = [''])
|
129
|
+
es = Fluent::MultiEventStream.new
|
130
|
+
msgs.each do |msg|
|
131
|
+
es.add(@time, {'eventType0' => 'bar', 'message' => msg})
|
132
|
+
end
|
133
|
+
|
134
|
+
configure(@instance, config)
|
135
|
+
@instance.filter_stream(@tag, es)
|
136
|
+
end
|
137
|
+
|
138
|
+
%w[yes no].each do |enable_ruby|
|
139
|
+
test "hostname with enble_ruby #{enable_ruby}" do
|
140
|
+
config = %[
|
141
|
+
enable_ruby #{enable_ruby}
|
142
|
+
<record>
|
143
|
+
message ${hostname}
|
144
|
+
</record>
|
145
|
+
]
|
146
|
+
es = emit(config)
|
147
|
+
es.each do |t, r|
|
148
|
+
assert_equal(@hostname, r['message'])
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
test "tag with enable_ruby #{enable_ruby}" do
|
153
|
+
config = %[
|
154
|
+
enable_ruby #{enable_ruby}
|
155
|
+
<record>
|
156
|
+
message ${tag}
|
157
|
+
</record>
|
158
|
+
]
|
159
|
+
es = emit(config)
|
160
|
+
es.each do |t, r|
|
161
|
+
assert_equal(@tag, r['message'])
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
test "tag_parts with enable_ruby #{enable_ruby}" do
|
166
|
+
config = %[
|
167
|
+
enable_ruby #{enable_ruby}
|
168
|
+
<record>
|
169
|
+
message ${tag_parts[0]} ${tag_parts[-1]}
|
170
|
+
</record>
|
171
|
+
]
|
172
|
+
expected = "#{@tag.split('.').first} #{@tag.split('.').last}"
|
173
|
+
es = emit(config)
|
174
|
+
es.each do |t, r|
|
175
|
+
assert_equal(expected, r['message'])
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
test "${tag_prefix[N]} and ${tag_suffix[N]} with enable_ruby #{enable_ruby}" do
|
180
|
+
config = %[
|
181
|
+
enable_ruby #{enable_ruby}
|
182
|
+
<record>
|
183
|
+
message ${tag_prefix[1]} ${tag_prefix[-2]} ${tag_suffix[2]} ${tag_suffix[-3]}
|
184
|
+
</record>
|
185
|
+
]
|
186
|
+
@tag = 'prefix.test.tag.suffix'
|
187
|
+
expected = "prefix.test prefix.test.tag tag.suffix test.tag.suffix"
|
188
|
+
es = emit(config)
|
189
|
+
es.each do |t, r|
|
190
|
+
assert_equal(expected, r['message'])
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
test "time with enable_ruby #{enable_ruby}" do
|
195
|
+
config = %[
|
196
|
+
enable_ruby #{enable_ruby}
|
197
|
+
<record>
|
198
|
+
message ${time}
|
199
|
+
</record>
|
200
|
+
]
|
201
|
+
es = emit(config)
|
202
|
+
es.each do |t, r|
|
203
|
+
assert_equal(@time.to_s, r['message'])
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
test "record keys with enable_ruby #{enable_ruby}" do
|
208
|
+
config = %[
|
209
|
+
enable_ruby #{enable_ruby}
|
210
|
+
remove_keys eventType0
|
211
|
+
<record>
|
212
|
+
message bar ${message}
|
213
|
+
eventtype ${eventType0}
|
214
|
+
</record>
|
215
|
+
]
|
216
|
+
msgs = ['1', '2']
|
217
|
+
es = emit(config, msgs)
|
218
|
+
es.each_with_index do |(t, r), i|
|
219
|
+
assert_not_include(r, 'eventType0')
|
220
|
+
assert_equal("bar", r['eventtype'])
|
221
|
+
assert_equal("bar #{msgs[i]}", r['message'])
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
test 'unknown placeholder (enable_ruby no)' do
|
227
|
+
config = %[
|
228
|
+
enable_ruby no
|
229
|
+
<record>
|
230
|
+
message ${unknown}
|
231
|
+
</record>
|
232
|
+
]
|
233
|
+
mock(@instance.log).warn("unknown placeholder `${unknown}` found")
|
234
|
+
emit(config)
|
235
|
+
end
|
236
|
+
|
237
|
+
test 'failed to expand (enable_ruby yes)' do
|
238
|
+
config = %[
|
239
|
+
enable_ruby yes
|
240
|
+
<record>
|
241
|
+
message ${unknown['bar']}
|
242
|
+
</record>
|
243
|
+
]
|
244
|
+
mock(@instance.log).warn("failed to expand `${unknown['bar']}`", anything)
|
245
|
+
es = emit(config)
|
246
|
+
es.each do |t, r|
|
247
|
+
assert_nil(r['message'])
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|