fluentd 0.12.20 → 0.12.21

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 (92) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +23 -0
  3. data/Rakefile +2 -2
  4. data/bin/fluent-debug +0 -1
  5. data/lib/fluent/agent.rb +12 -9
  6. data/lib/fluent/buffer.rb +9 -3
  7. data/lib/fluent/command/bundler_injection.rb +2 -0
  8. data/lib/fluent/command/cat.rb +1 -1
  9. data/lib/fluent/command/debug.rb +3 -2
  10. data/lib/fluent/command/fluentd.rb +3 -1
  11. data/lib/fluent/config.rb +4 -5
  12. data/lib/fluent/config/basic_parser.rb +3 -4
  13. data/lib/fluent/config/configure_proxy.rb +2 -0
  14. data/lib/fluent/config/dsl.rb +3 -0
  15. data/lib/fluent/config/element.rb +3 -2
  16. data/lib/fluent/config/literal_parser.rb +8 -5
  17. data/lib/fluent/config/parser.rb +5 -3
  18. data/lib/fluent/config/section.rb +3 -3
  19. data/lib/fluent/config/types.rb +44 -50
  20. data/lib/fluent/config/v1_parser.rb +8 -6
  21. data/lib/fluent/configurable.rb +8 -6
  22. data/lib/fluent/engine.rb +23 -11
  23. data/lib/fluent/event.rb +2 -0
  24. data/lib/fluent/event_router.rb +4 -2
  25. data/lib/fluent/filter.rb +6 -0
  26. data/lib/fluent/formatter.rb +27 -25
  27. data/lib/fluent/input.rb +5 -0
  28. data/lib/fluent/label.rb +2 -2
  29. data/lib/fluent/log.rb +5 -2
  30. data/lib/fluent/mixin.rb +4 -2
  31. data/lib/fluent/output.rb +45 -31
  32. data/lib/fluent/parser.rb +35 -25
  33. data/lib/fluent/plugin.rb +4 -0
  34. data/lib/fluent/plugin/buf_file.rb +9 -2
  35. data/lib/fluent/plugin/buf_memory.rb +7 -1
  36. data/lib/fluent/plugin/exec_util.rb +7 -2
  37. data/lib/fluent/plugin/filter_grep.rb +6 -3
  38. data/lib/fluent/plugin/filter_record_transformer.rb +52 -51
  39. data/lib/fluent/plugin/filter_stdout.rb +4 -1
  40. data/lib/fluent/plugin/in_debug_agent.rb +7 -5
  41. data/lib/fluent/plugin/in_dummy.rb +8 -3
  42. data/lib/fluent/plugin/in_exec.rb +16 -10
  43. data/lib/fluent/plugin/in_forward.rb +18 -11
  44. data/lib/fluent/plugin/in_gc_stat.rb +6 -2
  45. data/lib/fluent/plugin/in_http.rb +23 -14
  46. data/lib/fluent/plugin/in_monitor_agent.rb +24 -17
  47. data/lib/fluent/plugin/in_object_space.rb +9 -4
  48. data/lib/fluent/plugin/in_stream.rb +15 -6
  49. data/lib/fluent/plugin/in_syslog.rb +18 -12
  50. data/lib/fluent/plugin/in_tail.rb +61 -40
  51. data/lib/fluent/plugin/in_tcp.rb +3 -1
  52. data/lib/fluent/plugin/in_udp.rb +1 -1
  53. data/lib/fluent/plugin/out_copy.rb +5 -1
  54. data/lib/fluent/plugin/out_exec.rb +9 -6
  55. data/lib/fluent/plugin/out_exec_filter.rb +32 -25
  56. data/lib/fluent/plugin/out_file.rb +11 -5
  57. data/lib/fluent/plugin/out_forward.rb +30 -24
  58. data/lib/fluent/plugin/out_null.rb +2 -0
  59. data/lib/fluent/plugin/out_relabel.rb +2 -0
  60. data/lib/fluent/plugin/out_roundrobin.rb +3 -0
  61. data/lib/fluent/plugin/out_stdout.rb +3 -1
  62. data/lib/fluent/plugin/out_stream.rb +8 -8
  63. data/lib/fluent/plugin/socket_util.rb +12 -10
  64. data/lib/fluent/process.rb +14 -8
  65. data/lib/fluent/registry.rb +2 -2
  66. data/lib/fluent/root_agent.rb +16 -12
  67. data/lib/fluent/rpc.rb +7 -7
  68. data/lib/fluent/supervisor.rb +35 -69
  69. data/lib/fluent/system_config.rb +98 -0
  70. data/lib/fluent/test.rb +1 -1
  71. data/lib/fluent/test/base.rb +6 -1
  72. data/lib/fluent/test/filter_test.rb +4 -0
  73. data/lib/fluent/test/formatter_test.rb +3 -2
  74. data/lib/fluent/test/input_test.rb +6 -0
  75. data/lib/fluent/test/output_test.rb +4 -0
  76. data/lib/fluent/test/parser_test.rb +3 -2
  77. data/lib/fluent/timezone.rb +2 -0
  78. data/lib/fluent/version.rb +1 -1
  79. data/test/config/test_configurable.rb +11 -11
  80. data/test/config/test_configure_proxy.rb +1 -1
  81. data/test/config/test_system_config.rb +5 -5
  82. data/test/config/test_types.rb +70 -0
  83. data/test/plugin/test_filter_record_transformer.rb +72 -55
  84. data/test/plugin/test_in_forward.rb +4 -0
  85. data/test/plugin/test_in_tail.rb +73 -2
  86. data/test/test_config.rb +2 -2
  87. data/test/test_event_router.rb +1 -0
  88. data/test/test_output.rb +27 -3
  89. data/test/test_plugin_classes.rb +3 -0
  90. data/test/test_process.rb +1 -0
  91. data/test/test_root_agent.rb +5 -3
  92. metadata +3 -2
