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.

Files changed (253) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE.md +6 -0
  3. data/.gitignore +2 -0
  4. data/.travis.yml +33 -21
  5. data/CONTRIBUTING.md +1 -0
  6. data/ChangeLog +1239 -0
  7. data/README.md +0 -25
  8. data/Rakefile +2 -1
  9. data/Vagrantfile +17 -0
  10. data/appveyor.yml +35 -0
  11. data/example/filter_stdout.conf +5 -5
  12. data/example/in_forward.conf +2 -2
  13. data/example/in_http.conf +2 -2
  14. data/example/in_out_forward.conf +17 -0
  15. data/example/in_syslog.conf +2 -2
  16. data/example/in_tail.conf +2 -2
  17. data/example/in_tcp.conf +2 -2
  18. data/example/in_udp.conf +2 -2
  19. data/example/out_copy.conf +4 -4
  20. data/example/out_file.conf +2 -2
  21. data/example/out_forward.conf +2 -2
  22. data/example/out_forward_buf_file.conf +23 -0
  23. data/example/v0_12_filter.conf +8 -8
  24. data/fluent.conf +29 -0
  25. data/fluentd.gemspec +18 -11
  26. data/lib/fluent/agent.rb +60 -58
  27. data/lib/fluent/command/cat.rb +1 -1
  28. data/lib/fluent/command/debug.rb +7 -5
  29. data/lib/fluent/command/fluentd.rb +97 -2
  30. data/lib/fluent/compat/call_super_mixin.rb +67 -0
  31. data/lib/fluent/compat/filter.rb +50 -0
  32. data/lib/fluent/compat/formatter.rb +109 -0
  33. data/lib/fluent/compat/input.rb +50 -0
  34. data/lib/fluent/compat/output.rb +617 -0
  35. data/lib/fluent/compat/output_chain.rb +60 -0
  36. data/lib/fluent/compat/parser.rb +163 -0
  37. data/lib/fluent/compat/propagate_default.rb +62 -0
  38. data/lib/fluent/config.rb +23 -20
  39. data/lib/fluent/config/configure_proxy.rb +119 -70
  40. data/lib/fluent/config/dsl.rb +5 -18
  41. data/lib/fluent/config/element.rb +72 -8
  42. data/lib/fluent/config/error.rb +0 -3
  43. data/lib/fluent/config/literal_parser.rb +0 -2
  44. data/lib/fluent/config/parser.rb +4 -4
  45. data/lib/fluent/config/section.rb +39 -28
  46. data/lib/fluent/config/types.rb +2 -13
  47. data/lib/fluent/config/v1_parser.rb +1 -3
  48. data/lib/fluent/configurable.rb +48 -16
  49. data/lib/fluent/daemon.rb +15 -0
  50. data/lib/fluent/engine.rb +26 -52
  51. data/lib/fluent/env.rb +6 -4
  52. data/lib/fluent/event.rb +58 -11
  53. data/lib/fluent/event_router.rb +5 -5
  54. data/lib/fluent/filter.rb +2 -50
  55. data/lib/fluent/formatter.rb +4 -293
  56. data/lib/fluent/input.rb +2 -32
  57. data/lib/fluent/label.rb +2 -2
  58. data/lib/fluent/load.rb +3 -2
  59. data/lib/fluent/log.rb +107 -38
  60. data/lib/fluent/match.rb +0 -36
  61. data/lib/fluent/mixin.rb +117 -7
  62. data/lib/fluent/msgpack_factory.rb +62 -0
  63. data/lib/fluent/output.rb +7 -612
  64. data/lib/fluent/output_chain.rb +23 -0
  65. data/lib/fluent/parser.rb +4 -800
  66. data/lib/fluent/plugin.rb +100 -121
  67. data/lib/fluent/plugin/bare_output.rb +63 -0
  68. data/lib/fluent/plugin/base.rb +121 -0
  69. data/lib/fluent/plugin/buf_file.rb +101 -182
  70. data/lib/fluent/plugin/buf_memory.rb +9 -92
  71. data/lib/fluent/plugin/buffer.rb +473 -0
  72. data/lib/fluent/plugin/buffer/chunk.rb +135 -0
  73. data/lib/fluent/plugin/buffer/file_chunk.rb +339 -0
  74. data/lib/fluent/plugin/buffer/memory_chunk.rb +100 -0
  75. data/lib/fluent/plugin/exec_util.rb +80 -75
  76. data/lib/fluent/plugin/file_util.rb +33 -28
  77. data/lib/fluent/plugin/file_wrapper.rb +120 -0
  78. data/lib/fluent/plugin/filter.rb +51 -0
  79. data/lib/fluent/plugin/filter_grep.rb +13 -40
  80. data/lib/fluent/plugin/filter_record_transformer.rb +22 -18
  81. data/lib/fluent/plugin/formatter.rb +93 -0
  82. data/lib/fluent/plugin/formatter_csv.rb +48 -0
  83. data/lib/fluent/plugin/formatter_hash.rb +32 -0
  84. data/lib/fluent/plugin/formatter_json.rb +47 -0
  85. data/lib/fluent/plugin/formatter_ltsv.rb +42 -0
  86. data/lib/fluent/plugin/formatter_msgpack.rb +32 -0
  87. data/lib/fluent/plugin/formatter_out_file.rb +45 -0
  88. data/lib/fluent/plugin/formatter_single_value.rb +34 -0
  89. data/lib/fluent/plugin/formatter_stdout.rb +39 -0
  90. data/lib/fluent/plugin/in_debug_agent.rb +4 -0
  91. data/lib/fluent/plugin/in_dummy.rb +22 -18
  92. data/lib/fluent/plugin/in_exec.rb +18 -8
  93. data/lib/fluent/plugin/in_forward.rb +36 -79
  94. data/lib/fluent/plugin/in_gc_stat.rb +4 -0
  95. data/lib/fluent/plugin/in_http.rb +21 -18
  96. data/lib/fluent/plugin/in_monitor_agent.rb +15 -48
  97. data/lib/fluent/plugin/in_object_space.rb +6 -1
  98. data/lib/fluent/plugin/in_stream.rb +7 -3
  99. data/lib/fluent/plugin/in_syslog.rb +46 -95
  100. data/lib/fluent/plugin/in_tail.rb +58 -640
  101. data/lib/fluent/plugin/in_tcp.rb +8 -1
  102. data/lib/fluent/plugin/in_udp.rb +8 -18
  103. data/lib/fluent/plugin/input.rb +33 -0
  104. data/lib/fluent/plugin/multi_output.rb +95 -0
  105. data/lib/fluent/plugin/out_buffered_null.rb +59 -0
  106. data/lib/fluent/plugin/out_copy.rb +11 -7
  107. data/lib/fluent/plugin/out_exec.rb +15 -11
  108. data/lib/fluent/plugin/out_exec_filter.rb +18 -10
  109. data/lib/fluent/plugin/out_file.rb +34 -5
  110. data/lib/fluent/plugin/out_forward.rb +25 -19
  111. data/lib/fluent/plugin/out_null.rb +0 -14
  112. data/lib/fluent/plugin/out_roundrobin.rb +11 -7
  113. data/lib/fluent/plugin/out_stdout.rb +5 -7
  114. data/lib/fluent/plugin/out_stream.rb +3 -1
  115. data/lib/fluent/plugin/output.rb +979 -0
  116. data/lib/fluent/plugin/owned_by_mixin.rb +42 -0
  117. data/lib/fluent/plugin/parser.rb +244 -0
  118. data/lib/fluent/plugin/parser_apache.rb +24 -0
  119. data/lib/fluent/plugin/parser_apache2.rb +84 -0
  120. data/lib/fluent/plugin/parser_apache_error.rb +21 -0
  121. data/lib/fluent/plugin/parser_csv.rb +31 -0
  122. data/lib/fluent/plugin/parser_json.rb +79 -0
  123. data/lib/fluent/plugin/parser_ltsv.rb +50 -0
  124. data/lib/fluent/plugin/parser_multiline.rb +102 -0
  125. data/lib/fluent/plugin/parser_nginx.rb +24 -0
  126. data/lib/fluent/plugin/parser_none.rb +36 -0
  127. data/lib/fluent/plugin/parser_syslog.rb +82 -0
  128. data/lib/fluent/plugin/parser_tsv.rb +37 -0
  129. data/lib/fluent/plugin/socket_util.rb +119 -117
  130. data/lib/fluent/plugin/storage.rb +84 -0
  131. data/lib/fluent/plugin/storage_local.rb +116 -0
  132. data/lib/fluent/plugin/string_util.rb +16 -13
  133. data/lib/fluent/plugin_helper.rb +39 -0
  134. data/lib/fluent/plugin_helper/child_process.rb +298 -0
  135. data/lib/fluent/plugin_helper/compat_parameters.rb +99 -0
  136. data/lib/fluent/plugin_helper/event_emitter.rb +80 -0
  137. data/lib/fluent/plugin_helper/event_loop.rb +118 -0
  138. data/lib/fluent/plugin_helper/retry_state.rb +177 -0
  139. data/lib/fluent/plugin_helper/storage.rb +308 -0
  140. data/lib/fluent/plugin_helper/thread.rb +147 -0
  141. data/lib/fluent/plugin_helper/timer.rb +85 -0
  142. data/lib/fluent/plugin_id.rb +63 -0
  143. data/lib/fluent/process.rb +21 -30
  144. data/lib/fluent/registry.rb +21 -9
  145. data/lib/fluent/root_agent.rb +115 -40
  146. data/lib/fluent/supervisor.rb +330 -320
  147. data/lib/fluent/system_config.rb +42 -18
  148. data/lib/fluent/test.rb +6 -1
  149. data/lib/fluent/test/base.rb +23 -3
  150. data/lib/fluent/test/driver/base.rb +247 -0
  151. data/lib/fluent/test/driver/event_feeder.rb +98 -0
  152. data/lib/fluent/test/driver/filter.rb +35 -0
  153. data/lib/fluent/test/driver/input.rb +31 -0
  154. data/lib/fluent/test/driver/output.rb +78 -0
  155. data/lib/fluent/test/driver/test_event_router.rb +45 -0
  156. data/lib/fluent/test/filter_test.rb +0 -1
  157. data/lib/fluent/test/formatter_test.rb +2 -1
  158. data/lib/fluent/test/input_test.rb +23 -17
  159. data/lib/fluent/test/output_test.rb +28 -39
  160. data/lib/fluent/test/parser_test.rb +1 -1
  161. data/lib/fluent/time.rb +104 -1
  162. data/lib/fluent/{status.rb → unique_id.rb} +15 -24
  163. data/lib/fluent/version.rb +1 -1
  164. data/lib/fluent/winsvc.rb +72 -0
  165. data/test/compat/test_calls_super.rb +164 -0
  166. data/test/config/test_config_parser.rb +83 -0
  167. data/test/config/test_configurable.rb +547 -274
  168. data/test/config/test_configure_proxy.rb +146 -29
  169. data/test/config/test_dsl.rb +3 -181
  170. data/test/config/test_element.rb +274 -0
  171. data/test/config/test_literal_parser.rb +1 -1
  172. data/test/config/test_section.rb +79 -7
  173. data/test/config/test_system_config.rb +21 -0
  174. data/test/config/test_types.rb +3 -26
  175. data/test/helper.rb +78 -8
  176. data/test/plugin/test_bare_output.rb +118 -0
  177. data/test/plugin/test_base.rb +75 -0
  178. data/test/plugin/test_buf_file.rb +420 -521
  179. data/test/plugin/test_buf_memory.rb +32 -194
  180. data/test/plugin/test_buffer.rb +981 -0
  181. data/test/plugin/test_buffer_chunk.rb +110 -0
  182. data/test/plugin/test_buffer_file_chunk.rb +770 -0
  183. data/test/plugin/test_buffer_memory_chunk.rb +265 -0
  184. data/test/plugin/test_filter.rb +255 -0
  185. data/test/plugin/test_filter_grep.rb +2 -73
  186. data/test/plugin/test_filter_record_transformer.rb +24 -68
  187. data/test/plugin/test_filter_stdout.rb +6 -6
  188. data/test/plugin/test_in_debug_agent.rb +2 -0
  189. data/test/plugin/test_in_dummy.rb +11 -17
  190. data/test/plugin/test_in_exec.rb +6 -25
  191. data/test/plugin/test_in_forward.rb +112 -151
  192. data/test/plugin/test_in_gc_stat.rb +2 -0
  193. data/test/plugin/test_in_http.rb +106 -157
  194. data/test/plugin/test_in_object_space.rb +21 -5
  195. data/test/plugin/test_in_stream.rb +14 -13
  196. data/test/plugin/test_in_syslog.rb +30 -275
  197. data/test/plugin/test_in_tail.rb +95 -282
  198. data/test/plugin/test_in_tcp.rb +14 -0
  199. data/test/plugin/test_in_udp.rb +21 -67
  200. data/test/plugin/test_input.rb +122 -0
  201. data/test/plugin/test_multi_output.rb +180 -0
  202. data/test/plugin/test_out_buffered_null.rb +79 -0
  203. data/test/plugin/test_out_copy.rb +15 -2
  204. data/test/plugin/test_out_exec.rb +75 -25
  205. data/test/plugin/test_out_exec_filter.rb +74 -8
  206. data/test/plugin/test_out_file.rb +61 -7
  207. data/test/plugin/test_out_forward.rb +92 -15
  208. data/test/plugin/test_out_roundrobin.rb +1 -0
  209. data/test/plugin/test_out_stdout.rb +22 -13
  210. data/test/plugin/test_out_stream.rb +18 -0
  211. data/test/plugin/test_output.rb +515 -0
  212. data/test/plugin/test_output_as_buffered.rb +1540 -0
  213. data/test/plugin/test_output_as_buffered_overflow.rb +247 -0
  214. data/test/plugin/test_output_as_buffered_retries.rb +808 -0
  215. data/test/plugin/test_output_as_buffered_secondary.rb +776 -0
  216. data/test/plugin/test_output_as_standard.rb +362 -0
  217. data/test/plugin/test_owned_by.rb +35 -0
  218. data/test/plugin/test_storage.rb +167 -0
  219. data/test/plugin/test_storage_local.rb +8 -0
  220. data/test/plugin_helper/test_child_process.rb +599 -0
  221. data/test/plugin_helper/test_compat_parameters.rb +175 -0
  222. data/test/plugin_helper/test_event_emitter.rb +51 -0
  223. data/test/plugin_helper/test_event_loop.rb +52 -0
  224. data/test/plugin_helper/test_retry_state.rb +399 -0
  225. data/test/plugin_helper/test_storage.rb +411 -0
  226. data/test/plugin_helper/test_thread.rb +164 -0
  227. data/test/plugin_helper/test_timer.rb +100 -0
  228. data/test/scripts/exec_script.rb +0 -6
  229. data/test/scripts/fluent/plugin/out_test.rb +3 -0
  230. data/test/test_config.rb +13 -4
  231. data/test/test_event.rb +24 -13
  232. data/test/test_event_router.rb +8 -7
  233. data/test/test_event_time.rb +187 -0
  234. data/test/test_formatter.rb +13 -51
  235. data/test/test_input.rb +1 -1
  236. data/test/test_log.rb +239 -16
  237. data/test/test_mixin.rb +1 -1
  238. data/test/test_output.rb +53 -66
  239. data/test/test_parser.rb +105 -323
  240. data/test/test_plugin_helper.rb +81 -0
  241. data/test/test_root_agent.rb +4 -52
  242. data/test/test_supervisor.rb +272 -0
  243. data/test/test_unique_id.rb +47 -0
  244. metadata +181 -55
  245. data/CHANGELOG.md +0 -710
  246. data/lib/fluent/buffer.rb +0 -365
  247. data/lib/fluent/plugin/filter_parser.rb +0 -107
  248. data/lib/fluent/plugin/in_status.rb +0 -76
  249. data/lib/fluent/test/helpers.rb +0 -86
  250. data/test/plugin/data/log/foo/bar2 +0 -0
  251. data/test/plugin/test_filter_parser.rb +0 -744
  252. data/test/plugin/test_in_status.rb +0 -38
  253. 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, deprecated: "Use <regexp> section" }
