fluentd 1.13.3 → 1.16.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/{bug_report.yaml → bug_report.yml} +2 -0
- data/.github/ISSUE_TEMPLATE/config.yml +2 -2
- data/.github/ISSUE_TEMPLATE/{feature_request.yaml → feature_request.yml} +1 -0
- data/.github/workflows/stale-actions.yml +11 -9
- data/.github/workflows/test.yml +32 -0
- data/CHANGELOG.md +490 -10
- data/CONTRIBUTING.md +2 -2
- data/MAINTAINERS.md +7 -5
- data/README.md +3 -23
- data/Rakefile +1 -1
- data/SECURITY.md +14 -0
- data/fluentd.gemspec +7 -8
- data/lib/fluent/command/cat.rb +13 -3
- data/lib/fluent/command/ctl.rb +6 -3
- data/lib/fluent/command/fluentd.rb +73 -65
- data/lib/fluent/command/plugin_config_formatter.rb +1 -1
- data/lib/fluent/compat/output.rb +9 -6
- data/lib/fluent/config/dsl.rb +1 -1
- data/lib/fluent/config/error.rb +12 -0
- data/lib/fluent/config/literal_parser.rb +2 -2
- data/lib/fluent/config/parser.rb +1 -1
- data/lib/fluent/config/v1_parser.rb +3 -3
- data/lib/fluent/config/yaml_parser/fluent_value.rb +47 -0
- data/lib/fluent/config/yaml_parser/loader.rb +108 -0
- data/lib/fluent/config/yaml_parser/parser.rb +166 -0
- data/lib/fluent/config/yaml_parser/section_builder.rb +107 -0
- data/lib/fluent/config/yaml_parser.rb +56 -0
- data/lib/fluent/config.rb +14 -1
- data/lib/fluent/counter/server.rb +1 -1
- data/lib/fluent/counter/validator.rb +3 -3
- data/lib/fluent/daemon.rb +2 -4
- data/lib/fluent/engine.rb +1 -1
- data/lib/fluent/env.rb +4 -0
- data/lib/fluent/error.rb +3 -0
- data/lib/fluent/event.rb +8 -4
- data/lib/fluent/event_router.rb +47 -2
- data/lib/fluent/file_wrapper.rb +137 -0
- data/lib/fluent/log/console_adapter.rb +66 -0
- data/lib/fluent/log.rb +44 -5
- data/lib/fluent/match.rb +1 -1
- data/lib/fluent/msgpack_factory.rb +6 -1
- data/lib/fluent/oj_options.rb +1 -2
- data/lib/fluent/plugin/bare_output.rb +49 -8
- data/lib/fluent/plugin/base.rb +26 -9
- data/lib/fluent/plugin/buf_file.rb +34 -5
- data/lib/fluent/plugin/buf_file_single.rb +32 -3
- data/lib/fluent/plugin/buffer/file_chunk.rb +1 -1
- data/lib/fluent/plugin/buffer.rb +216 -70
- data/lib/fluent/plugin/filter.rb +35 -1
- data/lib/fluent/plugin/filter_record_transformer.rb +1 -1
- data/lib/fluent/plugin/in_forward.rb +2 -2
- data/lib/fluent/plugin/in_http.rb +39 -10
- data/lib/fluent/plugin/in_monitor_agent.rb +4 -2
- data/lib/fluent/plugin/in_sample.rb +1 -1
- data/lib/fluent/plugin/in_syslog.rb +13 -1
- data/lib/fluent/plugin/in_tail/group_watch.rb +204 -0
- data/lib/fluent/plugin/in_tail/position_file.rb +33 -33
- data/lib/fluent/plugin/in_tail.rb +216 -84
- data/lib/fluent/plugin/in_tcp.rb +47 -2
- data/lib/fluent/plugin/input.rb +39 -1
- data/lib/fluent/plugin/metrics.rb +119 -0
- data/lib/fluent/plugin/metrics_local.rb +96 -0
- data/lib/fluent/plugin/multi_output.rb +43 -6
- data/lib/fluent/plugin/out_copy.rb +1 -1
- data/lib/fluent/plugin/out_exec_filter.rb +2 -2
- data/lib/fluent/plugin/out_file.rb +20 -2
- data/lib/fluent/plugin/out_forward/ack_handler.rb +19 -4
- data/lib/fluent/plugin/out_forward/socket_cache.rb +2 -0
- data/lib/fluent/plugin/out_forward.rb +17 -9
- data/lib/fluent/plugin/out_secondary_file.rb +39 -22
- data/lib/fluent/plugin/output.rb +167 -78
- data/lib/fluent/plugin/parser.rb +3 -4
- data/lib/fluent/plugin/parser_apache2.rb +1 -1
- data/lib/fluent/plugin/parser_json.rb +1 -1
- data/lib/fluent/plugin/parser_syslog.rb +1 -1
- data/lib/fluent/plugin/storage_local.rb +3 -5
- data/lib/fluent/plugin.rb +10 -1
- data/lib/fluent/plugin_helper/child_process.rb +3 -0
- data/lib/fluent/plugin_helper/event_emitter.rb +8 -1
- data/lib/fluent/plugin_helper/event_loop.rb +2 -2
- data/lib/fluent/plugin_helper/http_server/server.rb +2 -1
- data/lib/fluent/plugin_helper/metrics.rb +129 -0
- data/lib/fluent/plugin_helper/record_accessor.rb +1 -1
- data/lib/fluent/plugin_helper/retry_state.rb +14 -4
- data/lib/fluent/plugin_helper/server.rb +35 -6
- data/lib/fluent/plugin_helper/service_discovery.rb +2 -2
- data/lib/fluent/plugin_helper/socket.rb +13 -2
- data/lib/fluent/plugin_helper/thread.rb +3 -3
- data/lib/fluent/plugin_helper.rb +1 -0
- data/lib/fluent/plugin_id.rb +3 -2
- data/lib/fluent/registry.rb +2 -1
- data/lib/fluent/root_agent.rb +6 -0
- data/lib/fluent/rpc.rb +4 -3
- data/lib/fluent/supervisor.rb +283 -259
- data/lib/fluent/system_config.rb +13 -3
- data/lib/fluent/test/driver/base.rb +11 -5
- data/lib/fluent/test/driver/filter.rb +4 -0
- data/lib/fluent/test/startup_shutdown.rb +6 -8
- data/lib/fluent/time.rb +21 -20
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/win32api.rb +38 -0
- data/lib/fluent/winsvc.rb +5 -8
- data/templates/new_gem/test/helper.rb.erb +0 -1
- data/test/command/test_cat.rb +31 -2
- data/test/command/test_ctl.rb +1 -2
- data/test/command/test_fluentd.rb +209 -24
- data/test/command/test_plugin_config_formatter.rb +0 -1
- data/test/compat/test_parser.rb +6 -6
- data/test/config/test_system_config.rb +13 -11
- data/test/config/test_types.rb +1 -1
- data/test/log/test_console_adapter.rb +110 -0
- data/test/plugin/in_tail/test_io_handler.rb +26 -8
- data/test/plugin/in_tail/test_position_file.rb +48 -59
- data/test/plugin/out_forward/test_ack_handler.rb +39 -0
- data/test/plugin/out_forward/test_socket_cache.rb +26 -1
- data/test/plugin/test_bare_output.rb +14 -1
- data/test/plugin/test_base.rb +133 -1
- data/test/plugin/test_buf_file.rb +62 -23
- data/test/plugin/test_buf_file_single.rb +65 -0
- data/test/plugin/test_buffer.rb +267 -3
- data/test/plugin/test_buffer_chunk.rb +11 -0
- data/test/plugin/test_filter.rb +12 -1
- data/test/plugin/test_filter_parser.rb +1 -1
- data/test/plugin/test_filter_stdout.rb +2 -2
- data/test/plugin/test_in_forward.rb +9 -11
- data/test/plugin/test_in_http.rb +65 -3
- data/test/plugin/test_in_monitor_agent.rb +216 -11
- data/test/plugin/test_in_object_space.rb +9 -3
- data/test/plugin/test_in_syslog.rb +35 -0
- data/test/plugin/test_in_tail.rb +1393 -385
- data/test/plugin/test_in_tcp.rb +87 -2
- data/test/plugin/test_in_udp.rb +28 -0
- data/test/plugin/test_in_unix.rb +2 -2
- data/test/plugin/test_input.rb +12 -1
- data/test/plugin/test_metrics.rb +294 -0
- data/test/plugin/test_metrics_local.rb +96 -0
- data/test/plugin/test_multi_output.rb +25 -1
- data/test/plugin/test_out_exec.rb +6 -4
- data/test/plugin/test_out_exec_filter.rb +6 -2
- data/test/plugin/test_out_file.rb +34 -17
- data/test/plugin/test_out_forward.rb +78 -77
- data/test/plugin/test_out_http.rb +1 -0
- data/test/plugin/test_out_stdout.rb +2 -2
- data/test/plugin/test_output.rb +297 -12
- data/test/plugin/test_output_as_buffered.rb +44 -44
- data/test/plugin/test_output_as_buffered_compress.rb +32 -18
- data/test/plugin/test_output_as_buffered_retries.rb +54 -7
- data/test/plugin/test_output_as_buffered_secondary.rb +4 -4
- data/test/plugin/test_parser_regexp.rb +1 -6
- data/test/plugin/test_parser_syslog.rb +1 -1
- data/test/plugin_helper/test_cert_option.rb +1 -1
- data/test/plugin_helper/test_child_process.rb +38 -16
- data/test/plugin_helper/test_event_emitter.rb +29 -0
- data/test/plugin_helper/test_http_server_helper.rb +1 -1
- data/test/plugin_helper/test_metrics.rb +137 -0
- data/test/plugin_helper/test_retry_state.rb +602 -38
- data/test/plugin_helper/test_server.rb +78 -6
- data/test/plugin_helper/test_timer.rb +2 -2
- data/test/test_config.rb +191 -24
- data/test/test_event_router.rb +17 -0
- data/test/test_file_wrapper.rb +53 -0
- data/test/test_formatter.rb +24 -21
- data/test/test_log.rb +122 -40
- data/test/test_msgpack_factory.rb +32 -0
- data/test/test_plugin_classes.rb +102 -0
- data/test/test_root_agent.rb +30 -1
- data/test/test_supervisor.rb +477 -257
- data/test/test_time_parser.rb +22 -0
- metadata +55 -34
- data/.drone.yml +0 -35
- data/.github/workflows/issue-auto-closer.yml +0 -12
- data/.github/workflows/linux-test.yaml +0 -36
- data/.github/workflows/macos-test.yaml +0 -30
- data/.github/workflows/windows-test.yaml +0 -46
- data/.gitlab-ci.yml +0 -103
- data/lib/fluent/plugin/file_wrapper.rb +0 -187
- data/test/plugin/test_file_wrapper.rb +0 -126
- data/test/test_logger_initializer.rb +0 -46
|
@@ -16,14 +16,20 @@ class ServerPluginHelperTest < Test::Unit::TestCase
|
|
|
16
16
|
|
|
17
17
|
setup do
|
|
18
18
|
@port = unused_port
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
if Fluent.windows?
|
|
20
|
+
@socket_manager_server = ServerEngine::SocketManager::Server.open
|
|
21
|
+
@socket_manager_path = @socket_manager_server.path
|
|
22
|
+
else
|
|
23
|
+
@socket_manager_path = ServerEngine::SocketManager::Server.generate_path
|
|
24
|
+
if @socket_manager_path.is_a?(String) && File.exist?(@socket_manager_path)
|
|
25
|
+
FileUtils.rm_f @socket_manager_path
|
|
26
|
+
end
|
|
27
|
+
@socket_manager_server = ServerEngine::SocketManager::Server.open(@socket_manager_path)
|
|
22
28
|
end
|
|
23
|
-
@socket_manager_server = ServerEngine::SocketManager::Server.open(@socket_manager_path)
|
|
24
29
|
ENV['SERVERENGINE_SOCKETMANAGER_PATH'] = @socket_manager_path.to_s
|
|
25
30
|
|
|
26
31
|
@d = Dummy.new
|
|
32
|
+
@d.under_plugin_development = true
|
|
27
33
|
@d.start
|
|
28
34
|
@d.after_start
|
|
29
35
|
end
|
|
@@ -37,7 +43,7 @@ class ServerPluginHelperTest < Test::Unit::TestCase
|
|
|
37
43
|
(@d.terminated? || @d.terminate) rescue nil
|
|
38
44
|
|
|
39
45
|
@socket_manager_server.close
|
|
40
|
-
if @
|
|
46
|
+
if @socket_manager_path.is_a?(String) && File.exist?(@socket_manager_path)
|
|
41
47
|
FileUtils.rm_f @socket_manager_path
|
|
42
48
|
end
|
|
43
49
|
end
|
|
@@ -64,6 +70,24 @@ class ServerPluginHelperTest < Test::Unit::TestCase
|
|
|
64
70
|
end
|
|
65
71
|
assert d.plugin_id
|
|
66
72
|
assert d.log
|
|
73
|
+
assert_equal 0, d.transport_config.linger_timeout
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
test 'can change linger_timeout option' do
|
|
77
|
+
d = Dummy.new
|
|
78
|
+
|
|
79
|
+
transport_opts = {
|
|
80
|
+
'linger_timeout' => 1,
|
|
81
|
+
}
|
|
82
|
+
transport_conf = config_element('transport', 'tcp', transport_opts)
|
|
83
|
+
conf = config_element('source', 'tag.*', {}, [transport_conf])
|
|
84
|
+
|
|
85
|
+
assert_nothing_raised do
|
|
86
|
+
d.configure(conf)
|
|
87
|
+
end
|
|
88
|
+
assert d.plugin_id
|
|
89
|
+
assert d.log
|
|
90
|
+
assert_equal 1, d.transport_config.linger_timeout
|
|
67
91
|
end
|
|
68
92
|
end
|
|
69
93
|
|
|
@@ -771,6 +795,50 @@ class ServerPluginHelperTest < Test::Unit::TestCase
|
|
|
771
795
|
end
|
|
772
796
|
end
|
|
773
797
|
end
|
|
798
|
+
|
|
799
|
+
sub_test_case 'over max_bytes' do
|
|
800
|
+
data("cut off on Non-Windows", { max_bytes: 32, records: ["a" * 40], expected: ["a" * 32] }, keep: true) unless Fluent.windows?
|
|
801
|
+
data("drop on Windows", { max_bytes: 32, records: ["a" * 40], expected: [] }, keep: true) if Fluent.windows?
|
|
802
|
+
test 'with sock' do |data|
|
|
803
|
+
max_bytes, records, expected = data.values
|
|
804
|
+
|
|
805
|
+
actual_records = []
|
|
806
|
+
@d.server_create_udp(:myserver, @port, max_bytes: max_bytes) do |data, sock|
|
|
807
|
+
actual_records << data
|
|
808
|
+
end
|
|
809
|
+
|
|
810
|
+
open_client(:udp, "127.0.0.1", @port) do |sock|
|
|
811
|
+
records.each do |record|
|
|
812
|
+
sock.send(record, 0)
|
|
813
|
+
end
|
|
814
|
+
end
|
|
815
|
+
|
|
816
|
+
waiting(10) { sleep 0.1 until actual_records.size >= expected.size }
|
|
817
|
+
sleep 1 if expected.size == 0 # To confirm no record recieved.
|
|
818
|
+
|
|
819
|
+
assert_equal expected, actual_records
|
|
820
|
+
end
|
|
821
|
+
|
|
822
|
+
test 'without sock' do |data|
|
|
823
|
+
max_bytes, records, expected = data.values
|
|
824
|
+
|
|
825
|
+
actual_records = []
|
|
826
|
+
@d.server_create_udp(:myserver, @port, max_bytes: max_bytes) do |data|
|
|
827
|
+
actual_records << data
|
|
828
|
+
end
|
|
829
|
+
|
|
830
|
+
open_client(:udp, "127.0.0.1", @port) do |sock|
|
|
831
|
+
records.each do |record|
|
|
832
|
+
sock.send(record, 0)
|
|
833
|
+
end
|
|
834
|
+
end
|
|
835
|
+
|
|
836
|
+
waiting(10) { sleep 0.1 until actual_records.size >= expected.size }
|
|
837
|
+
sleep 1 if expected.size == 0 # To confirm no record recieved.
|
|
838
|
+
|
|
839
|
+
assert_equal expected, actual_records
|
|
840
|
+
end
|
|
841
|
+
end
|
|
774
842
|
end
|
|
775
843
|
|
|
776
844
|
module CertUtil
|
|
@@ -1261,7 +1329,7 @@ class ServerPluginHelperTest < Test::Unit::TestCase
|
|
|
1261
1329
|
# OpenSSL 1.1.1: "TLSv1.2"
|
|
1262
1330
|
if tls_version == "TLSv1/SSLv3" || tls_version == "TLSv1.2"
|
|
1263
1331
|
matched = true
|
|
1264
|
-
unless cipher_name.match(/#{conf.ciphers}/)
|
|
1332
|
+
unless cipher_name.match?(/#{conf.ciphers}/)
|
|
1265
1333
|
matched = false
|
|
1266
1334
|
break
|
|
1267
1335
|
end
|
|
@@ -1552,6 +1620,10 @@ class ServerPluginHelperTest < Test::Unit::TestCase
|
|
|
1552
1620
|
|
|
1553
1621
|
def open_client(proto, addr, port)
|
|
1554
1622
|
client = case proto
|
|
1623
|
+
when :udp
|
|
1624
|
+
c = UDPSocket.open
|
|
1625
|
+
c.connect(addr, port)
|
|
1626
|
+
c
|
|
1555
1627
|
when :tcp
|
|
1556
1628
|
TCPSocket.open(addr, port)
|
|
1557
1629
|
when :tls
|
|
@@ -90,8 +90,8 @@ class TimerTest < Test::Unit::TestCase
|
|
|
90
90
|
assert{ counter1 >= 4 && counter1 <= 5 }
|
|
91
91
|
assert{ counter2 == 2 }
|
|
92
92
|
msg = "Unexpected error raised. Stopping the timer. title=:t2"
|
|
93
|
-
assert
|
|
94
|
-
assert
|
|
93
|
+
assert(d1.log.out.logs.any?{|line| line.include?("[error]:") && line.include?(msg) && line.include?("abort!!!!!!") })
|
|
94
|
+
assert(d1.log.out.logs.any?{|line| line.include?("[error]:") && line.include?("Timer detached. title=:t2") })
|
|
95
95
|
|
|
96
96
|
d1.shutdown; d1.close; d1.terminate
|
|
97
97
|
end
|
data/test/test_config.rb
CHANGED
|
@@ -10,11 +10,18 @@ class ConfigTest < Test::Unit::TestCase
|
|
|
10
10
|
|
|
11
11
|
TMP_DIR = File.dirname(__FILE__) + "/tmp/config#{ENV['TEST_ENV_NUMBER']}"
|
|
12
12
|
|
|
13
|
-
def read_config(path)
|
|
13
|
+
def read_config(path, use_yaml: false)
|
|
14
14
|
path = File.expand_path(path)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
if use_yaml
|
|
16
|
+
context = Kernel.binding
|
|
17
|
+
|
|
18
|
+
s = Fluent::Config::YamlParser::Loader.new(context).load(Pathname.new(path))
|
|
19
|
+
Fluent::Config::YamlParser::Parser.new(s).build.to_element
|
|
20
|
+
else
|
|
21
|
+
File.open(path) { |io|
|
|
22
|
+
Fluent::Config::Parser.parse(io, File.basename(path), File.dirname(path))
|
|
23
|
+
}
|
|
24
|
+
end
|
|
18
25
|
end
|
|
19
26
|
|
|
20
27
|
def prepare_config
|
|
@@ -151,30 +158,190 @@ class ConfigTest < Test::Unit::TestCase
|
|
|
151
158
|
assert_equal before_size, match_conf.unused.size
|
|
152
159
|
end
|
|
153
160
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
161
|
+
sub_test_case "yaml config" do
|
|
162
|
+
def test_included
|
|
163
|
+
write_config "#{TMP_DIR}/config_test_not_fetched.yaml", <<-EOS
|
|
164
|
+
config:
|
|
165
|
+
- source:
|
|
166
|
+
$type: dummy
|
|
167
|
+
tag: tag.dummy
|
|
168
|
+
- source:
|
|
169
|
+
$type: tcp
|
|
170
|
+
tag: tag.tcp
|
|
171
|
+
parse:
|
|
172
|
+
$arg:
|
|
173
|
+
- why.parse.section.doesnot.have.arg
|
|
174
|
+
- huh
|
|
175
|
+
$type: none
|
|
176
|
+
- match:
|
|
177
|
+
$tag: tag.*
|
|
178
|
+
$type: stdout
|
|
179
|
+
buffer:
|
|
180
|
+
$type: memory
|
|
181
|
+
flush_interval: 1s
|
|
182
|
+
- !include fluent-included.yaml
|
|
183
|
+
EOS
|
|
184
|
+
write_config "#{TMP_DIR}/fluent-included.yaml", <<-EOS
|
|
185
|
+
- label:
|
|
186
|
+
$name: '@FLUENT_LOG'
|
|
187
|
+
config:
|
|
188
|
+
- match:
|
|
189
|
+
$type: "null"
|
|
190
|
+
$tag: "**"
|
|
191
|
+
buffer:
|
|
192
|
+
$type: memory
|
|
193
|
+
flush_mode: interval
|
|
194
|
+
flush_interval: 1s
|
|
195
|
+
EOS
|
|
196
|
+
root_conf = read_config("#{TMP_DIR}/config_test_not_fetched.yaml", use_yaml: true)
|
|
197
|
+
dummy_source_conf = root_conf.elements.first
|
|
198
|
+
tcp_source_conf = root_conf.elements[1]
|
|
199
|
+
parse_tcp_conf = tcp_source_conf.elements.first
|
|
200
|
+
match_conf = root_conf.elements[2]
|
|
201
|
+
label_conf = root_conf.elements[3]
|
|
202
|
+
fluent_log_conf = label_conf.elements.first
|
|
203
|
+
fluent_log_buffer_conf = fluent_log_conf.elements.first
|
|
158
204
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
205
|
+
assert_equal(
|
|
206
|
+
[
|
|
207
|
+
'dummy',
|
|
208
|
+
'tag.dummy',
|
|
209
|
+
'tcp',
|
|
210
|
+
'tag.tcp',
|
|
211
|
+
'none',
|
|
212
|
+
'why.parse.section.doesnot.have.arg,huh',
|
|
213
|
+
'stdout',
|
|
214
|
+
'tag.*',
|
|
215
|
+
'null',
|
|
216
|
+
'**',
|
|
217
|
+
'@FLUENT_LOG',
|
|
218
|
+
'memory',
|
|
219
|
+
'interval',
|
|
220
|
+
'1s',
|
|
221
|
+
],
|
|
222
|
+
[
|
|
223
|
+
dummy_source_conf['@type'],
|
|
224
|
+
dummy_source_conf['tag'],
|
|
225
|
+
tcp_source_conf['@type'],
|
|
226
|
+
tcp_source_conf['tag'],
|
|
227
|
+
parse_tcp_conf['@type'],
|
|
228
|
+
parse_tcp_conf.arg,
|
|
229
|
+
match_conf['@type'],
|
|
230
|
+
match_conf.arg,
|
|
231
|
+
fluent_log_conf['@type'],
|
|
232
|
+
fluent_log_conf.arg,
|
|
233
|
+
label_conf.arg,
|
|
234
|
+
fluent_log_buffer_conf['@type'],
|
|
235
|
+
fluent_log_buffer_conf['flush_mode'],
|
|
236
|
+
fluent_log_buffer_conf['flush_interval'],
|
|
237
|
+
])
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def test_included_glob
|
|
241
|
+
write_config "#{TMP_DIR}/config.yaml", <<-EOS
|
|
242
|
+
config:
|
|
243
|
+
- !include "include/*.yaml"
|
|
244
|
+
EOS
|
|
245
|
+
write_config "#{TMP_DIR}/include/02_source2.yaml", <<-EOS
|
|
246
|
+
- source:
|
|
247
|
+
$type: dummy
|
|
248
|
+
tag: tag.dummy
|
|
249
|
+
EOS
|
|
250
|
+
write_config "#{TMP_DIR}/include/01_source1.yaml", <<-EOS
|
|
251
|
+
- source:
|
|
252
|
+
$type: tcp
|
|
253
|
+
tag: tag.tcp
|
|
254
|
+
parse:
|
|
255
|
+
$arg:
|
|
256
|
+
- why.parse.section.doesnot.have.arg
|
|
257
|
+
- huh
|
|
258
|
+
$type: none
|
|
259
|
+
EOS
|
|
260
|
+
write_config "#{TMP_DIR}/include/03_match1.yaml", <<-EOS
|
|
261
|
+
- match:
|
|
262
|
+
$tag: tag.*
|
|
263
|
+
$type: stdout
|
|
264
|
+
buffer:
|
|
265
|
+
$type: memory
|
|
266
|
+
flush_interval: 1s
|
|
267
|
+
EOS
|
|
268
|
+
root_conf = read_config("#{TMP_DIR}/config.yaml", use_yaml: true)
|
|
269
|
+
tcp_source_conf = root_conf.elements.first
|
|
270
|
+
dummy_source_conf = root_conf.elements[1]
|
|
271
|
+
parse_tcp_conf = tcp_source_conf.elements.first
|
|
272
|
+
match_conf = root_conf.elements[2]
|
|
273
|
+
|
|
274
|
+
assert_equal(
|
|
275
|
+
[
|
|
276
|
+
'tcp',
|
|
277
|
+
'tag.tcp',
|
|
278
|
+
'none',
|
|
279
|
+
'why.parse.section.doesnot.have.arg,huh',
|
|
280
|
+
'dummy',
|
|
281
|
+
'tag.dummy',
|
|
282
|
+
'stdout',
|
|
283
|
+
'tag.*',
|
|
284
|
+
],
|
|
285
|
+
[
|
|
286
|
+
tcp_source_conf['@type'],
|
|
287
|
+
tcp_source_conf['tag'],
|
|
288
|
+
parse_tcp_conf['@type'],
|
|
289
|
+
parse_tcp_conf.arg,
|
|
290
|
+
dummy_source_conf['@type'],
|
|
291
|
+
dummy_source_conf['tag'],
|
|
292
|
+
match_conf['@type'],
|
|
293
|
+
match_conf.arg,
|
|
294
|
+
])
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
def test_check_not_fetchd
|
|
298
|
+
write_config "#{TMP_DIR}/config_test_not_fetched.yaml", <<-EOS
|
|
299
|
+
config:
|
|
300
|
+
- match:
|
|
301
|
+
$arg: dummy
|
|
302
|
+
$type: rewrite
|
|
303
|
+
add_prefix: filtered
|
|
304
|
+
rule:
|
|
305
|
+
key: path
|
|
306
|
+
pattern: "^[A-Z]+"
|
|
307
|
+
replace: true
|
|
308
|
+
EOS
|
|
309
|
+
root_conf = read_config("#{TMP_DIR}/config_test_not_fetched.yaml", use_yaml: true)
|
|
310
|
+
match_conf = root_conf.elements.first
|
|
311
|
+
rule_conf = match_conf.elements.first
|
|
312
|
+
|
|
313
|
+
not_fetched = []; root_conf.check_not_fetched {|key, e| not_fetched << key }
|
|
314
|
+
assert_equal %w[@type $arg add_prefix key pattern replace], not_fetched
|
|
315
|
+
|
|
316
|
+
not_fetched = []; match_conf.check_not_fetched {|key, e| not_fetched << key }
|
|
317
|
+
assert_equal %w[@type $arg add_prefix key pattern replace], not_fetched
|
|
318
|
+
|
|
319
|
+
not_fetched = []; rule_conf.check_not_fetched {|key, e| not_fetched << key }
|
|
320
|
+
assert_equal %w[key pattern replace], not_fetched
|
|
321
|
+
|
|
322
|
+
# accessing should delete
|
|
323
|
+
match_conf['type']
|
|
324
|
+
rule_conf['key']
|
|
325
|
+
|
|
326
|
+
not_fetched = []; root_conf.check_not_fetched {|key, e| not_fetched << key }
|
|
327
|
+
assert_equal %w[@type $arg add_prefix pattern replace], not_fetched
|
|
328
|
+
|
|
329
|
+
not_fetched = []; match_conf.check_not_fetched {|key, e| not_fetched << key }
|
|
330
|
+
assert_equal %w[@type $arg add_prefix pattern replace], not_fetched
|
|
331
|
+
|
|
332
|
+
not_fetched = []; rule_conf.check_not_fetched {|key, e| not_fetched << key }
|
|
333
|
+
assert_equal %w[pattern replace], not_fetched
|
|
334
|
+
|
|
335
|
+
# repeatedly accessing should not grow memory usage
|
|
336
|
+
before_size = match_conf.unused.size
|
|
337
|
+
10.times { match_conf['type'] }
|
|
338
|
+
assert_equal before_size, match_conf.unused.size
|
|
168
339
|
end
|
|
169
|
-
create_warn_dummy_logger
|
|
170
340
|
end
|
|
171
341
|
|
|
172
|
-
def
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
logdev = Fluent::Test::DummyLogDevice.new
|
|
176
|
-
logger = ServerEngine::DaemonLogger.new(logdev, dl_opts)
|
|
177
|
-
$log = Fluent::Log.new(logger)
|
|
342
|
+
def write_config(path, data, encoding: 'utf-8')
|
|
343
|
+
FileUtils.mkdir_p(File.dirname(path))
|
|
344
|
+
File.open(path, "w:#{encoding}:utf-8") {|f| f.write data }
|
|
178
345
|
end
|
|
179
346
|
|
|
180
347
|
sub_test_case '.build' do
|
data/test/test_event_router.rb
CHANGED
|
@@ -326,6 +326,23 @@ class EventRouterTest < ::Test::Unit::TestCase
|
|
|
326
326
|
event_router.emit('test', Engine.now, 'k' => 'v')
|
|
327
327
|
end
|
|
328
328
|
end
|
|
329
|
+
|
|
330
|
+
test 'can pass records modified by filters to handle_emits_error' do
|
|
331
|
+
filter = Class.new(FluentTestFilter) {
|
|
332
|
+
def filter_stream(_tag, es); end
|
|
333
|
+
}.new
|
|
334
|
+
event_router.add_rule('test', filter)
|
|
335
|
+
event_router.add_rule('test', error_output)
|
|
336
|
+
|
|
337
|
+
time = Engine.now
|
|
338
|
+
modified_es = OneEventStream.new(time, 'modified_label' => 'modified_value')
|
|
339
|
+
|
|
340
|
+
assert_rr do
|
|
341
|
+
stub(filter).filter_stream { modified_es }
|
|
342
|
+
mock(emit_handler).handle_emits_error('test', modified_es, is_a(RuntimeError))
|
|
343
|
+
event_router.emit('test', time, 'pre_label' => 'pre_value')
|
|
344
|
+
end
|
|
345
|
+
end
|
|
329
346
|
end
|
|
330
347
|
end
|
|
331
348
|
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require_relative 'helper'
|
|
2
|
+
require 'fluent/file_wrapper'
|
|
3
|
+
|
|
4
|
+
class FileWrapperTest < Test::Unit::TestCase
|
|
5
|
+
TMP_DIR = File.dirname(__FILE__) + "/../tmp/file_wrapper#{ENV['TEST_ENV_NUMBER']}"
|
|
6
|
+
|
|
7
|
+
def setup
|
|
8
|
+
FileUtils.mkdir_p(TMP_DIR)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def teardown
|
|
12
|
+
FileUtils.rm_rf(TMP_DIR)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
sub_test_case 'WindowsFile exceptions' do
|
|
16
|
+
test 'nothing raised' do
|
|
17
|
+
begin
|
|
18
|
+
path = "#{TMP_DIR}/test_windows_file.txt"
|
|
19
|
+
file1 = file2 = nil
|
|
20
|
+
file1 = File.open(path, "wb") do |f|
|
|
21
|
+
end
|
|
22
|
+
assert_nothing_raised do
|
|
23
|
+
file2 = Fluent::WindowsFile.new(path)
|
|
24
|
+
ensure
|
|
25
|
+
file2.close
|
|
26
|
+
end
|
|
27
|
+
ensure
|
|
28
|
+
file1.close if file1
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
test 'Errno::ENOENT raised' do
|
|
33
|
+
path = "#{TMP_DIR}/nofile.txt"
|
|
34
|
+
file = nil
|
|
35
|
+
assert_raise(Errno::ENOENT) do
|
|
36
|
+
file = Fluent::WindowsFile.new(path)
|
|
37
|
+
ensure
|
|
38
|
+
file.close if file
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
test 'Errno::ENOENT raised on DeletePending' do
|
|
43
|
+
path = "#{TMP_DIR}/deletepending.txt"
|
|
44
|
+
file = Fluent::WindowsFile.new(path, mode='w')
|
|
45
|
+
File.delete(path)
|
|
46
|
+
assert_raise(Errno::ENOENT) do
|
|
47
|
+
file.stat
|
|
48
|
+
ensure
|
|
49
|
+
file.close if file
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end if Fluent.windows?
|
data/test/test_formatter.rb
CHANGED
|
@@ -18,7 +18,7 @@ module FormatterTest
|
|
|
18
18
|
|
|
19
19
|
def test_call
|
|
20
20
|
formatter = Formatter.new
|
|
21
|
-
formatter.configure(
|
|
21
|
+
formatter.configure(config_element())
|
|
22
22
|
assert_raise NotImplementedError do
|
|
23
23
|
formatter.format('tag', Engine.now, {})
|
|
24
24
|
end
|
|
@@ -130,7 +130,7 @@ module FormatterTest
|
|
|
130
130
|
include FormatterTest
|
|
131
131
|
|
|
132
132
|
def setup
|
|
133
|
-
@formatter = TextFormatter::MessagePackFormatter
|
|
133
|
+
@formatter = Fluent::Test::FormatterTestDriver.new(TextFormatter::MessagePackFormatter)
|
|
134
134
|
@time = Engine.now
|
|
135
135
|
end
|
|
136
136
|
|
|
@@ -146,7 +146,7 @@ module FormatterTest
|
|
|
146
146
|
include FormatterTest
|
|
147
147
|
|
|
148
148
|
def setup
|
|
149
|
-
@formatter = TextFormatter::LabeledTSVFormatter
|
|
149
|
+
@formatter = Fluent::Test::FormatterTestDriver.new(TextFormatter::LabeledTSVFormatter)
|
|
150
150
|
@time = Engine.now
|
|
151
151
|
@newline = if Fluent.windows?
|
|
152
152
|
"\r\n"
|
|
@@ -156,16 +156,16 @@ module FormatterTest
|
|
|
156
156
|
end
|
|
157
157
|
|
|
158
158
|
def test_config_params
|
|
159
|
-
assert_equal "\t", @formatter.delimiter
|
|
160
|
-
assert_equal ":", @formatter.label_delimiter
|
|
159
|
+
assert_equal "\t", @formatter.instance.delimiter
|
|
160
|
+
assert_equal ":", @formatter.instance.label_delimiter
|
|
161
161
|
|
|
162
162
|
@formatter.configure(
|
|
163
163
|
'delimiter' => ',',
|
|
164
164
|
'label_delimiter' => '=',
|
|
165
165
|
)
|
|
166
166
|
|
|
167
|
-
assert_equal ",", @formatter.delimiter
|
|
168
|
-
assert_equal "=", @formatter.label_delimiter
|
|
167
|
+
assert_equal ",", @formatter.instance.delimiter
|
|
168
|
+
assert_equal "=", @formatter.instance.label_delimiter
|
|
169
169
|
end
|
|
170
170
|
|
|
171
171
|
def test_format
|
|
@@ -220,14 +220,14 @@ module FormatterTest
|
|
|
220
220
|
include FormatterTest
|
|
221
221
|
|
|
222
222
|
def setup
|
|
223
|
-
@formatter = TextFormatter::CsvFormatter
|
|
223
|
+
@formatter = Fluent::Test::FormatterTestDriver.new(TextFormatter::CsvFormatter)
|
|
224
224
|
@time = Engine.now
|
|
225
225
|
end
|
|
226
226
|
|
|
227
227
|
def test_config_params
|
|
228
|
-
assert_equal ',', @formatter.delimiter
|
|
229
|
-
assert_equal true, @formatter.force_quotes
|
|
230
|
-
assert_nil @formatter.fields
|
|
228
|
+
assert_equal ',', @formatter.instance.delimiter
|
|
229
|
+
assert_equal true, @formatter.instance.force_quotes
|
|
230
|
+
assert_nil @formatter.instance.fields
|
|
231
231
|
end
|
|
232
232
|
|
|
233
233
|
data(
|
|
@@ -237,8 +237,8 @@ module FormatterTest
|
|
|
237
237
|
def test_config_params_with_customized_delimiters(data)
|
|
238
238
|
expected, target = data
|
|
239
239
|
@formatter.configure('delimiter' => target, 'fields' => 'a,b,c')
|
|
240
|
-
assert_equal expected, @formatter.delimiter
|
|
241
|
-
assert_equal ['a', 'b', 'c'], @formatter.fields
|
|
240
|
+
assert_equal expected, @formatter.instance.delimiter
|
|
241
|
+
assert_equal ['a', 'b', 'c'], @formatter.instance.fields
|
|
242
242
|
end
|
|
243
243
|
|
|
244
244
|
def test_format
|
|
@@ -299,7 +299,7 @@ module FormatterTest
|
|
|
299
299
|
'blank' => 'one,,two,three')
|
|
300
300
|
def test_config_params_with_fields(data)
|
|
301
301
|
@formatter.configure('fields' => data)
|
|
302
|
-
assert_equal %w(one two three), @formatter.fields
|
|
302
|
+
assert_equal %w(one two three), @formatter.instance.fields
|
|
303
303
|
end
|
|
304
304
|
end
|
|
305
305
|
|
|
@@ -313,31 +313,34 @@ module FormatterTest
|
|
|
313
313
|
end
|
|
314
314
|
end
|
|
315
315
|
|
|
316
|
+
def create_driver(klass_or_str)
|
|
317
|
+
Fluent::Test::FormatterTestDriver.new(klass_or_str)
|
|
318
|
+
end
|
|
316
319
|
|
|
317
320
|
def test_config_params
|
|
318
|
-
formatter = TextFormatter::SingleValueFormatter
|
|
319
|
-
assert_equal "message", formatter.message_key
|
|
321
|
+
formatter = create_driver(TextFormatter::SingleValueFormatter)
|
|
322
|
+
assert_equal "message", formatter.instance.message_key
|
|
320
323
|
|
|
321
324
|
formatter.configure('message_key' => 'foobar')
|
|
322
|
-
assert_equal "foobar", formatter.message_key
|
|
325
|
+
assert_equal "foobar", formatter.instance.message_key
|
|
323
326
|
end
|
|
324
327
|
|
|
325
328
|
def test_format
|
|
326
|
-
formatter =
|
|
329
|
+
formatter = create_driver('single_value')
|
|
327
330
|
formatter.configure({})
|
|
328
331
|
formatted = formatter.format('tag', Engine.now, {'message' => 'awesome'})
|
|
329
332
|
assert_equal("awesome#{@newline}", formatted)
|
|
330
333
|
end
|
|
331
334
|
|
|
332
335
|
def test_format_without_newline
|
|
333
|
-
formatter =
|
|
336
|
+
formatter = create_driver('single_value')
|
|
334
337
|
formatter.configure('add_newline' => 'false')
|
|
335
338
|
formatted = formatter.format('tag', Engine.now, {'message' => 'awesome'})
|
|
336
339
|
assert_equal("awesome", formatted)
|
|
337
340
|
end
|
|
338
341
|
|
|
339
342
|
def test_format_with_message_key
|
|
340
|
-
formatter = TextFormatter::SingleValueFormatter
|
|
343
|
+
formatter = create_driver(TextFormatter::SingleValueFormatter)
|
|
341
344
|
formatter.configure('message_key' => 'foobar')
|
|
342
345
|
formatted = formatter.format('tag', Engine.now, {'foobar' => 'foo'})
|
|
343
346
|
|
|
@@ -349,7 +352,7 @@ module FormatterTest
|
|
|
349
352
|
include FormatterTest
|
|
350
353
|
|
|
351
354
|
def test_unknown_format
|
|
352
|
-
assert_raise
|
|
355
|
+
assert_raise NotFoundPluginError do
|
|
353
356
|
Fluent::Plugin.new_formatter('unknown')
|
|
354
357
|
end
|
|
355
358
|
end
|