@@ -14,9 +14,19 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
- module Fluent
18
- require 'fluent/registry'
17
+ require 'time'
18
+ require 'json'
19
+
20
+ require 'yajl'
19
21
 
22
+ require 'fluent/config/error'
23
+ require 'fluent/config/element'
24
+ require 'fluent/configurable'
25
+ require 'fluent/engine'
26
+ require 'fluent/registry'
27
+ require 'fluent/time'
28
+
29
+ module Fluent
20
30
  class ParserError < StandardError
21
31
  end
22
32
 
@@ -27,7 +37,7 @@ module Fluent
27
37
  # 'configure()' may raise errors for unexpected configurations
28
38
  attr_accessor :estimate_current_event
29
39
 
30
- config_param :keep_time_key, :bool, :default => false
40
+ config_param :keep_time_key, :bool, default: false
31
41
 
32
42
  def initialize
33
43
  super
@@ -113,9 +123,9 @@ module Fluent
113
123
 
114
124
  def self.included(klass)
115
125
  klass.instance_eval {
116
- config_param :types, :string, :default => nil
117
- config_param :types_delimiter, :string, :default => ','
118
- config_param :types_label_delimiter, :string, :default => ':'
126
+ config_param :types, :string, default: nil
127
+ config_param :types_delimiter, :string, default: ','
128
+ config_param :types_label_delimiter, :string, default: ':'
119
129
  }
120
130
  end
121
131
 
@@ -162,8 +172,8 @@ module Fluent
162
172
  class RegexpParser < Parser
163
173
  include TypeConverter
164
174
 
165
- config_param :time_key, :string, :default => 'time'
166
- config_param :time_format, :string, :default => nil
175
+ config_param :time_key, :string, default: 'time'
176
+ config_param :time_format, :string, default: nil
167
177
 
168
178
  def initialize(regexp, conf={})
169
179
  super()
@@ -235,9 +245,9 @@ module Fluent
235
245
  end
236
246
 
237
247
  class JSONParser < Parser
238
- config_param :time_key, :string, :default => 'time'
239
- config_param :time_format, :string, :default => nil
240
- config_param :json_parser, :string, :default => 'oj'
248
+ config_param :time_key, :string, default: 'time'
249
+ config_param :time_format, :string, default: nil
250
+ config_param :json_parser, :string, default: 'oj'
241
251
 
242
252
  def configure(conf)
243
253
  super
@@ -250,7 +260,7 @@ module Fluent
250
260
  begin
251
261
  raise LoadError unless @json_parser == 'oj'
252
262
  require 'oj'
253
- Oj.default_options = {:bigdecimal_load => :float}
263
+ Oj.default_options = {bigdecimal_load: :float}
254
264
  @load_proc = Oj.method(:load)
255
265
  @error_class = Oj::ParseError
256
266
  rescue LoadError
@@ -298,17 +308,17 @@ module Fluent
298
308
  class ValuesParser < Parser
