fluentd 0.12.40 → 1.6.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 +5 -5
- data/.github/ISSUE_TEMPLATE/bug_report.md +39 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
- data/.github/ISSUE_TEMPLATE.md +17 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +13 -0
- data/.gitignore +5 -0
- data/.gitlab/cicd-template.yaml +10 -0
- data/.gitlab-ci.yml +147 -0
- data/.travis.yml +56 -20
- data/ADOPTERS.md +5 -0
- data/CHANGELOG.md +1369 -0
- data/CONTRIBUTING.md +16 -5
- data/GOVERNANCE.md +55 -0
- data/Gemfile +5 -0
- data/GithubWorkflow.md +78 -0
- data/LICENSE +202 -0
- data/MAINTAINERS.md +7 -0
- data/README.md +23 -11
- data/Rakefile +48 -2
- data/Vagrantfile +17 -0
- data/appveyor.yml +37 -0
- data/bin/fluent-binlog-reader +7 -0
- data/bin/fluent-ca-generate +6 -0
- data/bin/fluent-plugin-config-format +5 -0
- data/bin/fluent-plugin-generate +5 -0
- data/bin/fluentd +3 -0
- data/code-of-conduct.md +3 -0
- data/example/copy_roundrobin.conf +39 -0
- data/example/counter.conf +18 -0
- data/example/in_dummy_blocks.conf +17 -0
- data/example/in_dummy_with_compression.conf +23 -0
- data/example/in_forward.conf +7 -0
- data/example/in_forward_client.conf +37 -0
- data/example/in_forward_shared_key.conf +15 -0
- data/example/in_forward_tls.conf +14 -0
- data/example/in_forward_users.conf +24 -0
- data/example/in_forward_workers.conf +21 -0
- data/example/in_http.conf +3 -1
- data/example/in_out_forward.conf +17 -0
- data/example/logevents.conf +25 -0
- data/example/multi_filters.conf +61 -0
- data/example/out_exec_filter.conf +42 -0
- data/example/out_forward.conf +13 -13
- data/example/out_forward_buf_file.conf +23 -0
- data/example/out_forward_client.conf +109 -0
- data/example/out_forward_heartbeat_none.conf +16 -0
- data/example/out_forward_shared_key.conf +36 -0
- data/example/out_forward_tls.conf +18 -0
- data/example/out_forward_users.conf +65 -0
- data/example/out_null.conf +36 -0
- data/example/secondary_file.conf +42 -0
- data/example/suppress_config_dump.conf +7 -0
- data/example/worker_section.conf +36 -0
- data/fluent.conf +29 -0
- data/fluentd.gemspec +21 -11
- data/lib/fluent/agent.rb +67 -90
- data/lib/fluent/clock.rb +62 -0
- data/lib/fluent/command/binlog_reader.rb +244 -0
- data/lib/fluent/command/ca_generate.rb +181 -0
- data/lib/fluent/command/cat.rb +42 -18
- data/lib/fluent/command/debug.rb +12 -10
- data/lib/fluent/command/fluentd.rb +153 -5
- data/lib/fluent/command/plugin_config_formatter.rb +292 -0
- data/lib/fluent/command/plugin_generator.rb +324 -0
- data/lib/fluent/compat/call_super_mixin.rb +67 -0
- data/lib/fluent/compat/detach_process_mixin.rb +33 -0
- data/lib/fluent/compat/exec_util.rb +129 -0
- data/lib/fluent/compat/file_util.rb +54 -0
- data/lib/fluent/compat/filter.rb +68 -0
- data/lib/fluent/compat/formatter.rb +111 -0
- data/lib/fluent/compat/formatter_utils.rb +85 -0
- data/lib/fluent/compat/handle_tag_and_time_mixin.rb +62 -0
- data/lib/fluent/compat/handle_tag_name_mixin.rb +53 -0
- data/lib/fluent/compat/input.rb +49 -0
- data/lib/fluent/compat/output.rb +718 -0
- data/lib/fluent/compat/output_chain.rb +60 -0
- data/lib/fluent/compat/parser.rb +310 -0
- data/lib/fluent/compat/parser_utils.rb +40 -0
- data/lib/fluent/compat/propagate_default.rb +62 -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/socket_util.rb +165 -0
- data/lib/fluent/compat/string_util.rb +34 -0
- data/lib/fluent/compat/structured_format_mixin.rb +26 -0
- data/lib/fluent/compat/type_converter.rb +90 -0
- data/lib/fluent/config/configure_proxy.rb +210 -62
- data/lib/fluent/config/dsl.rb +12 -5
- data/lib/fluent/config/element.rb +107 -9
- data/lib/fluent/config/literal_parser.rb +9 -3
- data/lib/fluent/config/parser.rb +4 -4
- data/lib/fluent/config/section.rb +51 -14
- data/lib/fluent/config/types.rb +28 -13
- data/lib/fluent/config/v1_parser.rb +3 -5
- data/lib/fluent/config.rb +23 -20
- data/lib/fluent/configurable.rb +79 -21
- data/lib/fluent/counter/base_socket.rb +46 -0
- data/lib/fluent/counter/client.rb +297 -0
- data/lib/fluent/counter/error.rb +86 -0
- data/lib/fluent/counter/mutex_hash.rb +163 -0
- data/lib/fluent/counter/server.rb +273 -0
- data/lib/fluent/counter/store.rb +205 -0
- data/lib/fluent/counter/validator.rb +145 -0
- data/lib/fluent/counter.rb +23 -0
- data/lib/fluent/daemon.rb +15 -0
- data/lib/fluent/engine.rb +102 -65
- data/lib/fluent/env.rb +7 -3
- data/lib/fluent/error.rb +30 -0
- data/lib/fluent/event.rb +197 -21
- data/lib/fluent/event_router.rb +93 -10
- data/lib/fluent/filter.rb +2 -50
- data/lib/fluent/formatter.rb +4 -293
- data/lib/fluent/input.rb +2 -32
- data/lib/fluent/label.rb +10 -2
- data/lib/fluent/load.rb +3 -3
- data/lib/fluent/log.rb +348 -81
- data/lib/fluent/match.rb +37 -36
- data/lib/fluent/mixin.rb +12 -176
- data/lib/fluent/msgpack_factory.rb +62 -0
- data/lib/fluent/output.rb +10 -612
- data/lib/fluent/output_chain.rb +23 -0
- data/lib/fluent/parser.rb +4 -800
- data/lib/fluent/plugin/bare_output.rb +63 -0
- data/lib/fluent/plugin/base.rb +192 -0
- data/lib/fluent/plugin/buf_file.rb +128 -174
- data/lib/fluent/plugin/buf_memory.rb +9 -92
- data/lib/fluent/plugin/buffer/chunk.rb +221 -0
- data/lib/fluent/plugin/buffer/file_chunk.rb +383 -0
- data/lib/fluent/plugin/buffer/memory_chunk.rb +90 -0
- data/lib/fluent/plugin/buffer.rb +779 -0
- data/lib/fluent/plugin/compressable.rb +92 -0
- data/lib/fluent/plugin/exec_util.rb +3 -108
- data/lib/fluent/plugin/file_util.rb +4 -34
- data/lib/fluent/plugin/file_wrapper.rb +120 -0
- data/lib/fluent/plugin/filter.rb +93 -0
- data/lib/fluent/plugin/filter_grep.rb +117 -34
- data/lib/fluent/plugin/filter_parser.rb +85 -62
- data/lib/fluent/plugin/filter_record_transformer.rb +27 -39
- data/lib/fluent/plugin/filter_stdout.rb +15 -12
- data/lib/fluent/plugin/formatter.rb +50 -0
- data/lib/fluent/plugin/formatter_csv.rb +52 -0
- data/lib/fluent/plugin/formatter_hash.rb +33 -0
- data/lib/fluent/plugin/formatter_json.rb +55 -0
- data/lib/fluent/plugin/formatter_ltsv.rb +42 -0
- data/lib/fluent/plugin/formatter_msgpack.rb +33 -0
- data/lib/fluent/plugin/formatter_out_file.rb +51 -0
- data/lib/fluent/plugin/formatter_single_value.rb +34 -0
- data/lib/fluent/plugin/formatter_stdout.rb +76 -0
- data/lib/fluent/plugin/formatter_tsv.rb +38 -0
- data/lib/fluent/plugin/in_debug_agent.rb +17 -6
- data/lib/fluent/plugin/in_dummy.rb +47 -20
- data/lib/fluent/plugin/in_exec.rb +55 -123
- data/lib/fluent/plugin/in_forward.rb +299 -216
- data/lib/fluent/plugin/in_gc_stat.rb +14 -36
- data/lib/fluent/plugin/in_http.rb +204 -91
- data/lib/fluent/plugin/in_monitor_agent.rb +186 -258
- data/lib/fluent/plugin/in_object_space.rb +13 -41
- data/lib/fluent/plugin/in_syslog.rb +112 -134
- data/lib/fluent/plugin/in_tail.rb +408 -745
- data/lib/fluent/plugin/in_tcp.rb +66 -9
- data/lib/fluent/plugin/in_udp.rb +60 -11
- data/lib/fluent/plugin/{in_stream.rb → in_unix.rb} +8 -4
- data/lib/fluent/plugin/input.rb +37 -0
- data/lib/fluent/plugin/multi_output.rb +158 -0
- data/lib/fluent/plugin/out_copy.rb +23 -35
- data/lib/fluent/plugin/out_exec.rb +67 -70
- data/lib/fluent/plugin/out_exec_filter.rb +204 -271
- data/lib/fluent/plugin/out_file.rb +267 -73
- data/lib/fluent/plugin/out_forward.rb +854 -325
- data/lib/fluent/plugin/out_null.rb +42 -9
- data/lib/fluent/plugin/out_relabel.rb +9 -5
- data/lib/fluent/plugin/out_roundrobin.rb +18 -37
- data/lib/fluent/plugin/out_secondary_file.rb +133 -0
- data/lib/fluent/plugin/out_stdout.rb +43 -10
- data/lib/fluent/plugin/out_stream.rb +7 -2
- data/lib/fluent/plugin/output.rb +1498 -0
- data/lib/fluent/plugin/owned_by_mixin.rb +42 -0
- data/lib/fluent/plugin/parser.rb +191 -0
- data/lib/fluent/plugin/parser_apache.rb +28 -0
- data/lib/fluent/plugin/parser_apache2.rb +88 -0
- data/lib/fluent/plugin/parser_apache_error.rb +26 -0
- data/lib/fluent/plugin/parser_csv.rb +39 -0
- data/lib/fluent/plugin/parser_json.rb +94 -0
- data/lib/fluent/plugin/parser_ltsv.rb +49 -0
- data/lib/fluent/plugin/parser_msgpack.rb +50 -0
- data/lib/fluent/plugin/parser_multiline.rb +106 -0
- data/lib/fluent/plugin/parser_nginx.rb +28 -0
- data/lib/fluent/plugin/parser_none.rb +36 -0
- data/lib/fluent/plugin/parser_regexp.rb +68 -0
- data/lib/fluent/plugin/parser_syslog.rb +142 -0
- data/lib/fluent/plugin/parser_tsv.rb +42 -0
- data/lib/fluent/plugin/socket_util.rb +3 -143
- data/lib/fluent/plugin/storage.rb +84 -0
- data/lib/fluent/plugin/storage_local.rb +164 -0
- data/lib/fluent/plugin/string_util.rb +3 -15
- data/lib/fluent/plugin.rb +122 -121
- data/lib/fluent/plugin_helper/cert_option.rb +178 -0
- data/lib/fluent/plugin_helper/child_process.rb +364 -0
- data/lib/fluent/plugin_helper/compat_parameters.rb +333 -0
- data/lib/fluent/plugin_helper/counter.rb +51 -0
- data/lib/fluent/plugin_helper/event_emitter.rb +93 -0
- data/lib/fluent/plugin_helper/event_loop.rb +170 -0
- data/lib/fluent/plugin_helper/extract.rb +104 -0
- data/lib/fluent/plugin_helper/formatter.rb +147 -0
- data/lib/fluent/plugin_helper/http_server/app.rb +79 -0
- data/lib/fluent/plugin_helper/http_server/compat/server.rb +81 -0
- data/lib/fluent/plugin_helper/http_server/compat/webrick_handler.rb +58 -0
- data/lib/fluent/plugin_helper/http_server/methods.rb +35 -0
- data/lib/fluent/plugin_helper/http_server/request.rb +42 -0
- data/lib/fluent/plugin_helper/http_server/router.rb +54 -0
- data/lib/fluent/plugin_helper/http_server/server.rb +87 -0
- data/lib/fluent/plugin_helper/http_server.rb +76 -0
- data/lib/fluent/plugin_helper/inject.rb +151 -0
- data/lib/fluent/plugin_helper/parser.rb +147 -0
- data/lib/fluent/plugin_helper/record_accessor.rb +210 -0
- data/lib/fluent/plugin_helper/retry_state.rb +205 -0
- data/lib/fluent/plugin_helper/server.rb +807 -0
- data/lib/fluent/plugin_helper/socket.rb +250 -0
- data/lib/fluent/plugin_helper/socket_option.rb +80 -0
- data/lib/fluent/plugin_helper/storage.rb +349 -0
- data/lib/fluent/plugin_helper/thread.rb +179 -0
- data/lib/fluent/plugin_helper/timer.rb +92 -0
- data/lib/fluent/plugin_helper.rb +73 -0
- data/lib/fluent/plugin_id.rb +80 -0
- data/lib/fluent/process.rb +3 -489
- data/lib/fluent/registry.rb +52 -10
- data/lib/fluent/root_agent.rb +204 -42
- data/lib/fluent/supervisor.rb +597 -359
- data/lib/fluent/system_config.rb +131 -42
- data/lib/fluent/test/base.rb +6 -54
- data/lib/fluent/test/driver/base.rb +224 -0
- data/lib/fluent/test/driver/base_owned.rb +70 -0
- data/lib/fluent/test/driver/base_owner.rb +135 -0
- data/lib/fluent/test/driver/event_feeder.rb +98 -0
- data/lib/fluent/test/driver/filter.rb +57 -0
- data/lib/fluent/test/driver/formatter.rb +30 -0
- data/lib/fluent/test/driver/input.rb +31 -0
- data/lib/fluent/test/driver/multi_output.rb +53 -0
- data/lib/fluent/test/driver/output.rb +102 -0
- data/lib/fluent/test/driver/parser.rb +30 -0
- data/lib/fluent/test/driver/test_event_router.rb +45 -0
- data/lib/fluent/test/filter_test.rb +0 -1
- data/lib/fluent/test/formatter_test.rb +4 -1
- data/lib/fluent/test/helpers.rb +58 -10
- data/lib/fluent/test/input_test.rb +27 -19
- data/lib/fluent/test/log.rb +79 -0
- data/lib/fluent/test/output_test.rb +28 -39
- data/lib/fluent/test/parser_test.rb +3 -1
- data/lib/fluent/test/startup_shutdown.rb +46 -0
- data/lib/fluent/test.rb +33 -1
- data/lib/fluent/time.rb +450 -1
- data/lib/fluent/timezone.rb +27 -3
- data/lib/fluent/{status.rb → unique_id.rb} +15 -24
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/winsvc.rb +85 -0
- data/templates/new_gem/Gemfile +3 -0
- data/templates/new_gem/README.md.erb +43 -0
- data/templates/new_gem/Rakefile +13 -0
- data/templates/new_gem/fluent-plugin.gemspec.erb +27 -0
- data/templates/new_gem/lib/fluent/plugin/filter.rb.erb +14 -0
- data/templates/new_gem/lib/fluent/plugin/formatter.rb.erb +14 -0
- data/templates/new_gem/lib/fluent/plugin/input.rb.erb +11 -0
- data/templates/new_gem/lib/fluent/plugin/output.rb.erb +11 -0
- data/templates/new_gem/lib/fluent/plugin/parser.rb.erb +15 -0
- data/templates/new_gem/test/helper.rb.erb +8 -0
- data/templates/new_gem/test/plugin/test_filter.rb.erb +18 -0
- data/templates/new_gem/test/plugin/test_formatter.rb.erb +18 -0
- data/templates/new_gem/test/plugin/test_input.rb.erb +18 -0
- data/templates/new_gem/test/plugin/test_output.rb.erb +18 -0
- data/templates/new_gem/test/plugin/test_parser.rb.erb +18 -0
- data/templates/plugin_config_formatter/param.md-compact.erb +25 -0
- data/templates/plugin_config_formatter/param.md.erb +34 -0
- data/templates/plugin_config_formatter/section.md.erb +12 -0
- data/test/command/test_binlog_reader.rb +346 -0
- data/test/command/test_ca_generate.rb +70 -0
- data/test/command/test_fluentd.rb +901 -0
- data/test/command/test_plugin_config_formatter.rb +276 -0
- data/test/command/test_plugin_generator.rb +92 -0
- data/test/compat/test_calls_super.rb +166 -0
- data/test/compat/test_parser.rb +92 -0
- data/test/config/test_config_parser.rb +126 -2
- data/test/config/test_configurable.rb +946 -187
- data/test/config/test_configure_proxy.rb +424 -74
- data/test/config/test_dsl.rb +11 -11
- data/test/config/test_element.rb +500 -0
- data/test/config/test_literal_parser.rb +8 -0
- data/test/config/test_plugin_configuration.rb +56 -0
- data/test/config/test_section.rb +79 -7
- data/test/config/test_system_config.rb +122 -35
- data/test/config/test_types.rb +38 -0
- data/test/counter/test_client.rb +559 -0
- data/test/counter/test_error.rb +44 -0
- data/test/counter/test_mutex_hash.rb +179 -0
- data/test/counter/test_server.rb +589 -0
- data/test/counter/test_store.rb +258 -0
- data/test/counter/test_validator.rb +137 -0
- data/test/helper.rb +89 -6
- data/test/helpers/fuzzy_assert.rb +89 -0
- data/test/plugin/test_bare_output.rb +118 -0
- data/test/plugin/test_base.rb +115 -0
- data/test/plugin/test_buf_file.rb +823 -460
- data/test/plugin/test_buf_memory.rb +32 -194
- data/test/plugin/test_buffer.rb +1233 -0
- data/test/plugin/test_buffer_chunk.rb +198 -0
- data/test/plugin/test_buffer_file_chunk.rb +844 -0
- data/test/plugin/test_buffer_memory_chunk.rb +338 -0
- data/test/plugin/test_compressable.rb +84 -0
- data/test/plugin/test_filter.rb +357 -0
- data/test/plugin/test_filter_grep.rb +540 -29
- data/test/plugin/test_filter_parser.rb +439 -452
- data/test/plugin/test_filter_record_transformer.rb +123 -166
- data/test/plugin/test_filter_stdout.rb +160 -72
- data/test/plugin/test_formatter_csv.rb +111 -0
- data/test/plugin/test_formatter_hash.rb +35 -0
- data/test/plugin/test_formatter_json.rb +51 -0
- data/test/plugin/test_formatter_ltsv.rb +62 -0
- data/test/plugin/test_formatter_msgpack.rb +28 -0
- data/test/plugin/test_formatter_out_file.rb +95 -0
- data/test/plugin/test_formatter_single_value.rb +38 -0
- data/test/plugin/test_formatter_tsv.rb +68 -0
- data/test/plugin/test_in_debug_agent.rb +24 -1
- data/test/plugin/test_in_dummy.rb +111 -18
- data/test/plugin/test_in_exec.rb +200 -113
- data/test/plugin/test_in_forward.rb +990 -387
- data/test/plugin/test_in_gc_stat.rb +10 -8
- data/test/plugin/test_in_http.rb +600 -224
- data/test/plugin/test_in_monitor_agent.rb +690 -0
- data/test/plugin/test_in_object_space.rb +24 -8
- data/test/plugin/test_in_syslog.rb +154 -215
- data/test/plugin/test_in_tail.rb +1006 -707
- data/test/plugin/test_in_tcp.rb +125 -48
- data/test/plugin/test_in_udp.rb +204 -63
- data/test/plugin/{test_in_stream.rb → test_in_unix.rb} +14 -13
- data/test/plugin/test_input.rb +126 -0
- data/test/plugin/test_metadata.rb +89 -0
- data/test/plugin/test_multi_output.rb +180 -0
- data/test/plugin/test_out_copy.rb +117 -112
- data/test/plugin/test_out_exec.rb +258 -53
- data/test/plugin/test_out_exec_filter.rb +538 -115
- data/test/plugin/test_out_file.rb +865 -178
- data/test/plugin/test_out_forward.rb +998 -210
- data/test/plugin/test_out_null.rb +105 -0
- data/test/plugin/test_out_relabel.rb +28 -0
- data/test/plugin/test_out_roundrobin.rb +36 -29
- data/test/plugin/test_out_secondary_file.rb +458 -0
- data/test/plugin/test_out_stdout.rb +135 -37
- data/test/plugin/test_out_stream.rb +18 -0
- data/test/plugin/test_output.rb +984 -0
- data/test/plugin/test_output_as_buffered.rb +2021 -0
- data/test/plugin/test_output_as_buffered_backup.rb +312 -0
- data/test/plugin/test_output_as_buffered_compress.rb +165 -0
- data/test/plugin/test_output_as_buffered_overflow.rb +250 -0
- data/test/plugin/test_output_as_buffered_retries.rb +911 -0
- data/test/plugin/test_output_as_buffered_secondary.rb +874 -0
- data/test/plugin/test_output_as_standard.rb +374 -0
- data/test/plugin/test_owned_by.rb +35 -0
- data/test/plugin/test_parser.rb +359 -0
- data/test/plugin/test_parser_apache.rb +42 -0
- data/test/plugin/test_parser_apache2.rb +47 -0
- data/test/plugin/test_parser_apache_error.rb +45 -0
- data/test/plugin/test_parser_csv.rb +103 -0
- data/test/plugin/test_parser_json.rb +138 -0
- data/test/plugin/test_parser_labeled_tsv.rb +145 -0
- data/test/plugin/test_parser_multiline.rb +100 -0
- data/test/plugin/test_parser_nginx.rb +88 -0
- data/test/plugin/test_parser_none.rb +52 -0
- data/test/plugin/test_parser_regexp.rb +289 -0
- data/test/plugin/test_parser_syslog.rb +441 -0
- data/test/plugin/test_parser_tsv.rb +122 -0
- data/test/plugin/test_storage.rb +167 -0
- data/test/plugin/test_storage_local.rb +335 -0
- data/test/plugin_helper/data/cert/cert-key.pem +27 -0
- data/test/plugin_helper/data/cert/cert-with-no-newline.pem +19 -0
- data/test/plugin_helper/data/cert/cert.pem +19 -0
- data/test/plugin_helper/http_server/test_app.rb +65 -0
- data/test/plugin_helper/http_server/test_route.rb +32 -0
- data/test/plugin_helper/test_cert_option.rb +16 -0
- data/test/plugin_helper/test_child_process.rb +794 -0
- data/test/plugin_helper/test_compat_parameters.rb +353 -0
- data/test/plugin_helper/test_event_emitter.rb +51 -0
- data/test/plugin_helper/test_event_loop.rb +52 -0
- data/test/plugin_helper/test_extract.rb +194 -0
- data/test/plugin_helper/test_formatter.rb +255 -0
- data/test/plugin_helper/test_http_server_helper.rb +205 -0
- data/test/plugin_helper/test_inject.rb +519 -0
- data/test/plugin_helper/test_parser.rb +264 -0
- data/test/plugin_helper/test_record_accessor.rb +197 -0
- data/test/plugin_helper/test_retry_state.rb +442 -0
- data/test/plugin_helper/test_server.rb +1714 -0
- data/test/plugin_helper/test_storage.rb +542 -0
- data/test/plugin_helper/test_thread.rb +164 -0
- data/test/plugin_helper/test_timer.rb +132 -0
- data/test/scripts/exec_script.rb +0 -6
- data/test/scripts/fluent/plugin/formatter1/formatter_test1.rb +7 -0
- data/test/scripts/fluent/plugin/formatter2/formatter_test2.rb +7 -0
- data/test/scripts/fluent/plugin/out_test.rb +23 -15
- data/test/scripts/fluent/plugin/out_test2.rb +80 -0
- data/test/test_clock.rb +164 -0
- data/test/test_config.rb +16 -7
- data/test/test_configdsl.rb +2 -2
- data/test/test_event.rb +360 -13
- data/test/test_event_router.rb +108 -11
- data/test/test_event_time.rb +199 -0
- data/test/test_filter.rb +48 -6
- data/test/test_formatter.rb +11 -391
- data/test/test_input.rb +1 -1
- data/test/test_log.rb +591 -31
- data/test/test_mixin.rb +1 -1
- data/test/test_output.rb +121 -185
- data/test/test_plugin.rb +251 -0
- data/test/test_plugin_classes.rb +177 -10
- data/test/test_plugin_helper.rb +81 -0
- data/test/test_plugin_id.rb +101 -0
- data/test/test_process.rb +8 -42
- data/test/test_root_agent.rb +766 -21
- data/test/test_supervisor.rb +481 -0
- data/test/test_test_drivers.rb +135 -0
- data/test/test_time_formatter.rb +282 -0
- data/test/test_time_parser.rb +231 -0
- data/test/test_unique_id.rb +47 -0
- metadata +454 -60
- data/COPYING +0 -14
- data/ChangeLog +0 -666
- data/lib/fluent/buffer.rb +0 -365
- data/lib/fluent/plugin/in_status.rb +0 -76
- data/test/plugin/test_in_status.rb +0 -38
- data/test/test_buffer.rb +0 -624
- data/test/test_parser.rb +0 -1305
@@ -1,7 +1,10 @@
|
|
1
1
|
require_relative '../helper'
|
2
|
-
require 'fluent/test'
|
2
|
+
require 'fluent/test/driver/output'
|
3
|
+
require 'fluent/plugin/out_file'
|
3
4
|
require 'fileutils'
|
4
5
|
require 'time'
|
6
|
+
require 'timecop'
|
7
|
+
require 'zlib'
|
5
8
|
|
6
9
|
class FileOutputTest < Test::Unit::TestCase
|
7
10
|
def setup
|
@@ -11,109 +14,360 @@ class FileOutputTest < Test::Unit::TestCase
|
|
11
14
|
end
|
12
15
|
|
13
16
|
TMP_DIR = File.expand_path(File.dirname(__FILE__) + "/../tmp/out_file#{ENV['TEST_ENV_NUMBER']}")
|
14
|
-
SYMLINK_PATH = File.expand_path("#{TMP_DIR}/current")
|
15
17
|
|
16
18
|
CONFIG = %[
|
17
19
|
path #{TMP_DIR}/out_file_test
|
18
20
|
compress gz
|
19
21
|
utc
|
22
|
+
<buffer>
|
23
|
+
timekey_use_utc true
|
24
|
+
</buffer>
|
20
25
|
]
|
21
26
|
|
22
|
-
def create_driver(conf = CONFIG)
|
23
|
-
Fluent::Test::
|
27
|
+
def create_driver(conf = CONFIG, opts = {})
|
28
|
+
Fluent::Test::Driver::Output.new(Fluent::Plugin::FileOutput, opts: opts).configure(conf)
|
24
29
|
end
|
25
30
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
31
|
+
sub_test_case 'configuration' do
|
32
|
+
test 'basic configuration' do
|
33
|
+
d = create_driver %[
|
34
|
+
path test_path
|
35
|
+
compress gz
|
36
|
+
]
|
37
|
+
assert_equal 'test_path', d.instance.path
|
38
|
+
assert_equal :gz, d.instance.compress
|
39
|
+
assert_equal :gzip, d.instance.instance_eval{ @compress_method }
|
40
|
+
end
|
33
41
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
+
test 'using root_dir for buffer path' do
|
43
|
+
system_conf_opts = {'root_dir' => File.join(TMP_DIR, 'testrootdir')}
|
44
|
+
buf_conf = config_element('buffer', '', {'flush_interval' => '1s'})
|
45
|
+
conf = config_element('match', '**', {'@id' => 'myout', 'path' => 'test_path', 'append' => 'true'}, [buf_conf])
|
46
|
+
d = create_driver(conf, system_conf_opts)
|
47
|
+
|
48
|
+
assert_equal 'test_path', d.instance.path
|
49
|
+
assert d.instance.append
|
42
50
|
|
43
|
-
|
44
|
-
|
45
|
-
|
51
|
+
assert d.instance.buffer.respond_to?(:path) # file buffer
|
52
|
+
assert_equal 1, d.instance.buffer_config.flush_interval
|
53
|
+
|
54
|
+
assert_equal File.join(TMP_DIR, 'testrootdir', 'worker0', 'myout'), d.instance.plugin_root_dir
|
55
|
+
|
56
|
+
buffer_path_under_root_dir = File.join(TMP_DIR, 'testrootdir', 'worker0', 'myout', 'buffer', 'buffer.*.log')
|
57
|
+
assert_equal buffer_path_under_root_dir, d.instance.buffer.path
|
46
58
|
end
|
47
59
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
60
|
+
test 'path should be writable' do
|
61
|
+
assert_raise(Fluent::ConfigError.new("'path' parameter is required")) do
|
62
|
+
create_driver ""
|
63
|
+
end
|
64
|
+
|
65
|
+
assert_nothing_raised do
|
66
|
+
create_driver %[path #{TMP_DIR}/test_path]
|
67
|
+
end
|
68
|
+
|
69
|
+
assert_nothing_raised do
|
70
|
+
FileUtils.mkdir_p("#{TMP_DIR}/test_dir")
|
71
|
+
File.chmod(0777, "#{TMP_DIR}/test_dir")
|
72
|
+
create_driver %[path #{TMP_DIR}/test_dir/foo/bar/baz]
|
73
|
+
end
|
74
|
+
|
75
|
+
if Process.uid.nonzero?
|
76
|
+
assert_raise(Fluent::ConfigError) do
|
77
|
+
FileUtils.mkdir_p("#{TMP_DIR}/test_dir")
|
78
|
+
File.chmod(0555, "#{TMP_DIR}/test_dir")
|
79
|
+
create_driver %[path #{TMP_DIR}/test_dir/foo/bar/baz]
|
80
|
+
end
|
81
|
+
end
|
52
82
|
end
|
53
83
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
84
|
+
test 'default timezone is localtime' do
|
85
|
+
d = create_driver(%[path #{TMP_DIR}/out_file_test])
|
86
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
87
|
+
|
88
|
+
with_timezone(Fluent.windows? ? 'NST-8' : 'Asia/Taipei') do
|
89
|
+
d.run(default_tag: 'test') do
|
90
|
+
d.feed(time, {"a"=>1})
|
91
|
+
end
|
92
|
+
end
|
93
|
+
assert_equal 1, d.formatted.size
|
94
|
+
assert_equal %[2011-01-02T21:14:15+08:00\ttest\t{"a":1}\n], d.formatted[0]
|
58
95
|
end
|
59
|
-
end
|
60
96
|
|
61
|
-
|
62
|
-
|
63
|
-
|
97
|
+
test 'no configuration error raised for basic configuration using "*" (v0.12 style)' do
|
98
|
+
conf = config_element('match', '**', {
|
99
|
+
'path' => "#{TMP_DIR}/test_out.*.log",
|
100
|
+
'time_slice_format' => '%Y%m%d',
|
101
|
+
})
|
102
|
+
assert_nothing_raised do
|
103
|
+
create_driver(conf)
|
104
|
+
end
|
105
|
+
end
|
64
106
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
107
|
+
if Process.uid.nonzero?
|
108
|
+
test 'configuration error raised if specified directory via template is not writable' do
|
109
|
+
Timecop.freeze(Time.parse("2016-10-04 21:33:27 UTC")) do
|
110
|
+
conf = config_element('match', '**', {
|
111
|
+
'path' => "#{TMP_DIR}/prohibited/${tag}/file.%Y%m%d.log",
|
112
|
+
}, [ config_element('buffer', 'time,tag', {'timekey' => 86400, 'timekey_zone' => '+0000'}) ])
|
113
|
+
FileUtils.mkdir_p("#{TMP_DIR}/prohibited")
|
114
|
+
File.chmod(0555, "#{TMP_DIR}/prohibited")
|
115
|
+
assert_raise Fluent::ConfigError.new("out_file: `#{TMP_DIR}/prohibited/a/file.20161004.log_**.log` is not writable") do
|
116
|
+
create_driver(conf)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
test 'configuration using inject/format/buffer sections fully' do
|
123
|
+
conf = config_element('match', '**', {
|
124
|
+
'path' => "#{TMP_DIR}/${tag}/${type}/conf_test.%Y%m%d.%H%M.log",
|
125
|
+
'add_path_suffix' => 'false',
|
126
|
+
'append' => "true",
|
127
|
+
'symlink_path' => "#{TMP_DIR}/conf_test.current.log",
|
128
|
+
'compress' => 'gzip',
|
129
|
+
'recompress' => 'true',
|
130
|
+
}, [
|
131
|
+
config_element('inject', '', {
|
132
|
+
'hostname_key' => 'hostname',
|
133
|
+
'hostname' => 'testing.local',
|
134
|
+
'tag_key' => 'tag',
|
135
|
+
'time_key' => 'time',
|
136
|
+
'time_type' => 'string',
|
137
|
+
'time_format' => '%Y/%m/%d %H:%M:%S %z',
|
138
|
+
'timezone' => '+0900',
|
139
|
+
}),
|
140
|
+
config_element('format', '', {
|
141
|
+
'@type' => 'out_file',
|
142
|
+
'include_tag' => 'true',
|
143
|
+
'include_time' => 'true',
|
144
|
+
'delimiter' => 'COMMA',
|
145
|
+
'time_type' => 'string',
|
146
|
+
'time_format' => '%Y-%m-%d %H:%M:%S %z',
|
147
|
+
'utc' => 'true',
|
148
|
+
}),
|
149
|
+
config_element('buffer', 'time,tag,type', {
|
150
|
+
'@type' => 'file',
|
151
|
+
'timekey' => '15m',
|
152
|
+
'timekey_wait' => '5s',
|
153
|
+
'timekey_zone' => '+0000',
|
154
|
+
'path' => "#{TMP_DIR}/buf_conf_test",
|
155
|
+
'chunk_limit_size' => '50m',
|
156
|
+
'total_limit_size' => '1g',
|
157
|
+
'compress' => 'gzip',
|
158
|
+
}),
|
159
|
+
])
|
160
|
+
assert_nothing_raised do
|
161
|
+
create_driver(conf)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
test 'configured as secondary with primary using chunk_key_tag and not using chunk_key_time' do
|
166
|
+
require 'fluent/plugin/out_null'
|
167
|
+
conf = config_element('match', '**', {
|
168
|
+
}, [
|
169
|
+
config_element('buffer', 'tag', {
|
170
|
+
}),
|
171
|
+
config_element('secondary', '', {
|
172
|
+
'@type' => 'file',
|
173
|
+
'path' => "#{TMP_DIR}/testing_to_dump_by_out_file",
|
174
|
+
}),
|
175
|
+
])
|
176
|
+
assert_nothing_raised do
|
177
|
+
Fluent::Test::Driver::Output.new(Fluent::Plugin::NullOutput).configure(conf)
|
178
|
+
end
|
69
179
|
end
|
70
180
|
end
|
71
181
|
|
72
|
-
|
73
|
-
|
182
|
+
sub_test_case 'fully configured output' do
|
183
|
+
setup do
|
184
|
+
Timecop.freeze(Time.parse("2016-10-03 23:58:00 UTC"))
|
185
|
+
conf = config_element('match', '**', {
|
186
|
+
'path' => "#{TMP_DIR}/${tag}/${type}/full.%Y%m%d.%H%M.log",
|
187
|
+
'add_path_suffix' => 'false',
|
188
|
+
'append' => "true",
|
189
|
+
'symlink_path' => "#{TMP_DIR}/full.current.log",
|
190
|
+
'compress' => 'gzip',
|
191
|
+
'recompress' => 'true',
|
192
|
+
}, [
|
193
|
+
config_element('inject', '', {
|
194
|
+
'hostname_key' => 'hostname',
|
195
|
+
'hostname' => 'testing.local',
|
196
|
+
'tag_key' => 'tag',
|
197
|
+
'time_key' => 'time',
|
198
|
+
'time_type' => 'string',
|
199
|
+
'time_format' => '%Y/%m/%d %H:%M:%S %z',
|
200
|
+
'timezone' => '+0900',
|
201
|
+
}),
|
202
|
+
config_element('format', '', {
|
203
|
+
'@type' => 'out_file',
|
204
|
+
'include_tag' => 'true',
|
205
|
+
'include_time' => 'true',
|
206
|
+
'delimiter' => 'COMMA',
|
207
|
+
'time_type' => 'string',
|
208
|
+
'time_format' => '%Y-%m-%d %H:%M:%S %z',
|
209
|
+
'utc' => 'true',
|
210
|
+
}),
|
211
|
+
config_element('buffer', 'time,tag,type', {
|
212
|
+
'@type' => 'file',
|
213
|
+
'timekey' => '15m',
|
214
|
+
'timekey_wait' => '5s',
|
215
|
+
'timekey_zone' => '+0000',
|
216
|
+
'path' => "#{TMP_DIR}/buf_full",
|
217
|
+
'chunk_limit_size' => '50m',
|
218
|
+
'total_limit_size' => '1g',
|
219
|
+
'compress' => 'gzip',
|
220
|
+
}),
|
221
|
+
])
|
222
|
+
@d = create_driver(conf)
|
223
|
+
end
|
74
224
|
|
75
|
-
|
76
|
-
|
77
|
-
|
225
|
+
teardown do
|
226
|
+
FileUtils.rm_rf("#{TMP_DIR}/buf_full")
|
227
|
+
FileUtils.rm_rf("#{TMP_DIR}/my.data")
|
228
|
+
FileUtils.rm_rf("#{TMP_DIR}/your.data")
|
229
|
+
FileUtils.rm_rf("#{TMP_DIR}/full.current.log")
|
230
|
+
Timecop.return
|
231
|
+
end
|
78
232
|
|
79
|
-
|
80
|
-
|
233
|
+
test 'can format/write data correctly' do
|
234
|
+
d = @d
|
81
235
|
|
82
|
-
|
83
|
-
|
236
|
+
assert_equal 50*1024*1024, d.instance.buffer.chunk_limit_size
|
237
|
+
assert_equal 1*1024*1024*1024, d.instance.buffer.total_limit_size
|
84
238
|
|
85
|
-
|
86
|
-
d = create_driver %[
|
87
|
-
path #{TMP_DIR}/out_file_test
|
88
|
-
timezone Asia/Taipei
|
89
|
-
]
|
239
|
+
assert !(File.symlink?("#{TMP_DIR}/full.current.log"))
|
90
240
|
|
91
|
-
|
241
|
+
t1 = event_time("2016-10-03 23:58:09 UTC")
|
242
|
+
t2 = event_time("2016-10-03 23:59:33 UTC")
|
243
|
+
t3 = event_time("2016-10-03 23:59:57 UTC")
|
244
|
+
t4 = event_time("2016-10-04 00:00:17 UTC")
|
245
|
+
t5 = event_time("2016-10-04 00:01:59 UTC")
|
92
246
|
|
93
|
-
|
94
|
-
d.expect_format %[2011-01-02T21:14:15+08:00\ttest\t{"a":1}\n]
|
95
|
-
d.run
|
96
|
-
end
|
247
|
+
Timecop.freeze(Time.parse("2016-10-03 23:58:30 UTC"))
|
97
248
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
249
|
+
d.run(start: true, flush: false, shutdown: false) do
|
250
|
+
d.feed('my.data', t1, {"type" => "a", "message" => "data raw content"})
|
251
|
+
d.feed('my.data', t2, {"type" => "a", "message" => "data raw content"})
|
252
|
+
d.feed('your.data', t3, {"type" => "a", "message" => "data raw content"})
|
253
|
+
end
|
254
|
+
|
255
|
+
assert_equal 3, d.formatted.size
|
256
|
+
|
257
|
+
assert Dir.exist?("#{TMP_DIR}/buf_full")
|
258
|
+
assert !(Dir.exist?("#{TMP_DIR}/my.data/a"))
|
259
|
+
assert !(Dir.exist?("#{TMP_DIR}/your.data/a"))
|
260
|
+
buffer_files = Dir.entries("#{TMP_DIR}/buf_full").reject{|e| e =~ /^\.+$/ }
|
261
|
+
assert_equal 2, buffer_files.select{|n| n.end_with?('.meta') }.size
|
262
|
+
assert_equal 2, buffer_files.select{|n| !n.end_with?('.meta') }.size
|
103
263
|
|
104
|
-
|
264
|
+
m1 = d.instance.metadata('my.data', t1, {"type" => "a"})
|
265
|
+
m2 = d.instance.metadata('your.data', t3, {"type" => "a"})
|
266
|
+
|
267
|
+
assert_equal 2, d.instance.buffer.stage.size
|
268
|
+
b1_path = d.instance.buffer.stage[m1].path
|
269
|
+
b1_size = File.lstat(b1_path).size
|
270
|
+
|
271
|
+
unless Fluent.windows?
|
272
|
+
assert File.symlink?("#{TMP_DIR}/full.current.log")
|
273
|
+
assert_equal d.instance.buffer.stage[m2].path, File.readlink("#{TMP_DIR}/full.current.log")
|
274
|
+
end
|
275
|
+
|
276
|
+
Timecop.freeze(Time.parse("2016-10-04 00:00:06 UTC"))
|
277
|
+
|
278
|
+
d.run(start: false, flush: true, shutdown: true) do
|
279
|
+
d.feed('my.data', t4, {"type" => "a", "message" => "data raw content"})
|
280
|
+
d.feed('your.data', t5, {"type" => "a", "message" => "data raw content"})
|
281
|
+
end
|
105
282
|
|
106
|
-
|
107
|
-
|
108
|
-
|
283
|
+
assert Dir.exist?("#{TMP_DIR}/buf_full")
|
284
|
+
assert Dir.exist?("#{TMP_DIR}/my.data/a")
|
285
|
+
assert Dir.exist?("#{TMP_DIR}/your.data/a")
|
286
|
+
|
287
|
+
buffer_files = Dir.entries("#{TMP_DIR}/buf_full").reject{|e| e =~ /^\.+$/ }
|
288
|
+
assert_equal 0, buffer_files.size
|
289
|
+
|
290
|
+
assert File.exist?("#{TMP_DIR}/my.data/a/full.20161003.2345.log.gz")
|
291
|
+
assert File.exist?("#{TMP_DIR}/my.data/a/full.20161004.0000.log.gz")
|
292
|
+
assert File.exist?("#{TMP_DIR}/your.data/a/full.20161003.2345.log.gz")
|
293
|
+
assert File.exist?("#{TMP_DIR}/your.data/a/full.20161004.0000.log.gz")
|
294
|
+
|
295
|
+
assert{ File.lstat("#{TMP_DIR}/my.data/a/full.20161003.2345.log.gz").size < b1_size } # recompress
|
296
|
+
|
297
|
+
assert_equal 5, d.formatted.size
|
298
|
+
|
299
|
+
r1 = %!2016-10-03 23:58:09 +0000,my.data,{"type":"a","message":"data raw content","hostname":"testing.local","tag":"my.data","time":"2016/10/04 08:58:09 +0900"}\n!
|
300
|
+
r2 = %!2016-10-03 23:59:33 +0000,my.data,{"type":"a","message":"data raw content","hostname":"testing.local","tag":"my.data","time":"2016/10/04 08:59:33 +0900"}\n!
|
301
|
+
r3 = %!2016-10-03 23:59:57 +0000,your.data,{"type":"a","message":"data raw content","hostname":"testing.local","tag":"your.data","time":"2016/10/04 08:59:57 +0900"}\n!
|
302
|
+
r4 = %!2016-10-04 00:00:17 +0000,my.data,{"type":"a","message":"data raw content","hostname":"testing.local","tag":"my.data","time":"2016/10/04 09:00:17 +0900"}\n!
|
303
|
+
r5 = %!2016-10-04 00:01:59 +0000,your.data,{"type":"a","message":"data raw content","hostname":"testing.local","tag":"your.data","time":"2016/10/04 09:01:59 +0900"}\n!
|
304
|
+
assert_equal r1, d.formatted[0]
|
305
|
+
assert_equal r2, d.formatted[1]
|
306
|
+
assert_equal r3, d.formatted[2]
|
307
|
+
assert_equal r4, d.formatted[3]
|
308
|
+
assert_equal r5, d.formatted[4]
|
309
|
+
|
310
|
+
read_gunzip = ->(path){
|
311
|
+
File.open(path){ |fio|
|
312
|
+
Zlib::GzipReader.new(StringIO.new(fio.read)).read
|
313
|
+
}
|
314
|
+
}
|
315
|
+
assert_equal r1 + r2, read_gunzip.call("#{TMP_DIR}/my.data/a/full.20161003.2345.log.gz")
|
316
|
+
assert_equal r3, read_gunzip.call("#{TMP_DIR}/your.data/a/full.20161003.2345.log.gz")
|
317
|
+
assert_equal r4, read_gunzip.call("#{TMP_DIR}/my.data/a/full.20161004.0000.log.gz")
|
318
|
+
assert_equal r5, read_gunzip.call("#{TMP_DIR}/your.data/a/full.20161004.0000.log.gz")
|
319
|
+
end
|
109
320
|
end
|
110
321
|
|
111
|
-
|
112
|
-
|
113
|
-
create_driver
|
322
|
+
sub_test_case 'format' do
|
323
|
+
test 'timezone UTC specified' do
|
324
|
+
d = create_driver
|
325
|
+
|
326
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
327
|
+
d.run(default_tag: 'test') do
|
328
|
+
d.feed(time, {"a"=>1})
|
329
|
+
d.feed(time, {"a"=>2})
|
330
|
+
end
|
331
|
+
assert_equal 2, d.formatted.size
|
332
|
+
assert_equal %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n], d.formatted[0]
|
333
|
+
assert_equal %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n], d.formatted[1]
|
334
|
+
end
|
335
|
+
|
336
|
+
test 'time formatted with specified timezone, using area name' do
|
337
|
+
d = create_driver %[
|
338
|
+
path #{TMP_DIR}/out_file_test
|
339
|
+
timezone Asia/Taipei
|
340
|
+
]
|
341
|
+
|
342
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
343
|
+
d.run(default_tag: 'test') do
|
344
|
+
d.feed(time, {"a"=>1})
|
345
|
+
end
|
346
|
+
assert_equal 1, d.formatted.size
|
347
|
+
assert_equal %[2011-01-02T21:14:15+08:00\ttest\t{"a":1}\n], d.formatted[0]
|
348
|
+
end
|
349
|
+
|
350
|
+
test 'time formatted with specified timezone, using offset' do
|
351
|
+
d = create_driver %[
|
114
352
|
path #{TMP_DIR}/out_file_test
|
115
|
-
timezone
|
353
|
+
timezone -03:30
|
116
354
|
]
|
355
|
+
|
356
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
357
|
+
d.run(default_tag: 'test') do
|
358
|
+
d.feed(time, {"a"=>1})
|
359
|
+
end
|
360
|
+
assert_equal 1, d.formatted.size
|
361
|
+
assert_equal %[2011-01-02T09:44:15-03:30\ttest\t{"a":1}\n], d.formatted[0]
|
362
|
+
end
|
363
|
+
|
364
|
+
test 'configuration error raised for invalid timezone' do
|
365
|
+
assert_raise(Fluent::ConfigError) do
|
366
|
+
create_driver %[
|
367
|
+
path #{TMP_DIR}/out_file_test
|
368
|
+
timezone Invalid/Invalid
|
369
|
+
]
|
370
|
+
end
|
117
371
|
end
|
118
372
|
end
|
119
373
|
|
@@ -121,9 +375,9 @@ class FileOutputTest < Test::Unit::TestCase
|
|
121
375
|
# Zlib::GzipReader has a bug of concatenated file: https://bugs.ruby-lang.org/issues/9790
|
122
376
|
# Following code from https://www.ruby-forum.com/topic/971591#979520
|
123
377
|
result = ''
|
124
|
-
File.open(path) { |io|
|
378
|
+
File.open(path, "rb") { |io|
|
125
379
|
loop do
|
126
|
-
gzr = Zlib::GzipReader.new(io)
|
380
|
+
gzr = Zlib::GzipReader.new(StringIO.new(io.read))
|
127
381
|
result << gzr.read
|
128
382
|
unused = gzr.unused
|
129
383
|
gzr.finish
|
@@ -135,89 +389,149 @@ class FileOutputTest < Test::Unit::TestCase
|
|
135
389
|
assert_equal expect, result
|
136
390
|
end
|
137
391
|
|
138
|
-
|
139
|
-
|
392
|
+
sub_test_case 'write' do
|
393
|
+
test 'basic case' do
|
394
|
+
d = create_driver
|
140
395
|
|
141
|
-
|
142
|
-
d.emit({"a"=>1}, time)
|
143
|
-
d.emit({"a"=>2}, time)
|
396
|
+
assert_false File.exist?("#{TMP_DIR}/out_file_test.20110102_0.log.gz")
|
144
397
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
398
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
399
|
+
d.run(default_tag: 'test') do
|
400
|
+
d.feed(time, {"a"=>1})
|
401
|
+
d.feed(time, {"a"=>2})
|
402
|
+
end
|
149
403
|
|
150
|
-
|
404
|
+
assert File.exist?("#{TMP_DIR}/out_file_test.20110102_0.log.gz")
|
405
|
+
check_gzipped_result("#{TMP_DIR}/out_file_test.20110102_0.log.gz", %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n] + %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n])
|
406
|
+
end
|
151
407
|
end
|
152
408
|
|
153
|
-
|
154
|
-
|
409
|
+
sub_test_case 'file/directory permissions' do
|
410
|
+
TMP_DIR_WITH_SYSTEM = File.expand_path(File.dirname(__FILE__) + "/../tmp/out_file_system#{ENV['TEST_ENV_NUMBER']}")
|
411
|
+
# 0750 interprets as "488". "488".to_i(8) # => 4. So, it makes wrong permission. Umm....
|
412
|
+
OVERRIDE_DIR_PERMISSION = 750
|
413
|
+
OVERRIDE_FILE_PERMISSION = 0620
|
414
|
+
CONFIG_WITH_SYSTEM = %[
|
415
|
+
path #{TMP_DIR_WITH_SYSTEM}/out_file_test
|
416
|
+
compress gz
|
417
|
+
utc
|
418
|
+
<buffer>
|
419
|
+
timekey_use_utc true
|
420
|
+
</buffer>
|
421
|
+
<system>
|
422
|
+
file_permission #{OVERRIDE_FILE_PERMISSION}
|
423
|
+
dir_permission #{OVERRIDE_DIR_PERMISSION}
|
424
|
+
</system>
|
425
|
+
]
|
426
|
+
|
427
|
+
setup do
|
428
|
+
omit "NTFS doesn't support UNIX like permissions" if Fluent.windows?
|
429
|
+
FileUtils.rm_rf(TMP_DIR_WITH_SYSTEM)
|
430
|
+
end
|
431
|
+
|
432
|
+
def parse_system(text)
|
433
|
+
basepath = File.expand_path(File.dirname(__FILE__) + '/../../')
|
434
|
+
Fluent::Config.parse(text, '(test)', basepath, true).elements.find { |e| e.name == 'system' }
|
435
|
+
end
|
155
436
|
|
156
|
-
|
157
|
-
|
158
|
-
|
437
|
+
test 'write to file with permission specifications' do
|
438
|
+
system_conf = parse_system(CONFIG_WITH_SYSTEM)
|
439
|
+
sc = Fluent::SystemConfig.new(system_conf)
|
440
|
+
Fluent::Engine.init(sc)
|
441
|
+
d = create_driver CONFIG_WITH_SYSTEM
|
159
442
|
|
160
|
-
|
161
|
-
paths = d.run
|
162
|
-
check_gzipped_result(paths[0], %[#{Yajl.dump({"a" => 1, 'time' => time})}\n] + %[#{Yajl.dump({"a" => 2, 'time' => time})}\n])
|
163
|
-
end
|
443
|
+
assert_false File.exist?("#{TMP_DIR_WITH_SYSTEM}/out_file_test.20110102_0.log.gz")
|
164
444
|
|
165
|
-
|
166
|
-
|
445
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
446
|
+
d.run(default_tag: 'test') do
|
447
|
+
d.feed(time, {"a"=>1})
|
448
|
+
d.feed(time, {"a"=>2})
|
449
|
+
end
|
167
450
|
|
168
|
-
|
169
|
-
d.emit({"a"=>1}, time)
|
170
|
-
d.emit({"a"=>2}, time)
|
451
|
+
assert File.exist?("#{TMP_DIR_WITH_SYSTEM}/out_file_test.20110102_0.log.gz")
|
171
452
|
|
172
|
-
|
173
|
-
|
174
|
-
|
453
|
+
check_gzipped_result("#{TMP_DIR_WITH_SYSTEM}/out_file_test.20110102_0.log.gz", %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n] + %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n])
|
454
|
+
dir_mode = "%o" % File::stat(TMP_DIR_WITH_SYSTEM).mode
|
455
|
+
assert_equal(OVERRIDE_DIR_PERMISSION, dir_mode[-3, 3].to_i)
|
456
|
+
file_mode = "%o" % File::stat("#{TMP_DIR_WITH_SYSTEM}/out_file_test.20110102_0.log.gz").mode
|
457
|
+
assert_equal(OVERRIDE_FILE_PERMISSION, file_mode[-3, 3].to_i)
|
458
|
+
end
|
175
459
|
end
|
176
460
|
|
177
|
-
|
178
|
-
|
461
|
+
sub_test_case 'format specified' do
|
462
|
+
test 'json' do
|
463
|
+
d = create_driver [CONFIG, 'format json', 'include_time_key true', 'time_as_epoch'].join("\n")
|
464
|
+
|
465
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
466
|
+
d.run(default_tag: 'test') do
|
467
|
+
d.feed(time, {"a"=>1})
|
468
|
+
d.feed(time, {"a"=>2})
|
469
|
+
end
|
470
|
+
|
471
|
+
path = d.instance.last_written_path
|
472
|
+
check_gzipped_result(path, %[#{Yajl.dump({"a" => 1, 'time' => time.to_i})}\n] + %[#{Yajl.dump({"a" => 2, 'time' => time.to_i})}\n])
|
473
|
+
end
|
474
|
+
|
475
|
+
test 'ltsv' do
|
476
|
+
d = create_driver [CONFIG, 'format ltsv', 'include_time_key true'].join("\n")
|
179
477
|
|
180
|
-
|
181
|
-
|
182
|
-
|
478
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
479
|
+
d.run(default_tag: 'test') do
|
480
|
+
d.feed(time, {"a"=>1})
|
481
|
+
d.feed(time, {"a"=>2})
|
482
|
+
end
|
483
|
+
|
484
|
+
path = d.instance.last_written_path
|
485
|
+
check_gzipped_result(path, %[a:1\ttime:2011-01-02T13:14:15Z\n] + %[a:2\ttime:2011-01-02T13:14:15Z\n])
|
486
|
+
end
|
487
|
+
|
488
|
+
test 'single_value' do
|
489
|
+
d = create_driver [CONFIG, 'format single_value', 'message_key a'].join("\n")
|
490
|
+
|
491
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
492
|
+
d.run(default_tag: 'test') do
|
493
|
+
d.feed(time, {"a"=>1})
|
494
|
+
d.feed(time, {"a"=>2})
|
495
|
+
end
|
183
496
|
|
184
|
-
|
185
|
-
|
186
|
-
|
497
|
+
path = d.instance.last_written_path
|
498
|
+
check_gzipped_result(path, %[1\n] + %[2\n])
|
499
|
+
end
|
187
500
|
end
|
188
501
|
|
189
|
-
|
190
|
-
time =
|
502
|
+
test 'path with index number' do
|
503
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
191
504
|
formatted_lines = %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n] + %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n]
|
192
505
|
|
193
506
|
write_once = ->(){
|
194
507
|
d = create_driver
|
195
|
-
d.
|
196
|
-
|
197
|
-
|
508
|
+
d.run(default_tag: 'test'){
|
509
|
+
d.feed(time, {"a"=>1})
|
510
|
+
d.feed(time, {"a"=>2})
|
511
|
+
}
|
512
|
+
d.instance.last_written_path
|
198
513
|
}
|
199
514
|
|
200
515
|
assert !File.exist?("#{TMP_DIR}/out_file_test.20110102_0.log.gz")
|
201
516
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
check_gzipped_result(paths[0], formatted_lines)
|
517
|
+
path = write_once.call
|
518
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102_0.log.gz", path
|
519
|
+
check_gzipped_result(path, formatted_lines)
|
206
520
|
assert_equal 1, Dir.glob("#{TMP_DIR}/out_file_test.*").size
|
207
521
|
|
208
|
-
|
209
|
-
assert_equal
|
210
|
-
check_gzipped_result(
|
522
|
+
path = write_once.call
|
523
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102_1.log.gz", path
|
524
|
+
check_gzipped_result(path, formatted_lines)
|
211
525
|
assert_equal 2, Dir.glob("#{TMP_DIR}/out_file_test.*").size
|
212
526
|
|
213
|
-
|
214
|
-
assert_equal
|
215
|
-
check_gzipped_result(
|
527
|
+
path = write_once.call
|
528
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102_2.log.gz", path
|
529
|
+
check_gzipped_result(path, formatted_lines)
|
216
530
|
assert_equal 3, Dir.glob("#{TMP_DIR}/out_file_test.*").size
|
217
531
|
end
|
218
532
|
|
219
|
-
|
220
|
-
time =
|
533
|
+
test 'append' do
|
534
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
221
535
|
formatted_lines = %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n] + %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n]
|
222
536
|
|
223
537
|
write_once = ->(){
|
@@ -226,50 +540,184 @@ class FileOutputTest < Test::Unit::TestCase
|
|
226
540
|
compress gz
|
227
541
|
utc
|
228
542
|
append true
|
543
|
+
<buffer>
|
544
|
+
timekey_use_utc true
|
545
|
+
</buffer>
|
229
546
|
]
|
230
|
-
d.
|
231
|
-
|
232
|
-
|
547
|
+
d.run(default_tag: 'test'){
|
548
|
+
d.feed(time, {"a"=>1})
|
549
|
+
d.feed(time, {"a"=>2})
|
550
|
+
}
|
551
|
+
d.instance.last_written_path
|
233
552
|
}
|
234
553
|
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
assert_equal
|
241
|
-
check_gzipped_result(
|
242
|
-
|
243
|
-
|
244
|
-
|
554
|
+
path = write_once.call
|
555
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102.log.gz", path
|
556
|
+
check_gzipped_result(path, formatted_lines)
|
557
|
+
|
558
|
+
path = write_once.call
|
559
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102.log.gz", path
|
560
|
+
check_gzipped_result(path, formatted_lines * 2)
|
561
|
+
|
562
|
+
path = write_once.call
|
563
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102.log.gz", path
|
564
|
+
check_gzipped_result(path, formatted_lines * 3)
|
245
565
|
end
|
246
566
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
567
|
+
test 'append when JST' do
|
568
|
+
with_timezone(Fluent.windows? ? "JST-9" : "Asia/Tokyo") do
|
569
|
+
time = event_time("2011-01-02 03:14:15+09:00")
|
570
|
+
formatted_lines = %[2011-01-02T03:14:15+09:00\ttest\t{"a":1}\n] + %[2011-01-02T03:14:15+09:00\ttest\t{"a":2}\n]
|
571
|
+
|
572
|
+
write_once = ->(){
|
573
|
+
d = create_driver %[
|
574
|
+
path #{TMP_DIR}/out_file_test
|
575
|
+
compress gz
|
576
|
+
append true
|
577
|
+
<buffer>
|
578
|
+
timekey_use_utc false
|
579
|
+
timekey_zone Asia/Tokyo
|
580
|
+
</buffer>
|
581
|
+
]
|
582
|
+
d.run(default_tag: 'test'){
|
583
|
+
d.feed(time, {"a"=>1})
|
584
|
+
d.feed(time, {"a"=>2})
|
585
|
+
}
|
586
|
+
d.instance.last_written_path
|
587
|
+
}
|
588
|
+
|
589
|
+
path = write_once.call
|
590
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102.log.gz", path
|
591
|
+
check_gzipped_result(path, formatted_lines)
|
592
|
+
|
593
|
+
path = write_once.call
|
594
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102.log.gz", path
|
595
|
+
check_gzipped_result(path, formatted_lines * 2)
|
596
|
+
|
597
|
+
path = write_once.call
|
598
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102.log.gz", path
|
599
|
+
check_gzipped_result(path, formatted_lines * 3)
|
600
|
+
end
|
601
|
+
end
|
252
602
|
|
253
|
-
|
254
|
-
|
603
|
+
test 'append when UTC-02 but timekey_zone is +0900' do
|
604
|
+
with_timezone("UTC-02") do # +0200
|
605
|
+
time = event_time("2011-01-02 17:14:15+02:00")
|
606
|
+
formatted_lines = %[2011-01-02T17:14:15+02:00\ttest\t{"a":1}\n] + %[2011-01-02T17:14:15+02:00\ttest\t{"a":2}\n]
|
607
|
+
|
608
|
+
write_once = ->(){
|
609
|
+
d = create_driver %[
|
610
|
+
path #{TMP_DIR}/out_file_test
|
611
|
+
compress gz
|
612
|
+
append true
|
613
|
+
<buffer>
|
614
|
+
timekey_use_utc false
|
615
|
+
timekey_zone +0900
|
616
|
+
</buffer>
|
617
|
+
]
|
618
|
+
d.run(default_tag: 'test'){
|
619
|
+
d.feed(time, {"a"=>1})
|
620
|
+
d.feed(time, {"a"=>2})
|
621
|
+
}
|
622
|
+
d.instance.last_written_path
|
623
|
+
}
|
624
|
+
|
625
|
+
path = write_once.call
|
626
|
+
# Rotated at 2011-01-02 17:00:00+02:00
|
627
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110103.log.gz", path
|
628
|
+
check_gzipped_result(path, formatted_lines)
|
629
|
+
|
630
|
+
path = write_once.call
|
631
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110103.log.gz", path
|
632
|
+
check_gzipped_result(path, formatted_lines * 2)
|
633
|
+
|
634
|
+
path = write_once.call
|
635
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110103.log.gz", path
|
636
|
+
check_gzipped_result(path, formatted_lines * 3)
|
637
|
+
end
|
638
|
+
end
|
255
639
|
|
256
|
-
|
257
|
-
|
258
|
-
10.times { sleep 0.05 }
|
259
|
-
time = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
260
|
-
es = Fluent::OneEventStream.new(time, {"a"=>1})
|
261
|
-
d.instance.emit('tag', es, Fluent::NullOutputChain.instance)
|
640
|
+
test '${chunk_id}' do
|
641
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
262
642
|
|
263
|
-
|
264
|
-
|
643
|
+
write_once = ->(){
|
644
|
+
d = create_driver %[
|
645
|
+
path #{TMP_DIR}/out_file_chunk_id_${chunk_id}
|
646
|
+
utc
|
647
|
+
append true
|
648
|
+
<buffer>
|
649
|
+
timekey_use_utc true
|
650
|
+
</buffer>
|
651
|
+
]
|
652
|
+
d.run(default_tag: 'test'){
|
653
|
+
d.feed(time, {"a"=>1})
|
654
|
+
d.feed(time, {"a"=>2})
|
655
|
+
}
|
656
|
+
d.instance.last_written_path
|
657
|
+
}
|
658
|
+
|
659
|
+
path = write_once.call
|
660
|
+
if File.basename(path) =~ /out_file_chunk_id_([-_.@a-zA-Z0-9].*).20110102.log/
|
661
|
+
unique_id = Fluent::UniqueId.hex(Fluent::UniqueId.generate)
|
662
|
+
assert_equal unique_id.size, $1.size, "chunk_id size is mismatched"
|
663
|
+
else
|
664
|
+
flunk "chunk_id is not included in the path"
|
665
|
+
end
|
666
|
+
end
|
265
667
|
|
266
|
-
|
668
|
+
SYMLINK_PATH = File.expand_path("#{TMP_DIR}/current")
|
267
669
|
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
670
|
+
sub_test_case 'symlink' do
|
671
|
+
test 'static symlink' do
|
672
|
+
omit "Windows doesn't support symlink" if Fluent.windows?
|
673
|
+
conf = CONFIG + %[
|
674
|
+
symlink_path #{SYMLINK_PATH}
|
675
|
+
]
|
676
|
+
symlink_path = "#{SYMLINK_PATH}"
|
677
|
+
|
678
|
+
d = create_driver(conf)
|
679
|
+
begin
|
680
|
+
run_and_check(d, symlink_path)
|
681
|
+
ensure
|
682
|
+
FileUtils.rm_rf(symlink_path)
|
683
|
+
end
|
684
|
+
end
|
685
|
+
|
686
|
+
test 'symlink with placeholders' do
|
687
|
+
omit "Windows doesn't support symlink" if Fluent.windows?
|
688
|
+
conf = %[
|
689
|
+
path #{TMP_DIR}/${tag}/out_file_test
|
690
|
+
symlink_path #{SYMLINK_PATH}/foo/${tag}
|
691
|
+
<buffer tag,time>
|
692
|
+
</buffer>
|
693
|
+
]
|
694
|
+
symlink_path = "#{SYMLINK_PATH}/foo/tag"
|
695
|
+
|
696
|
+
d = create_driver(conf)
|
697
|
+
begin
|
698
|
+
run_and_check(d, symlink_path)
|
699
|
+
ensure
|
700
|
+
FileUtils.rm_rf(symlink_path)
|
701
|
+
end
|
702
|
+
end
|
703
|
+
|
704
|
+
def run_and_check(d, symlink_path)
|
705
|
+
d.run(default_tag: 'tag') do
|
706
|
+
es = Fluent::OneEventStream.new(event_time("2011-01-02 13:14:15 UTC"), {"a"=>1})
|
707
|
+
d.feed(es)
|
708
|
+
|
709
|
+
assert File.symlink?(symlink_path)
|
710
|
+
assert File.exist?(symlink_path) # This checks dest of symlink exists or not.
|
711
|
+
|
712
|
+
es = Fluent::OneEventStream.new(event_time("2011-01-03 14:15:16 UTC"), {"a"=>2})
|
713
|
+
d.feed(es)
|
714
|
+
|
715
|
+
assert File.symlink?(symlink_path)
|
716
|
+
assert File.exist?(symlink_path)
|
717
|
+
|
718
|
+
meta = d.instance.metadata('tag', event_time("2011-01-03 14:15:16 UTC"), {})
|
719
|
+
assert_equal d.instance.buffer.instance_eval{ @stage[meta].path }, File.readlink(symlink_path)
|
720
|
+
end
|
273
721
|
end
|
274
722
|
end
|
275
723
|
|
@@ -280,11 +728,12 @@ class FileOutputTest < Test::Unit::TestCase
|
|
280
728
|
time_slice_format %Y-%m-%d-%H
|
281
729
|
utc true
|
282
730
|
])
|
283
|
-
time =
|
284
|
-
d.
|
285
|
-
|
286
|
-
|
287
|
-
|
731
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
732
|
+
d.run(default_tag: 'test') do
|
733
|
+
d.feed(time, {"a"=>1})
|
734
|
+
end
|
735
|
+
path = d.instance.last_written_path
|
736
|
+
assert_equal "#{TMP_DIR}/out_file_test.2011-01-02-13_0.log", path
|
288
737
|
end
|
289
738
|
|
290
739
|
test 'normal with append' do
|
@@ -294,22 +743,26 @@ class FileOutputTest < Test::Unit::TestCase
|
|
294
743
|
utc true
|
295
744
|
append true
|
296
745
|
])
|
297
|
-
time =
|
298
|
-
d.
|
299
|
-
|
300
|
-
|
301
|
-
|
746
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
747
|
+
d.run(default_tag: 'test') do
|
748
|
+
d.feed(time, {"a"=>1})
|
749
|
+
end
|
750
|
+
path = d.instance.last_written_path
|
751
|
+
assert_equal "#{TMP_DIR}/out_file_test.2011-01-02-13.log", path
|
752
|
+
end
|
302
753
|
|
303
|
-
|
754
|
+
test '*' do
|
304
755
|
d = create_driver(%[
|
305
756
|
path #{TMP_DIR}/out_file_test.*.txt
|
306
757
|
time_slice_format %Y-%m-%d-%H
|
307
758
|
utc true
|
308
759
|
])
|
309
|
-
time =
|
310
|
-
d.
|
311
|
-
|
312
|
-
|
760
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
761
|
+
d.run(default_tag: 'test') do
|
762
|
+
d.feed(time, {"a"=>1})
|
763
|
+
end
|
764
|
+
path = d.instance.last_written_path
|
765
|
+
assert_equal "#{TMP_DIR}/out_file_test.2011-01-02-13_0.txt", path
|
313
766
|
end
|
314
767
|
|
315
768
|
test '* with append' do
|
@@ -319,11 +772,245 @@ class FileOutputTest < Test::Unit::TestCase
|
|
319
772
|
utc true
|
320
773
|
append true
|
321
774
|
])
|
322
|
-
time =
|
323
|
-
d.
|
324
|
-
|
325
|
-
|
775
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
776
|
+
d.run(default_tag: 'test') do
|
777
|
+
d.feed(time, {"a"=>1})
|
778
|
+
end
|
779
|
+
path = d.instance.last_written_path
|
780
|
+
assert_equal "#{TMP_DIR}/out_file_test.2011-01-02-13.txt", path
|
326
781
|
end
|
327
782
|
end
|
328
|
-
end
|
329
783
|
|
784
|
+
sub_test_case '#timekey_to_timeformat' do
|
785
|
+
setup do
|
786
|
+
@d = create_driver
|
787
|
+
@i = @d.instance
|
788
|
+
end
|
789
|
+
|
790
|
+
test 'returns empty string for nil' do
|
791
|
+
assert_equal '', @i.timekey_to_timeformat(nil)
|
792
|
+
end
|
793
|
+
|
794
|
+
test 'returns timestamp string with seconds for timekey smaller than 60' do
|
795
|
+
assert_equal '%Y%m%d%H%M%S', @i.timekey_to_timeformat(1)
|
796
|
+
assert_equal '%Y%m%d%H%M%S', @i.timekey_to_timeformat(30)
|
797
|
+
assert_equal '%Y%m%d%H%M%S', @i.timekey_to_timeformat(59)
|
798
|
+
end
|
799
|
+
|
800
|
+
test 'returns timestamp string with minutes for timekey smaller than 3600' do
|
801
|
+
assert_equal '%Y%m%d%H%M', @i.timekey_to_timeformat(60)
|
802
|
+
assert_equal '%Y%m%d%H%M', @i.timekey_to_timeformat(180)
|
803
|
+
assert_equal '%Y%m%d%H%M', @i.timekey_to_timeformat(1800)
|
804
|
+
assert_equal '%Y%m%d%H%M', @i.timekey_to_timeformat(3599)
|
805
|
+
end
|
806
|
+
|
807
|
+
test 'returns timestamp string with hours for timekey smaller than 86400 (1 day)' do
|
808
|
+
assert_equal '%Y%m%d%H', @i.timekey_to_timeformat(3600)
|
809
|
+
assert_equal '%Y%m%d%H', @i.timekey_to_timeformat(7200)
|
810
|
+
assert_equal '%Y%m%d%H', @i.timekey_to_timeformat(86399)
|
811
|
+
end
|
812
|
+
|
813
|
+
test 'returns timestamp string with days for timekey equal or greater than 86400' do
|
814
|
+
assert_equal '%Y%m%d', @i.timekey_to_timeformat(86400)
|
815
|
+
assert_equal '%Y%m%d', @i.timekey_to_timeformat(1000000)
|
816
|
+
assert_equal '%Y%m%d', @i.timekey_to_timeformat(1000000000)
|
817
|
+
end
|
818
|
+
end
|
819
|
+
|
820
|
+
sub_test_case '#compression_suffix' do
|
821
|
+
setup do
|
822
|
+
@i = create_driver.instance
|
823
|
+
end
|
824
|
+
|
825
|
+
test 'returns empty string for nil (no compression method specified)' do
|
826
|
+
assert_equal '', @i.compression_suffix(nil)
|
827
|
+
end
|
828
|
+
|
829
|
+
test 'returns .gz for gzip' do
|
830
|
+
assert_equal '.gz', @i.compression_suffix(:gzip)
|
831
|
+
end
|
832
|
+
end
|
833
|
+
|
834
|
+
sub_test_case '#generate_path_template' do
|
835
|
+
setup do
|
836
|
+
@i = create_driver.instance
|
837
|
+
end
|
838
|
+
|
839
|
+
data(
|
840
|
+
'day' => [86400, '%Y%m%d', '%Y-%m-%d'],
|
841
|
+
'hour' => [3600, '%Y%m%d%H', '%Y-%m-%d_%H'],
|
842
|
+
'minute' => [60, '%Y%m%d%H%M', '%Y-%m-%d_%H%M'],
|
843
|
+
)
|
844
|
+
test 'generates path with timestamp placeholder for original path with tailing star with timekey' do |data|
|
845
|
+
timekey, placeholder, time_slice_format = data
|
846
|
+
# with index placeholder, without compression suffix when append disabled and compression disabled
|
847
|
+
assert_equal "/path/to/file.#{placeholder}_**", @i.generate_path_template('/path/to/file.*', timekey, false, nil)
|
848
|
+
# with index placeholder, with .gz suffix when append disabled and gzip compression enabled
|
849
|
+
assert_equal "/path/to/file.#{placeholder}_**.gz", @i.generate_path_template('/path/to/file.*', timekey, false, :gzip)
|
850
|
+
# without index placeholder, without compression suffix when append enabled and compression disabled
|
851
|
+
assert_equal "/path/to/file.#{placeholder}", @i.generate_path_template('/path/to/file.*', timekey, true, nil)
|
852
|
+
# without index placeholder, with .gz suffix when append disabled and gzip compression enabled
|
853
|
+
assert_equal "/path/to/file.#{placeholder}.gz", @i.generate_path_template('/path/to/file.*', timekey, true, :gzip)
|
854
|
+
|
855
|
+
# time_slice_format will used instead of computed placeholder if specified
|
856
|
+
assert_equal "/path/to/file.#{time_slice_format}_**", @i.generate_path_template('/path/to/file.*', timekey, false, nil, time_slice_format: time_slice_format)
|
857
|
+
assert_equal "/path/to/file.#{time_slice_format}_**.gz", @i.generate_path_template('/path/to/file.*', timekey, false, :gzip, time_slice_format: time_slice_format)
|
858
|
+
assert_equal "/path/to/file.#{time_slice_format}", @i.generate_path_template('/path/to/file.*', timekey, true, nil, time_slice_format: time_slice_format)
|
859
|
+
assert_equal "/path/to/file.#{time_slice_format}.gz", @i.generate_path_template('/path/to/file.*', timekey, true, :gzip, time_slice_format: time_slice_format)
|
860
|
+
end
|
861
|
+
|
862
|
+
data(
|
863
|
+
'day' => [86400 * 2, '%Y%m%d', '%Y-%m-%d'],
|
864
|
+
'hour' => [7200, '%Y%m%d%H', '%Y-%m-%d_%H'],
|
865
|
+
'minute' => [180, '%Y%m%d%H%M', '%Y-%m-%d_%H%M'],
|
866
|
+
)
|
867
|
+
test 'generates path with timestamp placeholder for original path with star and suffix with timekey' do |data|
|
868
|
+
timekey, placeholder, time_slice_format = data
|
869
|
+
# with index placeholder, without compression suffix when append disabled and compression disabled
|
870
|
+
assert_equal "/path/to/file.#{placeholder}_**.data", @i.generate_path_template('/path/to/file.*.data', timekey, false, nil)
|
871
|
+
# with index placeholder, with .gz suffix when append disabled and gzip compression enabled
|
872
|
+
assert_equal "/path/to/file.#{placeholder}_**.data.gz", @i.generate_path_template('/path/to/file.*.data', timekey, false, :gzip)
|
873
|
+
# without index placeholder, without compression suffix when append enabled and compression disabled
|
874
|
+
assert_equal "/path/to/file.#{placeholder}.data", @i.generate_path_template('/path/to/file.*.data', timekey, true, nil)
|
875
|
+
# without index placeholder, with .gz suffix when append disabled and gzip compression enabled
|
876
|
+
assert_equal "/path/to/file.#{placeholder}.data.gz", @i.generate_path_template('/path/to/file.*.data', timekey, true, :gzip)
|
877
|
+
|
878
|
+
# time_slice_format will used instead of computed placeholder if specified
|
879
|
+
assert_equal "/path/to/file.#{time_slice_format}_**.data", @i.generate_path_template('/path/to/file.*.data', timekey, false, nil, time_slice_format: time_slice_format)
|
880
|
+
assert_equal "/path/to/file.#{time_slice_format}_**.data.gz", @i.generate_path_template('/path/to/file.*.data', timekey, false, :gzip, time_slice_format: time_slice_format)
|
881
|
+
assert_equal "/path/to/file.#{time_slice_format}.data", @i.generate_path_template('/path/to/file.*.data', timekey, true, nil, time_slice_format: time_slice_format)
|
882
|
+
assert_equal "/path/to/file.#{time_slice_format}.data.gz", @i.generate_path_template('/path/to/file.*.data', timekey, true, :gzip, time_slice_format: time_slice_format)
|
883
|
+
end
|
884
|
+
|
885
|
+
test 'raise error to show it is a bug when path including * specified without timekey' do
|
886
|
+
assert_raise RuntimeError.new("BUG: configuration error must be raised for path including '*' without timekey") do
|
887
|
+
@i.generate_path_template('/path/to/file.*.log', nil, false, nil)
|
888
|
+
end
|
889
|
+
end
|
890
|
+
|
891
|
+
data(
|
892
|
+
'day' => [86400 * 7, '%Y%m%d', '%Y-%m-%d'],
|
893
|
+
'hour' => [3600 * 6, '%Y%m%d%H', '%Y-%m-%d_%H'],
|
894
|
+
'minute' => [60 * 15, '%Y%m%d%H%M', '%Y-%m-%d_%H%M'],
|
895
|
+
)
|
896
|
+
test 'generates path with timestamp placeholder for original path without time placeholders & star with timekey, and path_suffix configured' do |data|
|
897
|
+
timekey, placeholder, time_slice_format = data
|
898
|
+
# with index placeholder, without compression suffix when append disabled and compression disabled
|
899
|
+
assert_equal "/path/to/file.#{placeholder}_**.log", @i.generate_path_template('/path/to/file', timekey, false, nil, path_suffix: '.log')
|
900
|
+
# with index placeholder, with .gz suffix when append disabled and gzip compression enabled
|
901
|
+
assert_equal "/path/to/file.#{placeholder}_**.log.gz", @i.generate_path_template('/path/to/file', timekey, false, :gzip, path_suffix: '.log')
|
902
|
+
# without index placeholder, without compression suffix when append enabled and compression disabled
|
903
|
+
assert_equal "/path/to/file.#{placeholder}.log", @i.generate_path_template('/path/to/file', timekey, true, nil, path_suffix: '.log')
|
904
|
+
# without index placeholder, with compression suffix when append enabled and gzip compression enabled
|
905
|
+
assert_equal "/path/to/file.#{placeholder}.log.gz", @i.generate_path_template('/path/to/file', timekey, true, :gzip, path_suffix: '.log')
|
906
|
+
|
907
|
+
# time_slice_format will be appended always if it's specified
|
908
|
+
assert_equal "/path/to/file.#{time_slice_format}_**.log", @i.generate_path_template('/path/to/file', timekey, false, nil, path_suffix: '.log', time_slice_format: time_slice_format)
|
909
|
+
assert_equal "/path/to/file.#{time_slice_format}_**.log.gz", @i.generate_path_template('/path/to/file', timekey, false, :gzip, path_suffix: '.log', time_slice_format: time_slice_format)
|
910
|
+
assert_equal "/path/to/file.#{time_slice_format}.log", @i.generate_path_template('/path/to/file', timekey, true, nil, path_suffix: '.log', time_slice_format: time_slice_format)
|
911
|
+
assert_equal "/path/to/file.#{time_slice_format}.log.gz", @i.generate_path_template('/path/to/file', timekey, true, :gzip, path_suffix: '.log', time_slice_format: time_slice_format)
|
912
|
+
end
|
913
|
+
|
914
|
+
data(
|
915
|
+
'day' => [86400, '%Y%m%d'],
|
916
|
+
'hour' => [3600, '%Y%m%d%H'],
|
917
|
+
'minute' => [60, '%Y%m%d%H%M'],
|
918
|
+
)
|
919
|
+
test 'generates path with timestamp placeholder for original path without star with timekey, and path_suffix not configured' do |data|
|
920
|
+
timekey, placeholder = data
|
921
|
+
# with index placeholder, without compression suffix when append disabled and compression disabled
|
922
|
+
assert_equal "/path/to/file.#{placeholder}_**", @i.generate_path_template('/path/to/file', timekey, false, nil)
|
923
|
+
# with index placeholder, with .gz suffix when append disabled and gzip compression enabled
|
924
|
+
assert_equal "/path/to/file.#{placeholder}_**.gz", @i.generate_path_template('/path/to/file', timekey, false, :gzip)
|
925
|
+
# without index placeholder, without compression suffix when append enabled and compression disabled
|
926
|
+
assert_equal "/path/to/file.#{placeholder}", @i.generate_path_template('/path/to/file', timekey, true, nil)
|
927
|
+
# without index placeholder, with compression suffix when append enabled and gzip compression enabled
|
928
|
+
assert_equal "/path/to/file.#{placeholder}.gz", @i.generate_path_template('/path/to/file', timekey, true, :gzip)
|
929
|
+
end
|
930
|
+
|
931
|
+
test 'generates path without adding timestamp placeholder part if original path has enough placeholders for specified timekey' do
|
932
|
+
assert_equal "/path/to/file.%Y%m%d", @i.generate_path_template('/path/to/file.%Y%m%d', 86400, true, nil)
|
933
|
+
assert_equal "/path/to/%Y%m%d/file", @i.generate_path_template('/path/to/%Y%m%d/file', 86400, true, nil)
|
934
|
+
|
935
|
+
assert_equal "/path/to/%Y%m%d/file_**", @i.generate_path_template('/path/to/%Y%m%d/file', 86400, false, nil)
|
936
|
+
|
937
|
+
assert_raise Fluent::ConfigError.new("insufficient timestamp placeholders in path") do
|
938
|
+
@i.generate_path_template('/path/to/%Y%m/file', 86400, true, nil)
|
939
|
+
end
|
940
|
+
assert_raise Fluent::ConfigError.new("insufficient timestamp placeholders in path") do
|
941
|
+
@i.generate_path_template('/path/to/file.%Y%m%d.log', 3600, true, nil)
|
942
|
+
end
|
943
|
+
|
944
|
+
assert_equal "/path/to/file.%Y%m%d_%H_**.log.gz", @i.generate_path_template('/path/to/file.%Y%m%d_%H', 7200, false, :gzip, path_suffix: '.log')
|
945
|
+
assert_equal "/path/to/${tag}/file.%Y%m%d_%H_**.log.gz", @i.generate_path_template('/path/to/${tag}/file.%Y%m%d_%H', 7200, false, :gzip, path_suffix: '.log')
|
946
|
+
end
|
947
|
+
|
948
|
+
test 'generates path with specified time_slice_format appended even if path has sufficient timestamp placeholders' do
|
949
|
+
assert_equal "/path/to/%Y%m%d/file.%Y-%m-%d_%H_**", @i.generate_path_template('/path/to/%Y%m%d/file', 86400, false, nil, time_slice_format: '%Y-%m-%d_%H')
|
950
|
+
assert_equal "/path/to/%Y%m%d/file.%Y-%m-%d_%H", @i.generate_path_template('/path/to/%Y%m%d/file', 86400, true, nil, time_slice_format: '%Y-%m-%d_%H')
|
951
|
+
assert_equal "/path/to/%Y%m%d/file.%Y-%m-%d_%H_**.log", @i.generate_path_template('/path/to/%Y%m%d/file', 86400, false, nil, time_slice_format: '%Y-%m-%d_%H', path_suffix: '.log')
|
952
|
+
assert_equal "/path/to/%Y%m%d/file.%Y-%m-%d_%H.log", @i.generate_path_template('/path/to/%Y%m%d/file', 86400, true, nil, time_slice_format: '%Y-%m-%d_%H', path_suffix: '.log')
|
953
|
+
assert_equal "/path/to/%Y%m%d/file.%Y-%m-%d_%H.log.gz", @i.generate_path_template('/path/to/%Y%m%d/file', 86400, true, :gzip, time_slice_format: '%Y-%m-%d_%H', path_suffix: '.log')
|
954
|
+
end
|
955
|
+
|
956
|
+
test 'generates path without timestamp placeholder when path does not include * and timekey not specified' do
|
957
|
+
assert_equal '/path/to/file.log', @i.generate_path_template('/path/to/file.log', nil, true, nil)
|
958
|
+
assert_equal '/path/to/file.log_**', @i.generate_path_template('/path/to/file.log', nil, false, nil)
|
959
|
+
assert_equal '/path/to/file.${tag}.log_**', @i.generate_path_template('/path/to/file.${tag}.log', nil, false, nil)
|
960
|
+
assert_equal '/path/to/file.${tag}_**.log', @i.generate_path_template('/path/to/file.${tag}', nil, false, nil, path_suffix: '.log')
|
961
|
+
end
|
962
|
+
end
|
963
|
+
|
964
|
+
sub_test_case '#find_filepath_available' do
|
965
|
+
setup do
|
966
|
+
@tmp = File.join(TMP_DIR, 'find_filepath_test')
|
967
|
+
FileUtils.mkdir_p @tmp
|
968
|
+
@i = create_driver.instance
|
969
|
+
end
|
970
|
+
|
971
|
+
teardown do
|
972
|
+
FileUtils.rm_rf @tmp
|
973
|
+
end
|
974
|
+
|
975
|
+
test 'raise error if argument path does not include index placeholder' do
|
976
|
+
assert_raise RuntimeError.new("BUG: index placeholder not found in path: #{@tmp}/myfile") do
|
977
|
+
@i.find_filepath_available("#{@tmp}/myfile") do |path|
|
978
|
+
# ...
|
979
|
+
end
|
980
|
+
end
|
981
|
+
end
|
982
|
+
|
983
|
+
data(
|
984
|
+
'without suffix' => ['myfile_0', 'myfile_**'],
|
985
|
+
'with timestamp' => ['myfile_20161003_0', 'myfile_20161003_**'],
|
986
|
+
'with base suffix' => ['myfile_0.log', 'myfile_**.log'],
|
987
|
+
'with compression suffix' => ['myfile_0.log.gz', 'myfile_**.log.gz'],
|
988
|
+
)
|
989
|
+
test 'returns filepath with _0 at first' do |data|
|
990
|
+
expected, argument = data
|
991
|
+
@i.find_filepath_available(File.join(@tmp, argument)) do |path|
|
992
|
+
assert_equal File.join(@tmp, expected), path
|
993
|
+
end
|
994
|
+
end
|
995
|
+
|
996
|
+
test 'returns filepath with index which does not exist yet' do
|
997
|
+
5.times do |i|
|
998
|
+
File.open(File.join(@tmp, "exist_#{i}.log"), 'a'){|f| } # open(create) and close
|
999
|
+
end
|
1000
|
+
@i.find_filepath_available(File.join(@tmp, "exist_**.log")) do |path|
|
1001
|
+
assert_equal File.join(@tmp, "exist_5.log"), path
|
1002
|
+
end
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
test 'creates lock directory when with_lock is true to exclude operations of other worker process' do
|
1006
|
+
5.times do |i|
|
1007
|
+
File.open(File.join(@tmp, "exist_#{i}.log"), 'a')
|
1008
|
+
end
|
1009
|
+
Dir.mkdir(File.join(@tmp, "exist_5.log.lock"))
|
1010
|
+
@i.find_filepath_available(File.join(@tmp, "exist_**.log"), with_lock: true) do |path|
|
1011
|
+
assert Dir.exist?(File.join(@tmp, "exist_6.log.lock"))
|
1012
|
+
assert_equal File.join(@tmp, "exist_6.log"), path
|
1013
|
+
end
|
1014
|
+
end
|
1015
|
+
end
|
1016
|
+
end
|