fluentd 0.12.43 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of fluentd might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE.md +6 -0
- data/.gitignore +2 -0
- data/.travis.yml +33 -21
- data/CONTRIBUTING.md +1 -0
- data/ChangeLog +1239 -0
- data/README.md +0 -25
- data/Rakefile +2 -1
- data/Vagrantfile +17 -0
- data/appveyor.yml +35 -0
- data/example/filter_stdout.conf +5 -5
- data/example/in_forward.conf +2 -2
- data/example/in_http.conf +2 -2
- data/example/in_out_forward.conf +17 -0
- data/example/in_syslog.conf +2 -2
- data/example/in_tail.conf +2 -2
- data/example/in_tcp.conf +2 -2
- data/example/in_udp.conf +2 -2
- data/example/out_copy.conf +4 -4
- data/example/out_file.conf +2 -2
- data/example/out_forward.conf +2 -2
- data/example/out_forward_buf_file.conf +23 -0
- data/example/v0_12_filter.conf +8 -8
- data/fluent.conf +29 -0
- data/fluentd.gemspec +18 -11
- data/lib/fluent/agent.rb +60 -58
- data/lib/fluent/command/cat.rb +1 -1
- data/lib/fluent/command/debug.rb +7 -5
- data/lib/fluent/command/fluentd.rb +97 -2
- data/lib/fluent/compat/call_super_mixin.rb +67 -0
- data/lib/fluent/compat/filter.rb +50 -0
- data/lib/fluent/compat/formatter.rb +109 -0
- data/lib/fluent/compat/input.rb +50 -0
- data/lib/fluent/compat/output.rb +617 -0
- data/lib/fluent/compat/output_chain.rb +60 -0
- data/lib/fluent/compat/parser.rb +163 -0
- data/lib/fluent/compat/propagate_default.rb +62 -0
- data/lib/fluent/config.rb +23 -20
- data/lib/fluent/config/configure_proxy.rb +119 -70
- data/lib/fluent/config/dsl.rb +5 -18
- data/lib/fluent/config/element.rb +72 -8
- data/lib/fluent/config/error.rb +0 -3
- data/lib/fluent/config/literal_parser.rb +0 -2
- data/lib/fluent/config/parser.rb +4 -4
- data/lib/fluent/config/section.rb +39 -28
- data/lib/fluent/config/types.rb +2 -13
- data/lib/fluent/config/v1_parser.rb +1 -3
- data/lib/fluent/configurable.rb +48 -16
- data/lib/fluent/daemon.rb +15 -0
- data/lib/fluent/engine.rb +26 -52
- data/lib/fluent/env.rb +6 -4
- data/lib/fluent/event.rb +58 -11
- data/lib/fluent/event_router.rb +5 -5
- 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 +2 -2
- data/lib/fluent/load.rb +3 -2
- data/lib/fluent/log.rb +107 -38
- data/lib/fluent/match.rb +0 -36
- data/lib/fluent/mixin.rb +117 -7
- data/lib/fluent/msgpack_factory.rb +62 -0
- data/lib/fluent/output.rb +7 -612
- data/lib/fluent/output_chain.rb +23 -0
- data/lib/fluent/parser.rb +4 -800
- data/lib/fluent/plugin.rb +100 -121
- data/lib/fluent/plugin/bare_output.rb +63 -0
- data/lib/fluent/plugin/base.rb +121 -0
- data/lib/fluent/plugin/buf_file.rb +101 -182
- data/lib/fluent/plugin/buf_memory.rb +9 -92
- data/lib/fluent/plugin/buffer.rb +473 -0
- data/lib/fluent/plugin/buffer/chunk.rb +135 -0
- data/lib/fluent/plugin/buffer/file_chunk.rb +339 -0
- data/lib/fluent/plugin/buffer/memory_chunk.rb +100 -0
- data/lib/fluent/plugin/exec_util.rb +80 -75
- data/lib/fluent/plugin/file_util.rb +33 -28
- data/lib/fluent/plugin/file_wrapper.rb +120 -0
- data/lib/fluent/plugin/filter.rb +51 -0
- data/lib/fluent/plugin/filter_grep.rb +13 -40
- data/lib/fluent/plugin/filter_record_transformer.rb +22 -18
- data/lib/fluent/plugin/formatter.rb +93 -0
- data/lib/fluent/plugin/formatter_csv.rb +48 -0
- data/lib/fluent/plugin/formatter_hash.rb +32 -0
- data/lib/fluent/plugin/formatter_json.rb +47 -0
- data/lib/fluent/plugin/formatter_ltsv.rb +42 -0
- data/lib/fluent/plugin/formatter_msgpack.rb +32 -0
- data/lib/fluent/plugin/formatter_out_file.rb +45 -0
- data/lib/fluent/plugin/formatter_single_value.rb +34 -0
- data/lib/fluent/plugin/formatter_stdout.rb +39 -0
- data/lib/fluent/plugin/in_debug_agent.rb +4 -0
- data/lib/fluent/plugin/in_dummy.rb +22 -18
- data/lib/fluent/plugin/in_exec.rb +18 -8
- data/lib/fluent/plugin/in_forward.rb +36 -79
- data/lib/fluent/plugin/in_gc_stat.rb +4 -0
- data/lib/fluent/plugin/in_http.rb +21 -18
- data/lib/fluent/plugin/in_monitor_agent.rb +15 -48
- data/lib/fluent/plugin/in_object_space.rb +6 -1
- data/lib/fluent/plugin/in_stream.rb +7 -3
- data/lib/fluent/plugin/in_syslog.rb +46 -95
- data/lib/fluent/plugin/in_tail.rb +58 -640
- data/lib/fluent/plugin/in_tcp.rb +8 -1
- data/lib/fluent/plugin/in_udp.rb +8 -18
- data/lib/fluent/plugin/input.rb +33 -0
- data/lib/fluent/plugin/multi_output.rb +95 -0
- data/lib/fluent/plugin/out_buffered_null.rb +59 -0
- data/lib/fluent/plugin/out_copy.rb +11 -7
- data/lib/fluent/plugin/out_exec.rb +15 -11
- data/lib/fluent/plugin/out_exec_filter.rb +18 -10
- data/lib/fluent/plugin/out_file.rb +34 -5
- data/lib/fluent/plugin/out_forward.rb +25 -19
- data/lib/fluent/plugin/out_null.rb +0 -14
- data/lib/fluent/plugin/out_roundrobin.rb +11 -7
- data/lib/fluent/plugin/out_stdout.rb +5 -7
- data/lib/fluent/plugin/out_stream.rb +3 -1
- data/lib/fluent/plugin/output.rb +979 -0
- data/lib/fluent/plugin/owned_by_mixin.rb +42 -0
- data/lib/fluent/plugin/parser.rb +244 -0
- data/lib/fluent/plugin/parser_apache.rb +24 -0
- data/lib/fluent/plugin/parser_apache2.rb +84 -0
- data/lib/fluent/plugin/parser_apache_error.rb +21 -0
- data/lib/fluent/plugin/parser_csv.rb +31 -0
- data/lib/fluent/plugin/parser_json.rb +79 -0
- data/lib/fluent/plugin/parser_ltsv.rb +50 -0
- data/lib/fluent/plugin/parser_multiline.rb +102 -0
- data/lib/fluent/plugin/parser_nginx.rb +24 -0
- data/lib/fluent/plugin/parser_none.rb +36 -0
- data/lib/fluent/plugin/parser_syslog.rb +82 -0
- data/lib/fluent/plugin/parser_tsv.rb +37 -0
- data/lib/fluent/plugin/socket_util.rb +119 -117
- data/lib/fluent/plugin/storage.rb +84 -0
- data/lib/fluent/plugin/storage_local.rb +116 -0
- data/lib/fluent/plugin/string_util.rb +16 -13
- data/lib/fluent/plugin_helper.rb +39 -0
- data/lib/fluent/plugin_helper/child_process.rb +298 -0
- data/lib/fluent/plugin_helper/compat_parameters.rb +99 -0
- data/lib/fluent/plugin_helper/event_emitter.rb +80 -0
- data/lib/fluent/plugin_helper/event_loop.rb +118 -0
- data/lib/fluent/plugin_helper/retry_state.rb +177 -0
- data/lib/fluent/plugin_helper/storage.rb +308 -0
- data/lib/fluent/plugin_helper/thread.rb +147 -0
- data/lib/fluent/plugin_helper/timer.rb +85 -0
- data/lib/fluent/plugin_id.rb +63 -0
- data/lib/fluent/process.rb +21 -30
- data/lib/fluent/registry.rb +21 -9
- data/lib/fluent/root_agent.rb +115 -40
- data/lib/fluent/supervisor.rb +330 -320
- data/lib/fluent/system_config.rb +42 -18
- data/lib/fluent/test.rb +6 -1
- data/lib/fluent/test/base.rb +23 -3
- data/lib/fluent/test/driver/base.rb +247 -0
- data/lib/fluent/test/driver/event_feeder.rb +98 -0
- data/lib/fluent/test/driver/filter.rb +35 -0
- data/lib/fluent/test/driver/input.rb +31 -0
- data/lib/fluent/test/driver/output.rb +78 -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 +2 -1
- data/lib/fluent/test/input_test.rb +23 -17
- data/lib/fluent/test/output_test.rb +28 -39
- data/lib/fluent/test/parser_test.rb +1 -1
- data/lib/fluent/time.rb +104 -1
- data/lib/fluent/{status.rb → unique_id.rb} +15 -24
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/winsvc.rb +72 -0
- data/test/compat/test_calls_super.rb +164 -0
- data/test/config/test_config_parser.rb +83 -0
- data/test/config/test_configurable.rb +547 -274
- data/test/config/test_configure_proxy.rb +146 -29
- data/test/config/test_dsl.rb +3 -181
- data/test/config/test_element.rb +274 -0
- data/test/config/test_literal_parser.rb +1 -1
- data/test/config/test_section.rb +79 -7
- data/test/config/test_system_config.rb +21 -0
- data/test/config/test_types.rb +3 -26
- data/test/helper.rb +78 -8
- data/test/plugin/test_bare_output.rb +118 -0
- data/test/plugin/test_base.rb +75 -0
- data/test/plugin/test_buf_file.rb +420 -521
- data/test/plugin/test_buf_memory.rb +32 -194
- data/test/plugin/test_buffer.rb +981 -0
- data/test/plugin/test_buffer_chunk.rb +110 -0
- data/test/plugin/test_buffer_file_chunk.rb +770 -0
- data/test/plugin/test_buffer_memory_chunk.rb +265 -0
- data/test/plugin/test_filter.rb +255 -0
- data/test/plugin/test_filter_grep.rb +2 -73
- data/test/plugin/test_filter_record_transformer.rb +24 -68
- data/test/plugin/test_filter_stdout.rb +6 -6
- data/test/plugin/test_in_debug_agent.rb +2 -0
- data/test/plugin/test_in_dummy.rb +11 -17
- data/test/plugin/test_in_exec.rb +6 -25
- data/test/plugin/test_in_forward.rb +112 -151
- data/test/plugin/test_in_gc_stat.rb +2 -0
- data/test/plugin/test_in_http.rb +106 -157
- data/test/plugin/test_in_object_space.rb +21 -5
- data/test/plugin/test_in_stream.rb +14 -13
- data/test/plugin/test_in_syslog.rb +30 -275
- data/test/plugin/test_in_tail.rb +95 -282
- data/test/plugin/test_in_tcp.rb +14 -0
- data/test/plugin/test_in_udp.rb +21 -67
- data/test/plugin/test_input.rb +122 -0
- data/test/plugin/test_multi_output.rb +180 -0
- data/test/plugin/test_out_buffered_null.rb +79 -0
- data/test/plugin/test_out_copy.rb +15 -2
- data/test/plugin/test_out_exec.rb +75 -25
- data/test/plugin/test_out_exec_filter.rb +74 -8
- data/test/plugin/test_out_file.rb +61 -7
- data/test/plugin/test_out_forward.rb +92 -15
- data/test/plugin/test_out_roundrobin.rb +1 -0
- data/test/plugin/test_out_stdout.rb +22 -13
- data/test/plugin/test_out_stream.rb +18 -0
- data/test/plugin/test_output.rb +515 -0
- data/test/plugin/test_output_as_buffered.rb +1540 -0
- data/test/plugin/test_output_as_buffered_overflow.rb +247 -0
- data/test/plugin/test_output_as_buffered_retries.rb +808 -0
- data/test/plugin/test_output_as_buffered_secondary.rb +776 -0
- data/test/plugin/test_output_as_standard.rb +362 -0
- data/test/plugin/test_owned_by.rb +35 -0
- data/test/plugin/test_storage.rb +167 -0
- data/test/plugin/test_storage_local.rb +8 -0
- data/test/plugin_helper/test_child_process.rb +599 -0
- data/test/plugin_helper/test_compat_parameters.rb +175 -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_retry_state.rb +399 -0
- data/test/plugin_helper/test_storage.rb +411 -0
- data/test/plugin_helper/test_thread.rb +164 -0
- data/test/plugin_helper/test_timer.rb +100 -0
- data/test/scripts/exec_script.rb +0 -6
- data/test/scripts/fluent/plugin/out_test.rb +3 -0
- data/test/test_config.rb +13 -4
- data/test/test_event.rb +24 -13
- data/test/test_event_router.rb +8 -7
- data/test/test_event_time.rb +187 -0
- data/test/test_formatter.rb +13 -51
- data/test/test_input.rb +1 -1
- data/test/test_log.rb +239 -16
- data/test/test_mixin.rb +1 -1
- data/test/test_output.rb +53 -66
- data/test/test_parser.rb +105 -323
- data/test/test_plugin_helper.rb +81 -0
- data/test/test_root_agent.rb +4 -52
- data/test/test_supervisor.rb +272 -0
- data/test/test_unique_id.rb +47 -0
- metadata +181 -55
- data/CHANGELOG.md +0 -710
- data/lib/fluent/buffer.rb +0 -365
- data/lib/fluent/plugin/filter_parser.rb +0 -107
- data/lib/fluent/plugin/in_status.rb +0 -76
- data/lib/fluent/test/helpers.rb +0 -86
- data/test/plugin/data/log/foo/bar2 +0 -0
- data/test/plugin/test_filter_parser.rb +0 -744
- data/test/plugin/test_in_status.rb +0 -38
- data/test/test_buffer.rb +0 -624
@@ -0,0 +1,51 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'fluent/plugin/base'
|
18
|
+
|
19
|
+
require 'fluent/event'
|
20
|
+
require 'fluent/log'
|
21
|
+
require 'fluent/plugin_id'
|
22
|
+
require 'fluent/plugin_helper'
|
23
|
+
|
24
|
+
module Fluent
|
25
|
+
module Plugin
|
26
|
+
class Filter < Base
|
27
|
+
include PluginId
|
28
|
+
include PluginLoggerMixin
|
29
|
+
include PluginHelper::Mixin
|
30
|
+
|
31
|
+
helpers :event_emitter
|
32
|
+
|
33
|
+
def filter(tag, time, record)
|
34
|
+
raise NotImplementedError, "BUG: filter plugins MUST implement this method"
|
35
|
+
end
|
36
|
+
|
37
|
+
def filter_stream(tag, es)
|
38
|
+
new_es = MultiEventStream.new
|
39
|
+
es.each do |time, record|
|
40
|
+
begin
|
41
|
+
filtered_record = filter(tag, time, record)
|
42
|
+
new_es.add(time, filtered_record) if filtered_record
|
43
|
+
rescue => e
|
44
|
+
router.emit_error_event(tag, time, record, e)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
new_es
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -28,59 +28,32 @@ module Fluent
|
|
28
28
|
|
29
29
|
REGEXP_MAX_NUM = 20
|
30
30
|
|
31
|
-
(1..REGEXP_MAX_NUM).each {|i| config_param :"regexp#{i}", :string, default: nil
|
32
|
-
(1..REGEXP_MAX_NUM).each {|i| config_param :"exclude#{i}", :string, default: nil
|
33
|
-
|
34
|
-
config_section :regexp, param_name: :regexps, multi: true do
|
35
|
-
desc "The field name to which the regular expression is applied."
|
36
|
-
config_param :key, :string
|
37
|
-
desc "The regular expression."
|
38
|
-
config_param :pattern do |value|
|
39
|
-
Regexp.compile(value)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
config_section :exclude, param_name: :excludes, multi: true do
|
44
|
-
desc "The field name to which the regular expression is applied."
|
45
|
-
config_param :key, :string
|
46
|
-
desc "The regular expression."
|
47
|
-
config_param :pattern do |value|
|
48
|
-
Regexp.compile(value)
|
49
|
-
end
|
50
|
-
end
|
31
|
+
(1..REGEXP_MAX_NUM).each {|i| config_param :"regexp#{i}", :string, default: nil }
|
32
|
+
(1..REGEXP_MAX_NUM).each {|i| config_param :"exclude#{i}", :string, default: nil }
|
51
33
|
|
52
34
|
# for test
|
53
|
-
attr_reader :
|
54
|
-
attr_reader :
|
35
|
+
attr_reader :regexps
|
36
|
+
attr_reader :excludes
|
55
37
|
|
56
38
|
def configure(conf)
|
57
39
|
super
|
58
40
|
|
59
|
-
@
|
41
|
+
@regexps = {}
|
60
42
|
(1..REGEXP_MAX_NUM).each do |i|
|
61
43
|
next unless conf["regexp#{i}"]
|
62
44
|
key, regexp = conf["regexp#{i}"].split(/ /, 2)
|
63
45
|
raise ConfigError, "regexp#{i} does not contain 2 parameters" unless regexp
|
64
|
-
raise ConfigError, "regexp#{i} contains a duplicated key, #{key}" if @
|
65
|
-
@
|
46
|
+
raise ConfigError, "regexp#{i} contains a duplicated key, #{key}" if @regexps[key]
|
47
|
+
@regexps[key] = Regexp.compile(regexp)
|
66
48
|
end
|
67
49
|
|
68
|
-
@
|
50
|
+
@excludes = {}
|
69
51
|
(1..REGEXP_MAX_NUM).each do |i|
|
70
52
|
next unless conf["exclude#{i}"]
|
71
53
|
key, exclude = conf["exclude#{i}"].split(/ /, 2)
|
72
54
|
raise ConfigError, "exclude#{i} does not contain 2 parameters" unless exclude
|
73
|
-
raise ConfigError, "exclude#{i} contains a duplicated key, #{key}" if @
|
74
|
-
@
|
75
|
-
end
|
76
|
-
|
77
|
-
@regexps.each do |e|
|
78
|
-
raise Fluent::ConfigError, "Duplicate key: #{e.key}" if @_regexps.key?(e.key)
|
79
|
-
@_regexps[e.key] = e.pattern
|
80
|
-
end
|
81
|
-
@excludes.each do |e|
|
82
|
-
raise Fluent::ConfigError, "Duplicate key: #{e.key}" if @_excludes.key?(e.key)
|
83
|
-
@_excludes[e.key] = e.pattern
|
55
|
+
raise ConfigError, "exclude#{i} contains a duplicated key, #{key}" if @excludes[key]
|
56
|
+
@excludes[key] = Regexp.compile(exclude)
|
84
57
|
end
|
85
58
|
end
|
86
59
|
|
@@ -88,16 +61,16 @@ module Fluent
|
|
88
61
|
result = nil
|
89
62
|
begin
|
90
63
|
catch(:break_loop) do
|
91
|
-
@
|
64
|
+
@regexps.each do |key, regexp|
|
92
65
|
throw :break_loop unless ::Fluent::StringUtil.match_regexp(regexp, record[key].to_s)
|
93
66
|
end
|
94
|
-
@
|
67
|
+
@excludes.each do |key, exclude|
|
95
68
|
throw :break_loop if ::Fluent::StringUtil.match_regexp(exclude, record[key].to_s)
|
96
69
|
end
|
97
70
|
result = record
|
98
71
|
end
|
99
72
|
rescue => e
|
100
|
-
log.warn "failed to grep events",
|
73
|
+
log.warn "failed to grep events", error: e
|
101
74
|
log.warn_backtrace
|
102
75
|
end
|
103
76
|
result
|
@@ -28,9 +28,9 @@ module Fluent
|
|
28
28
|
Fluent::Plugin.register_filter('record_transformer', self)
|
29
29
|
|
30
30
|
desc 'A comma-delimited list of keys to delete.'
|
31
|
-
config_param :remove_keys, :
|
31
|
+
config_param :remove_keys, :string, default: nil
|
32
32
|
desc 'A comma-delimited list of keys to keep.'
|
33
|
-
config_param :keep_keys, :
|
33
|
+
config_param :keep_keys, :string, default: nil
|
34
34
|
desc 'Create new Hash to transform incoming data'
|
35
35
|
config_param :renew_record, :bool, default: false
|
36
36
|
desc 'Specify field name of the record to overwrite the time of events. Its value must be unix time.'
|
@@ -52,8 +52,13 @@ module Fluent
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
+
if @remove_keys
|
56
|
+
@remove_keys = @remove_keys.split(',')
|
57
|
+
end
|
58
|
+
|
55
59
|
if @keep_keys
|
56
60
|
raise Fluent::ConfigError, "`renew_record` must be true to use `keep_keys`" unless @renew_record
|
61
|
+
@keep_keys = @keep_keys.split(',')
|
57
62
|
end
|
58
63
|
|
59
64
|
placeholder_expander_params = {
|
@@ -90,18 +95,19 @@ module Fluent
|
|
90
95
|
last_record = nil
|
91
96
|
es.each do |time, record|
|
92
97
|
last_record = record # for debug log
|
93
|
-
placeholder_values
|
94
|
-
|
98
|
+
placeholder_values.merge!({
|
99
|
+
'time' => @placeholder_expander.time_value(time),
|
100
|
+
'record' => record,
|
101
|
+
})
|
95
102
|
new_record = reform(record, placeholder_values)
|
96
103
|
if @renew_time_key && new_record.has_key?(@renew_time_key)
|
97
|
-
time = new_record[@renew_time_key].
|
104
|
+
time = EventTime.from_time(Time.at(new_record[@renew_time_key].to_f))
|
98
105
|
end
|
99
|
-
@remove_keys.each { |k| new_record.delete(k) } if @remove_keys
|
100
106
|
new_es.add(time, new_record)
|
101
107
|
end
|
102
108
|
new_es
|
103
109
|
rescue => e
|
104
|
-
log.warn "failed to reform records",
|
110
|
+
log.warn "failed to reform records", error: e
|
105
111
|
log.warn_backtrace
|
106
112
|
log.debug "map:#{@map} record:#{last_record} placeholder_values:#{placeholder_values}"
|
107
113
|
end
|
@@ -115,7 +121,7 @@ module Fluent
|
|
115
121
|
value_str
|
116
122
|
end
|
117
123
|
rescue => e
|
118
|
-
log.warn "failed to parse #{value_str} as json. Assuming #{value_str} is a string",
|
124
|
+
log.warn "failed to parse #{value_str} as json. Assuming #{value_str} is a string", error: e
|
119
125
|
value_str # emit as string
|
120
126
|
end
|
121
127
|
|
@@ -123,10 +129,9 @@ module Fluent
|
|
123
129
|
placeholders = @placeholder_expander.prepare_placeholders(placeholder_values)
|
124
130
|
|
125
131
|
new_record = @renew_record ? {} : record.dup
|
126
|
-
@keep_keys.each
|
127
|
-
new_record[k] = record[k] if record.has_key?(k)
|
128
|
-
end if @keep_keys && @renew_record
|
132
|
+
@keep_keys.each {|k| new_record[k] = record[k]} if @keep_keys and @renew_record
|
129
133
|
new_record.merge!(expand_placeholders(@map, placeholders))
|
134
|
+
@remove_keys.each {|k| new_record.delete(k) } if @remove_keys
|
130
135
|
|
131
136
|
new_record
|
132
137
|
end
|
@@ -199,9 +204,7 @@ module Fluent
|
|
199
204
|
end
|
200
205
|
elsif value.kind_of?(Hash) # record, etc
|
201
206
|
value.each do |k, v|
|
202
|
-
|
203
|
-
placeholders.store("${#{k}}", v) # foo
|
204
|
-
end
|
207
|
+
placeholders.store("${#{k}}", v) # foo
|
205
208
|
placeholders.store(%Q[${#{key}["#{k}"]}], v) # record["foo"]
|
206
209
|
end
|
207
210
|
else # string, interger, float, and others?
|
@@ -217,7 +220,7 @@ module Fluent
|
|
217
220
|
# @param [String] str
|
218
221
|
# @param [Boolean] force_stringify the value must be string, used for hash key
|
219
222
|
def expand(str, placeholders, force_stringify = false)
|
220
|
-
if @auto_typecast
|
223
|
+
if @auto_typecast and !force_stringify
|
221
224
|
single_placeholder_matched = str.match(/\A(\${[^}]+}|__[A-Z_]+__)\z/)
|
222
225
|
if single_placeholder_matched
|
223
226
|
log_if_unknown_placeholder($1, placeholders)
|
@@ -260,9 +263,9 @@ module Fluent
|
|
260
263
|
def preprocess_map(value, force_stringify = false)
|
261
264
|
new_value = nil
|
262
265
|
if value.is_a?(String)
|
263
|
-
if @auto_typecast
|
266
|
+
if @auto_typecast and !force_stringify
|
264
267
|
num_placeholders = value.scan('${').size
|
265
|
-
if num_placeholders == 1
|
268
|
+
if num_placeholders == 1 and value.start_with?('${') && value.end_with?('}')
|
266
269
|
new_value = value[2..-2] # ${..} => ..
|
267
270
|
end
|
268
271
|
end
|
@@ -304,7 +307,7 @@ module Fluent
|
|
304
307
|
placeholders['hostname'],
|
305
308
|
)
|
306
309
|
rescue => e
|
307
|
-
log.warn "failed to expand `#{str}`",
|
310
|
+
log.warn "failed to expand `#{str}`", error: e
|
308
311
|
log.warn_backtrace
|
309
312
|
nil
|
310
313
|
end
|
@@ -312,6 +315,7 @@ module Fluent
|
|
312
315
|
class CleanroomExpander
|
313
316
|
def expand(__str_to_eval__, tag, time, record, tag_parts, tag_prefix, tag_suffix, hostname)
|
314
317
|
tags = tag_parts # for old version compatibility
|
318
|
+
_ = tags # to suppress "unused variable" warning for tags
|
315
319
|
Thread.current[:record_transformer_record] = record # for old version compatibility
|
316
320
|
instance_eval(__str_to_eval__)
|
317
321
|
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'fluent/plugin/base'
|
18
|
+
require 'fluent/plugin/owned_by_mixin'
|
19
|
+
|
20
|
+
require 'fluent/mixin' # for TimeFormatter
|
21
|
+
|
22
|
+
module Fluent
|
23
|
+
module Plugin
|
24
|
+
class Formatter < Base
|
25
|
+
include OwnedByMixin
|
26
|
+
|
27
|
+
configured_in :format
|
28
|
+
|
29
|
+
def format(tag, time, record)
|
30
|
+
raise NotImplementedError, "Implement this method in child class"
|
31
|
+
end
|
32
|
+
|
33
|
+
# Mixins for formatter plugins
|
34
|
+
module HandleTagAndTimeMixin
|
35
|
+
def self.included(klass)
|
36
|
+
klass.instance_eval {
|
37
|
+
config_param :include_time_key, :bool, default: false
|
38
|
+
config_param :time_key, :string, default: 'time'
|
39
|
+
config_param :time_format, :string, default: nil
|
40
|
+
config_param :time_as_epoch, :bool, default: false
|
41
|
+
config_param :include_tag_key, :bool, default: false
|
42
|
+
config_param :tag_key, :string, default: 'tag'
|
43
|
+
config_param :localtime, :bool, default: true
|
44
|
+
config_param :timezone, :string, default: nil
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def configure(conf)
|
49
|
+
super
|
50
|
+
|
51
|
+
if conf['utc']
|
52
|
+
@localtime = false
|
53
|
+
end
|
54
|
+
@timef = Fluent::TimeFormatter.new(@time_format, @localtime, @timezone)
|
55
|
+
if @time_as_epoch && !@include_time_key
|
56
|
+
log.warn "time_as_epoch will be ignored because include_time_key is false"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def filter_record(tag, time, record)
|
61
|
+
if @include_tag_key
|
62
|
+
record[@tag_key] = tag
|
63
|
+
end
|
64
|
+
if @include_time_key
|
65
|
+
if @time_as_epoch
|
66
|
+
record[@time_key] = time.to_i
|
67
|
+
else
|
68
|
+
record[@time_key] = @timef.format(time)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
module StructuredFormatMixin
|
75
|
+
def format(tag, time, record)
|
76
|
+
filter_record(tag, time, record)
|
77
|
+
format_record(record)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class ProcWrappedFormatter < Formatter
|
83
|
+
def initialize(proc)
|
84
|
+
super()
|
85
|
+
@proc = proc
|
86
|
+
end
|
87
|
+
|
88
|
+
def format(tag, time, record)
|
89
|
+
@proc.call(tag, time, record)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'fluent/plugin/formatter'
|
18
|
+
require 'csv'
|
19
|
+
|
20
|
+
module Fluent
|
21
|
+
module Plugin
|
22
|
+
class CsvFormatter < Formatter
|
23
|
+
Plugin.register_formatter('csv', self)
|
24
|
+
|
25
|
+
include HandleTagAndTimeMixin
|
26
|
+
|
27
|
+
config_param :delimiter, default: ',' do |val|
|
28
|
+
['\t', 'TAB'].include?(val) ? "\t" : val
|
29
|
+
end
|
30
|
+
config_param :force_quotes, :bool, default: true
|
31
|
+
# "array" looks good for type of :fields, but this implementation removes tailing comma
|
32
|
+
# TODO: Is it needed to support tailing comma?
|
33
|
+
config_param :fields, default: [] do |val|
|
34
|
+
val.split(',').map{|f| f.strip!; f.empty? ? nil : f }.compact
|
35
|
+
end
|
36
|
+
|
37
|
+
def format(tag, time, record)
|
38
|
+
filter_record(tag, time, record)
|
39
|
+
row = @fields.inject([]) do |memo, key|
|
40
|
+
memo << record[key]
|
41
|
+
memo
|
42
|
+
end
|
43
|
+
CSV.generate_line(row, col_sep: @delimiter,
|
44
|
+
force_quotes: @force_quotes)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'fluent/plugin/formatter'
|
18
|
+
|
19
|
+
module Fluent
|
20
|
+
module Plugin
|
21
|
+
class HashFormatter < Formatter
|
22
|
+
Plugin.register_formatter('hash', self)
|
23
|
+
|
24
|
+
include HandleTagAndTimeMixin
|
25
|
+
include StructuredFormatMixin
|
26
|
+
|
27
|
+
def format_record(record)
|
28
|
+
"#{record.to_s}\n"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'fluent/plugin/formatter'
|
18
|
+
|
19
|
+
module Fluent
|
20
|
+
module Plugin
|
21
|
+
class JSONFormatter < Formatter
|
22
|
+
Plugin.register_formatter('json', self)
|
23
|
+
|
24
|
+
include HandleTagAndTimeMixin
|
25
|
+
include StructuredFormatMixin
|
26
|
+
|
27
|
+
config_param :json_parser, :string, default: 'oj'
|
28
|
+
|
29
|
+
def configure(conf)
|
30
|
+
super
|
31
|
+
|
32
|
+
begin
|
33
|
+
raise LoadError unless @json_parser == 'oj'
|
34
|
+
require 'oj'
|
35
|
+
Oj.default_options = {mode: :compat}
|
36
|
+
@dump_proc = Oj.method(:dump)
|
37
|
+
rescue LoadError
|
38
|
+
@dump_proc = Yajl.method(:dump)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def format_record(record)
|
43
|
+
"#{@dump_proc.call(record)}\n"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|