299
309
  include TypeConverter
300
310
 
301
- config_param :keys, :default => [] do |val|
311
+ config_param :keys, default: [] do |val|
302
312
  if val.start_with?('[') # This check is enough because keys parameter is simple. No '[' started column name.
303
313
  JSON.load(val)
304
314
  else
305
315
  val.split(",")
306
316
  end
307
317
  end
308
- config_param :time_key, :string, :default => nil
309
- config_param :time_format, :string, :default => nil
310
- config_param :null_value_pattern, :string, :default => nil
311
- config_param :null_empty_string, :bool, :default => false
318
+ config_param :time_key, :string, default: nil
319
+ config_param :time_format, :string, default: nil
320
+ config_param :null_value_pattern, :string, default: nil
321
+ config_param :null_empty_string, :bool, default: false
312
322
 
313
323
  def configure(conf)
314
324
  super
@@ -377,7 +387,7 @@ module Fluent
377
387
  end
378
388
 
379
389
  class TSVParser < ValuesParser
380
- config_param :delimiter, :string, :default => "\t"
390
+ config_param :delimiter, :string, default: "\t"
381
391
 
382
392
  def configure(conf)
383
393
  super
@@ -394,9 +404,9 @@ module Fluent
394
404
  end
395
405
 
396
406
  class LabeledTSVParser < ValuesParser
397
- config_param :delimiter, :string, :default => "\t"
398
- config_param :label_delimiter, :string, :default => ":"
399
- config_param :time_key, :string, :default => "time"
407
+ config_param :delimiter, :string, default: "\t"
408
+ config_param :label_delimiter, :string, default: ":"
409
+ config_param :time_key, :string, default: "time"
400
410
 
401
411
  def configure(conf)
402
412
  conf['keys'] = conf['time_key'] || 'time'
@@ -437,7 +447,7 @@ module Fluent
437
447
  end
438
448
 
439
449
  class NoneParser < Parser
440
- config_param :message_key, :string, :default => 'message'
450
+ config_param :message_key, :string, default: 'message'
441
451
 
442
452
  def parse(text)
443
453
  record = {}
@@ -526,8 +536,8 @@ module Fluent
526
536
  # From in_syslog default pattern
527
537
  REGEXP_WITH_PRI = /^\<(?<pri>[0-9]+)\>(?<time>[^ ]* {1,2}[^ ]* [^ ]*) (?<host>[^ ]*) (?<ident>[a-zA-Z0-9_\/\.\-]*)(?:\[(?<pid>[0-9]+)\])?(?:[^\:]*\:)? *(?<message>.*)$/
528
538
 
529
- config_param :time_format, :string, :default => "%b %d %H:%M:%S"
530
- config_param :with_priority, :bool, :default => false
539
+ config_param :time_format, :string, default: "%b %d %H:%M:%S"
540
+ config_param :with_priority, :bool, default: false
531
541
 
532
542
  def initialize
533
543
  super
@@ -586,7 +596,7 @@ module Fluent
586
596
  end
587
597
 
588
598
  class MultilineParser < Parser
589
- config_param :format_firstline, :string, :default => nil
599
+ config_param :format_firstline, :string, default: nil
590
600
 
591
601
  FORMAT_MAX_NUM = 20
592
602
 
@@ -14,6 +14,8 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
+ require 'fluent/config/error'
18
+
17
19
  module Fluent
18
20
  class PluginClass
19
21
  # This class is refactored using Fluent::Registry at v0.14
@@ -66,10 +68,12 @@ module Fluent
66
68
  end
67
69
 
68
70
  def new_parser(type)
71
+ require 'fluent/parser'
69
72
  TextParser.lookup(type)
70
73
  end
71
74
 
72
75
  def new_formatter(type)
76
+ require 'fluent/formatter'
73
77
  TextFormatter.lookup(type)
74
78
  end
75
79
 
@@ -14,6 +14,13 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
+ require 'fileutils'
18
+ require 'uri'
19
+
20
+ require 'fluent/env'
21
+ require 'fluent/plugin'
22
+ require 'fluent/buffer'
23
+
17
24
  module Fluent
18
25
  class FileBufferChunk < BufferChunk
19
26
  def initialize(key, path, unique_id, mode="a+", symlink_path = nil)
@@ -85,7 +92,7 @@ module Fluent
85
92
  desc 'The path where buffer chunks are stored.'
86
93
  config_param :buffer_path, :string