32
- (1..REGEXP_MAX_NUM).each {|i| config_param :"exclude#{i}", :string, default: nil, deprecated: "Use <exclude> section" }
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 :_regexps
54
- attr_reader :_excludes
35
+ attr_reader :regexps
36
+ attr_reader :excludes
55
37
 
56
38
  def configure(conf)
57
39
  super
58
40
 
59
- @_regexps = {}
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 @_regexps[key]
65
- @_regexps[key] = Regexp.compile(regexp)
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
- @_excludes = {}
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 @_excludes[key]
74
- @_excludes[key] = Regexp.compile(exclude)
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
- @_regexps.each do |key, regexp|
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
- @_excludes.each do |key, exclude|
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", error_class: e.class, error: e.message
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, :array, default: nil
31
+ config_param :remove_keys, :string, default: nil
32
32
  desc 'A comma-delimited list of keys to keep.'
33
- config_param :keep_keys, :array, default: nil
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['time'] = @placeholder_expander.time_value(time)
94
- placeholder_values['record'] = record
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].to_i
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", error_class: e.class, error: e.message
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", error_class: e.class, error: e.message
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 do |k|
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
- unless placeholder_values.has_key?(k) # prevent overwriting reserved keys such as tag
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 && !force_stringify
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 && !force_stringify
266
+ if @auto_typecast and !force_stringify
264
267
  num_placeholders = value.scan('${').size
265
- if num_placeholders == 1 && value.start_with?('${') && value.end_with?('}')
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}`", error_class: e.class, error: e.message
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