87
94
  desc 'If true, queued chunks are flushed at shutdown process.'
88
- config_param :flush_at_shutdown, :bool, :default => false
95
+ config_param :flush_at_shutdown, :bool, default: false
89
96
 
90
97
  # 'symlink_path' is currently only for out_file.
91
98
  # That is the reason why this is not config_param, but attr_accessor.
@@ -112,7 +119,7 @@ module Fluent
112
119
  end
113
120
 
114
121
  def start
115
- FileUtils.mkdir_p File.dirname(@buffer_path_prefix + "path"), :mode => DEFAULT_DIR_PERMISSION
122
+ FileUtils.mkdir_p File.dirname(@buffer_path_prefix + "path"), mode: DEFAULT_DIR_PERMISSION
116
123
  super
117
124
  end
118
125
 
@@ -14,6 +14,12 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
+ require 'stringio'
18
+
19
+ require 'fluent/engine'
20
+ require 'fluent/plugin'
21
+ require 'fluent/buffer'
22
+
17
23
  module Fluent
18
24
  class MemoryBufferChunk < BufferChunk
19
25
  def initialize(key, data='')
@@ -71,7 +77,7 @@ module Fluent
71
77
  end
72
78
 
73
79
  desc 'If true, queued chunks are flushed at shutdown process. Otherwise queued chunks are discarded'
74
- config_param :flush_at_shutdown, :bool, :default => true
80
+ config_param :flush_at_shutdown, :bool, default: true
75
81
  # Overwrite default BasicBuffer#buffer_queue_limit
76
82
  # to limit total memory usage upto 512MB.
77
83
  config_set_default :buffer_queue_limit, 64
@@ -14,10 +14,15 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
+ require 'msgpack'
18
+ require 'yajl'
19
+
20
+ require 'fluent/engine'
21
+ require 'fluent/plugin'
22
+ require 'fluent/parser'
23
+
17
24
  module Fluent
18
25
  module ExecUtil
19
- require 'fluent/parser'
20
-
21
26
  SUPPORTED_FORMAT = {
22
27
  'tsv' => :tsv,
23
28
  'json' => :json,
@@ -14,6 +14,9 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
+ require 'fluent/filter'
18
+ require 'fluent/config/error'
19
+
17
20
  module Fluent
18
21
  class GrepFilter < Filter
19
22
  Fluent::Plugin.register_filter('grep', self)
@@ -25,8 +28,8 @@ module Fluent
25
28
 
26
29
  REGEXP_MAX_NUM = 20
27
30
 
28
- (1..REGEXP_MAX_NUM).each {|i| config_param :"regexp#{i}", :string, :default => nil }
29
- (1..REGEXP_MAX_NUM).each {|i| config_param :"exclude#{i}", :string, :default => nil }
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 }
30
33
 
31
34
  # for test
32
35
  attr_reader :regexps
@@ -67,7 +70,7 @@ module Fluent
67
70
  result = record
68
71
  end
69
72
  rescue => e
70
- log.warn "failed to grep events", :error_class => e.class, :error => e.message
73
+ log.warn "failed to grep events", error_class: e.class, error: e.message
71
74
  log.warn_backtrace
72
75
  end
73
76
  result
@@ -14,29 +14,31 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
+ require 'socket'
18
+ require 'json'
17
19
  require 'ostruct'
18
20
 
21
+ require 'fluent/filter'
22
+ require 'fluent/config/error'
23
+ require 'fluent/event'
24
+ require 'fluent/time'
25
+
19
26
  module Fluent
20
27
  class RecordTransformerFilter < Filter
21
28
  Fluent::Plugin.register_filter('record_transformer', self)
22
29
 
23
- def initialize
24
- require 'socket'
25
- super
26
- end
27
-
28
30
  desc 'A comma-delimited list of keys to delete.'
29
- config_param :remove_keys, :string, :default => nil
31
+ config_param :remove_keys, :string, default: nil
30
32
  desc 'A comma-delimited list of keys to keep.'
31
- config_param :keep_keys, :string, :default => nil
33
+ config_param :keep_keys, :string, default: nil
32
34
  desc 'Create new Hash to transform incoming data'
33
- config_param :renew_record, :bool, :default => false
35
+ config_param :renew_record, :bool, default: false
34
36
  desc 'Specify field name of the record to overwrite the time of events. Its value must be unix time.'
35
- config_param :renew_time_key, :string, :default => nil
37
+ config_param :renew_time_key, :string, default: nil
36
38
  desc 'When set to true, the full Ruby syntax is enabled in the ${...} expression.'
37
- config_param :enable_ruby, :bool, :default => false
39
+ config_param :enable_ruby, :bool, default: false
38
40
  desc 'Use original value type.'
39
- config_param :auto_typecast, :bool, :default => false # false for lower version compatibility
41
+ config_param :auto_typecast, :bool, default: false # false for lower version compatibility
40
42
 
41
43
  def configure(conf)
42
44
  super
@@ -60,8 +62,8 @@ module Fluent
60
62
  end
61
63
 
62
64
  placeholder_expander_params = {
63
- :log => log,
64
- :auto_typecast => @auto_typecast,
65
+ log: log,
66
+ auto_typecast: @auto_typecast,
65
67
  }
66
68
  @placeholder_expander =
67
69
  if @enable_ruby
@@ -105,7 +107,7 @@ module Fluent
105
107
  end
106
108
  new_es
107
109
  rescue => e
108
- log.warn "failed to reform records", :error_class => e.class, :error => e.message
110
+ log.warn "failed to reform records", error_class: e.class, error: e.message
109
111
  log.warn_backtrace
110
112
  log.debug "map:#{@map} record:#{last_record} placeholder_values:#{placeholder_values}"
111
113
  end
@@ -119,33 +121,34 @@ module Fluent
119
121
  value_str
120
122
  end
121
123
  rescue => e
122
- 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_class: e.class, error: e.message
123
125
  value_str # emit as string
124
126
  end
125
127
 
126
128
  def reform(record, placeholder_values)
127
- @placeholder_expander.prepare_placeholders(placeholder_values)
129
+ placeholders = @placeholder_expander.prepare_placeholders(placeholder_values)
128
130
 
129
131
  new_record = @renew_record ? {} : record.dup
130
132
  @keep_keys.each {|k| new_record[k] = record[k]} if @keep_keys and @renew_record
131
- new_record.merge!(expand_placeholders(@map))
133
+ new_record.merge!(expand_placeholders(@map, placeholders))
132
134
  @remove_keys.each {|k| new_record.delete(k) } if @remove_keys
133
135
 
134
136
  new_record
135
137
  end
136
138
 
137
- def expand_placeholders(value)
139
+ def expand_placeholders(value, placeholders)
138
140
  if value.is_a?(String)
139
- new_value = @placeholder_expander.expand(value)
141
+ new_value = @placeholder_expander.expand(value, placeholders)
140
142
  elsif value.is_a?(Hash)
141
143
  new_value = {}
142
144
  value.each_pair do |k, v|
143
- new_value[@placeholder_expander.expand(k, true)] = expand_placeholders(v)
145
+ new_key = @placeholder_expander.expand(k, placeholders, true)
146
+ new_value[new_key] = expand_placeholders(v, placeholders)
144
147
  end
145
148
  elsif value.is_a?(Array)
146
149
  new_value = []
147
150
  value.each_with_index do |v, i|
148
- new_value[i] = expand_placeholders(v)
151
+ new_value[i] = expand_placeholders(v, placeholders)
149
152
  end
150
153
  else
151
154
  new_value = value
@@ -172,6 +175,7 @@ module Fluent
172
175
  rev_tag_suffix.reverse!
173
176
  end
174
177
 
178
+ # THIS CLASS MUST BE THREAD-SAFE
175
179
  class PlaceholderExpander
176
180
  attr_reader :placeholders, :log
177
181
 
@@ -208,36 +212,37 @@ module Fluent
208
212
  end
209
213
  end
210
214
 
211
- @placeholders = placeholders
215
+ placeholders
212
216
  end
213
217
 
214
218
  # Expand string with placeholders
215
219
  #
216
220
  # @param [String] str
217
221
  # @param [Boolean] force_stringify the value must be string, used for hash key
218
- def expand(str, force_stringify = false)
222
+ def expand(str, placeholders, force_stringify = false)
219
223
  if @auto_typecast and !force_stringify
220
224
  single_placeholder_matched = str.match(/\A(\${[^}]+}|__[A-Z_]+__)\z/)
221
225
  if single_placeholder_matched
222
- log_if_unknown_placeholder($1)
223
- return @placeholders[single_placeholder_matched[1]]
226
+ log_if_unknown_placeholder($1, placeholders)
227
+ return placeholders[single_placeholder_matched[1]]
224
228
  end
225
229
  end
226
230
  str.gsub(/(\${[^}]+}|__[A-Z_]+__)/) {
227
- log_if_unknown_placeholder($1)
228
- @placeholders[$1]
231
+ log_if_unknown_placeholder($1, placeholders)
232
+ placeholders[$1]
229
233
  }
230
234
  end
231
235
 
232
236
  private
233
237
 
234
- def log_if_unknown_placeholder(placeholder)
235
- unless @placeholders.include?(placeholder)
238
+ def log_if_unknown_placeholder(placeholder, placeholders)
239
+ unless placeholders.include?(placeholder)
236
240
  log.warn "unknown placeholder `#{placeholder}` found"
237
241
  end
238
242
  end
239
243
  end
240
244
 
245
+ # THIS CLASS MUST BE THREAD-SAFE
241
246
  class RubyPlaceholderExpander
242
247
  attr_reader :log
243
248
 
@@ -259,12 +264,13 @@ module Fluent
259
264
  new_value = nil
260
265
  if value.is_a?(String)
261
266
  if @auto_typecast and !force_stringify
262
- if single_placeholder_matched = value.match(/\A\${([^}]+)}\z/) # ${..} => ..
263
- new_value = single_placeholder_matched[1]
267
+ num_placeholders = value.scan('${').size
268
+ if num_placeholders == 1 and value.start_with?('${') && value.end_with?('}')
269
+ new_value = value[2..-2] # ${..} => ..
264
270
  end
265
271
  end
266
272
  unless new_value
267
- new_value = %Q{%Q[#{value.gsub(/\$\{([^}]+)\}/, '#{\1}')}]} # xx${..}xx => %Q[xx#{..}xx]
273
+ new_value = "%Q[#{value.gsub('${', '#{')}]" # xx${..}xx => %Q[xx#{..}xx]
268
274
  end
269
275
  elsif value.is_a?(Hash)
270
276
  new_value = {}
@@ -283,31 +289,25 @@ module Fluent
283
289
  end
284
290
 
285
291
  def prepare_placeholders(placeholder_values)
286
- @tag = placeholder_values['tag']
287
- @time = placeholder_values['time']
288
- @record = placeholder_values['record']
289
- @tag_parts = placeholder_values['tag_parts']
290
- @tag_prefix = placeholder_values['tag_prefix']
291
- @tag_suffix = placeholder_values['tag_suffix']
292
- @hostname = placeholder_values['hostname']
292
+ placeholder_values
293
293
  end
294
294
 
295
295
  # Expand string with placeholders
296
296
  #
297
297
  # @param [String] str
298
- def expand(str, force_stringify = false)
298
+ def expand(str, placeholders, force_stringify = false)
299
299
  @cleanroom_expander.expand(
300
300
  str,
301
- @tag,
302
- @time,
303
- @record,
304
- @tag_parts,
305
- @tag_prefix,
306
- @tag_suffix,
307
- @hostname,
301
+ placeholders['tag'],
302
+ placeholders['time'],
303
+ placeholders['record'],
304
+ placeholders['tag_parts'],
305
+ placeholders['tag_prefix'],
306
+ placeholders['tag_suffix'],
307
+ placeholders['hostname'],
308
308
  )
309
309
  rescue => e
310
- log.warn "failed to expand `#{str}`", :error_class => e.class, :error => e.message
310
+ log.warn "failed to expand `#{str}`", error_class: e.class, error: e.message
311
311
  log.warn_backtrace
312
312
  nil
313
313
  end
@@ -315,15 +315,16 @@ module Fluent
315
315
  class CleanroomExpander
316
316
  def expand(__str_to_eval__, tag, time, record, tag_parts, tag_prefix, tag_suffix, hostname)
317
317
  tags = tag_parts # for old version compatibility
318
- @record = record # for old version compatibility
318
+ Thread.current[:record_transformer_record] = record # for old version compatibility
319
319
  instance_eval(__str_to_eval__)
320
320
  end
321
321
 
322
322
  # for old version compatibility
323
323
  def method_missing(name)
324
324
  key = name.to_s
325
- if @record.has_key?(key)
326
- @record[key]
325
+ record = Thread.current[:record_transformer_record]
326
+ if record.has_key?(key)
327
+ record[key]
327
328
  else
328
329
  raise NameError, "undefined local variable or method `#{key}'"
329
330
  end