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,6 +14,9 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
+ require 'fluent/filter'
18
+ require 'fluent/plugin'
19
+
17
20
  module Fluent
18
21
  class StdoutFilter < Filter
19
22
  Plugin.register_filter('stdout', self)
@@ -22,7 +25,7 @@ module Fluent
22
25
  attr_reader :formatter
23
26
 
24
27
  desc 'The format of the output.'
25
- config_param :format, :string, :default => 'stdout'
28
+ config_param :format, :string, default: 'stdout'
26
29
  # config_param :output_type, :string, :default => 'json' (StdoutFormatter defines this)
27
30
 
28
31
  def configure(conf)
@@ -14,6 +14,8 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
+ require 'fluent/input'
18
+
17
19
  module Fluent
18
20
  class DebugAgentInput < Input
19
21
  Plugin.register_input('debug_agent', self)
@@ -24,11 +26,11 @@ module Fluent
24
26
  super
25
27
  end
26
28
 
27
- config_param :bind, :string, :default => '0.0.0.0'
28
- config_param :port, :integer, :default => 24230
29
- config_param :unix_path, :string, :default => nil
29
+ config_param :bind, :string, default: '0.0.0.0'
30
+ config_param :port, :integer, default: 24230
31
+ config_param :unix_path, :string, default: nil
30
32
  #config_param :unix_mode # TODO
31
- config_param :object, :string, :default => 'Engine'
33
+ config_param :object, :string, default: 'Engine'
32
34
 
33
35
  def configure(conf)
34
36
  super
@@ -46,7 +48,7 @@ module Fluent
46
48
  else
47
49
  uri = "druby://#{@bind}:#{@port}"
48
50
  end
49
- log.info "listening dRuby", :uri => uri, :object => @object
51
+ log.info "listening dRuby", uri: uri, object: @object
50
52
  obj = eval(@object)
51
53
  @server = DRb::DRbServer.new(uri, obj)
52
54
  end
@@ -14,6 +14,11 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
+ require 'json'
18
+
19
+ require 'fluent/input'
20
+ require 'fluent/config/error'
21
+
17
22
  module Fluent
18
23
  class DummyInput < Input
19
24
  Fluent::Plugin.register_input('dummy', self)
@@ -23,11 +28,11 @@ module Fluent
23
28
  desc "The value is the tag assigned to the generated events."
24
29
  config_param :tag, :string
25
30
  desc "It configures how many events to generate per second."
26
- config_param :rate, :integer, :default => 1
31
+ config_param :rate, :integer, default: 1
27
32
  desc "If specified, each generated event has an auto-incremented key field."
28
- config_param :auto_increment_key, :string, :default => nil
33
+ config_param :auto_increment_key, :string, default: nil
29
34
  desc "The dummy data to be generated. An array of JSON hashes or a single JSON hash."
30
- config_param :dummy, :default => [{"message"=>"dummy"}] do |val|
35
+ config_param :dummy, default: [{"message"=>"dummy"}] do |val|
31
36
  begin
32
37
  parsed = JSON.parse(val)
33
38
  rescue JSON::ParserError => e
@@ -14,6 +14,13 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
+ require 'yajl'
18
+
19
+ require 'fluent/input'
20
+ require 'fluent/time'
21
+ require 'fluent/timezone'
22
+ require 'fluent/config/error'
23
+
17
24
  module Fluent
18
25
  class ExecInput < Input
19
26
  Plugin.register_input('exec', self)
@@ -21,27 +28,26 @@ module Fluent
21
28
  def initialize
22
29
  super
23
30
  require 'fluent/plugin/exec_util'
24
- require 'fluent/timezone'
25
31
  end
26
32
 
27
33
  desc 'The command (program) to execute.'
28
34
  config_param :command, :string
29
35
  desc 'The format used to map the program output to the incoming event.(tsv,json,msgpack)'
30
- config_param :format, :string, :default => 'tsv'
36
+ config_param :format, :string, default: 'tsv'
31
37
  desc 'Specify the comma-separated keys when using the tsv format.'
32
- config_param :keys, :default => [] do |val|
38
+ config_param :keys, default: [] do |val|
33
39
  val.split(',')
34
40
  end
35
41
  desc 'Tag of the output events.'
36
- config_param :tag, :string, :default => nil
42
+ config_param :tag, :string, default: nil
37
43
  desc 'The key to use as the event tag instead of the value in the event record. '
38
- config_param :tag_key, :string, :default => nil
44
+ config_param :tag_key, :string, default: nil
39
45
  desc 'The key to use as the event time instead of the value in the event record.'
40
- config_param :time_key, :string, :default => nil
46
+ config_param :time_key, :string, default: nil
41
47
  desc 'The format of the event time used for the time_key parameter.'
42
- config_param :time_format, :string, :default => nil
48
+ config_param :time_format, :string, default: nil
43
49
  desc 'The interval time between periodic program runs.'
44
- config_param :run_interval, :time, :default => nil
50
+ config_param :run_interval, :time, default: nil
45
51
 
46
52
  def configure(conf)
47
53
  super
@@ -136,7 +142,7 @@ module Fluent
136
142
  Process.waitpid(io.pid)
137
143
  sleep @run_interval
138
144
  rescue
139
- log.error "exec failed to run or shutdown child process", :error => $!.to_s, :error_class => $!.class.to_s
145
+ log.error "exec failed to run or shutdown child process", error: $!.to_s, error_class: $!.class.to_s
140
146
  log.warn_backtrace $!.backtrace
141
147
  end
142
148
  end
@@ -163,7 +169,7 @@ module Fluent
163
169
 
164
170
  router.emit(tag, time, record)
165
171
  rescue => e
166
- log.error "exec failed to emit", :error => e.to_s, :error_class => e.class.to_s, :tag => tag, :record => Yajl.dump(record)
172
+ log.error "exec failed to emit", error: e.to_s, error_class: e.class.to_s, tag: tag, record: Yajl.dump(record)
167
173
  end
168
174
  end
169
175
  end
@@ -14,6 +14,13 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
+ require 'fcntl'
18
+
19
+ require 'cool.io'
20
+ require 'yajl'
21
+
22
+ require 'fluent/input'
23
+
17
24
  module Fluent
18
25
  class ForwardInput < Input
19
26
  Plugin.register_input('forward', self)
@@ -24,22 +31,22 @@ module Fluent
24
31
  end
25
32
 
26
33
  desc 'The port to listen to.'
27
- config_param :port, :integer, :default => DEFAULT_LISTEN_PORT
34
+ config_param :port, :integer, default: DEFAULT_LISTEN_PORT
28
35
  desc 'The bind address to listen to.'
29
- config_param :bind, :string, :default => '0.0.0.0'
30
- config_param :backlog, :integer, :default => nil
36
+ config_param :bind, :string, default: '0.0.0.0'
37
+ config_param :backlog, :integer, default: nil
31
38
  # SO_LINGER 0 to send RST rather than FIN to avoid lots of connections sitting in TIME_WAIT at src
32
39
  desc 'The timeout time used to set linger option.'
33
- config_param :linger_timeout, :integer, :default => 0
40
+ config_param :linger_timeout, :integer, default: 0
34
41
  # This option is for Cool.io's loop wait timeout to avoid loop stuck at shutdown. Almost users don't need to change this value.
35
- config_param :blocking_timeout, :time, :default => 0.5
42
+ config_param :blocking_timeout, :time, default: 0.5
36
43
 
37
44
  desc 'Log warning if received chunk size is larger than this value.'
38
- config_param :chunk_size_warn_limit, :size, :default => nil
45
+ config_param :chunk_size_warn_limit, :size, default: nil
39
46
  desc 'Received chunk is dropped if it is larger than this value.'
40
- config_param :chunk_size_limit, :size, :default => nil
47
+ config_param :chunk_size_limit, :size, default: nil
41
48
  desc 'Skip an event if incoming event is invalid.'
42
- config_param :skip_invalid_event, :bool, :default => false
49
+ config_param :skip_invalid_event, :bool, default: false
43
50
 
44
51
  def configure(conf)
45
52
  super
@@ -97,7 +104,7 @@ module Fluent
97
104
  def run
98
105
  @loop.run(@blocking_timeout)
99
106
  rescue => e
100
- log.error "unexpected error", :error => e, :error_class => e.class
107
+ log.error "unexpected error", error: e, error_class: e.class
101
108
  log.error_backtrace
102
109
  end
103
110
 
@@ -265,7 +272,7 @@ module Fluent
265
272
  @chunk_counter += data.bytesize
266
273
  @y << data
267
274
  rescue => e
268
- @log.error "forward error", :error => e, :error_class => e.class
275
+ @log.error "forward error", error: e, error_class: e.class
269
276
  @log.error_backtrace
270
277
  close
271
278
  end
@@ -278,7 +285,7 @@ module Fluent
278
285
  @chunk_counter = 0
279
286
  end
280
287
  rescue => e
281
- @log.error "forward error", :error => e, :error_class => e.class
288
+ @log.error "forward error", error: e, error_class: e.class
282
289
  @log.error_backtrace
283
290
  close
284
291
  end
@@ -14,6 +14,10 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
+ require 'cool.io'
18
+
19
+ require 'fluent/input'
20
+
17
21
  module Fluent
18
22
  class GCStatInput < Input
19
23
  Plugin.register_input('gc_stat', self)
@@ -22,7 +26,7 @@ module Fluent
22
26
  super
23
27
  end
24
28
 
25
- config_param :emit_interval, :time, :default => 60
29
+ config_param :emit_interval, :time, default: 60
26
30
  config_param :tag, :string
27
31
 
28
32
  class TimerWatcher < Coolio::TimerWatcher
@@ -61,7 +65,7 @@ module Fluent
61
65
  def run
62
66
  @loop.run
63
67
  rescue
64
- log.error "unexpected error", :error=>$!.to_s
68
+ log.error "unexpected error", error: $!.to_s
65
69
  log.error_backtrace
66
70
  end
67
71
 
@@ -14,6 +14,16 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
+ require 'uri'
18
+ require 'socket'
19
+ require 'json'
20
+
21
+ require 'cool.io'
22
+
23
+ require 'fluent/input'
24
+ require 'fluent/event'
25
+ require 'fluent/process'
26
+
17
27
  module Fluent
18
28
  class HttpInput < Input
19
29
  Plugin.register_input('http', self)
@@ -24,32 +34,31 @@ module Fluent
24
34
 
25
35
  def initialize
26
36
  require 'webrick/httputils'
27
- require 'uri'
28
37
  super
29
38
  end
30
39
 
31
40
  EMPTY_GIF_IMAGE = "GIF89a\u0001\u0000\u0001\u0000\x80\xFF\u0000\xFF\xFF\xFF\u0000\u0000\u0000,\u0000\u0000\u0000\u0000\u0001\u0000\u0001\u0000\u0000\u0002\u0002D\u0001\u0000;".force_encoding("UTF-8")
32
41
 
33
42
  desc 'The port to listen to.'
34
- config_param :port, :integer, :default => 9880
43
+ config_param :port, :integer, default: 9880
35
44
  desc 'The bind address to listen to.'
36
- config_param :bind, :string, :default => '0.0.0.0'
45
+ config_param :bind, :string, default: '0.0.0.0'
37
46
  desc 'The size limit of the POSTed element. Default is 32MB.'
38
- config_param :body_size_limit, :size, :default => 32*1024*1024 # TODO default
47
+ config_param :body_size_limit, :size, default: 32*1024*1024 # TODO default
39
48
  desc 'The timeout limit for keeping the connection alive.'
40
- config_param :keepalive_timeout, :time, :default => 10 # TODO default
41
- config_param :backlog, :integer, :default => nil
49
+ config_param :keepalive_timeout, :time, default: 10 # TODO default
50
+ config_param :backlog, :integer, default: nil
42
51
  desc 'Add HTTP_ prefix headers to the record.'
43
- config_param :add_http_headers, :bool, :default => false
52
+ config_param :add_http_headers, :bool, default: false
44
53
  desc 'Add REMOTE_ADDR header to the record.'
45
- config_param :add_remote_addr, :bool, :default => false
54
+ config_param :add_remote_addr, :bool, default: false
46
55
  desc 'The format of the HTTP body.'
47
- config_param :format, :string, :default => 'default'
48
- config_param :blocking_timeout, :time, :default => 0.5
56
+ config_param :format, :string, default: 'default'
57
+ config_param :blocking_timeout, :time, default: 0.5
49
58
  desc 'Set a white list of domains that can do CORS (Cross-Origin Resource Sharing)'
50
- config_param :cors_allow_origins, :array, :default => nil
59
+ config_param :cors_allow_origins, :array, default: nil
51
60
  desc 'Respond with empty gif image of 1x1 pixel.'
52
- config_param :respond_with_empty_img, :bool, :default => false
61
+ config_param :respond_with_empty_img, :bool, default: false
53
62
 
54
63
  def configure(conf)
55
64
  super
@@ -121,7 +130,7 @@ module Fluent
121
130
  def run
122
131
  @loop.run(@blocking_timeout)
123
132
  rescue
124
- log.error "unexpected error", :error=>$!.to_s
133
+ log.error "unexpected error", error: $!.to_s
125
134
  log.error_backtrace
126
135
  end
127
136
 
@@ -254,7 +263,7 @@ module Fluent
254
263
  @idle = 0
255
264
  @parser << data
256
265
  rescue
257
- @log.warn "unexpected error", :error=>$!.to_s
266
+ @log.warn "unexpected error", error: $!.to_s
258
267
  @log.warn_backtrace
259
268
  close
260
269
  end
@@ -14,21 +14,24 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
+ require 'json'
18
+ require 'webrick'
19
+ require 'cgi'
20
+
21
+ require 'cool.io'
22
+
23
+ require 'fluent/input'
24
+ require 'fluent/output'
25
+ require 'fluent/filter'
26
+
17
27
  module Fluent
18
28
  class MonitorAgentInput < Input
19
29
  Plugin.register_input('monitor_agent', self)
20
30
 
21
- require 'webrick'
22
-
23
- def initialize
24
- require 'cgi'
25
- super
26
- end
27
-
28
- config_param :bind, :string, :default => '0.0.0.0'
29
- config_param :port, :integer, :default => 24220
30
- config_param :tag, :string, :default => nil
31
- config_param :emit_interval, :time, :default => 60
31
+ config_param :bind, :string, default: '0.0.0.0'
32
+ config_param :port, :integer, default: 24220
33
+ config_param :tag, :string, default: nil
34
+ config_param :emit_interval, :time, default: 60
32
35
 
33
36
  class MonitorServlet < WEBrick::HTTPServlet::AbstractServlet
34
37
  def initialize(server, agent)
@@ -234,10 +237,10 @@ module Fluent
234
237
  def start
235
238
  log.debug "listening monitoring http server on http://#{@bind}:#{@port}/api/plugins"
236
239
  @srv = WEBrick::HTTPServer.new({
237
- :BindAddress => @bind,
238
- :Port => @port,
239
- :Logger => WEBrick::Log.new(STDERR, WEBrick::Log::FATAL),
240
- :AccessLog => [],
240
+ BindAddress: @bind,
241
+ Port: @port,
242
+ Logger: WEBrick::Log.new(STDERR, WEBrick::Log::FATAL),
243
+ AccessLog: [],
241
244
  })
242
245
  @srv.mount('/api/plugins', LTSVMonitorServlet, self)
243
246
  @srv.mount('/api/plugins.json', JSONMonitorServlet, self)
@@ -250,7 +253,7 @@ module Fluent
250
253
  log.debug "tag parameter is specified. Emit plugins info to '#{@tag}'"
251
254
 
252
255
  @loop = Coolio::Loop.new
253
- opts = {:with_config => false}
256
+ opts = {with_config: false}
254
257
  timer = TimerWatcher.new(@emit_interval, log) {
255
258
  es = MultiEventStream.new
256
259
  now = Engine.now
@@ -267,7 +270,7 @@ module Fluent
267
270
  def run
268
271
  @loop.run
269
272
  rescue => e
270
- log.error "unexpected error", :error => e.to_s
273
+ log.error "unexpected error", error: e.to_s
271
274
  log.error_backtrace
272
275
  end
273
276
 
@@ -374,6 +377,9 @@ module Fluent
374
377
  }
375
378
  end
376
379
 
380
+ # TODO: use %i() after drop ruby v1.9.3 support.
381
+ IGNORE_ATTRIBUTES = %W(@config_root_section @config @masked_config).map(&:to_sym)
382
+
377
383
  # get monitor info from the plugin `pe` and return a hash object
378
384
  def get_monitor_info(pe, opts={})
379
385
  obj = {}
@@ -397,6 +403,7 @@ module Fluent
397
403
  iv = {}
398
404
  pe.instance_eval do
399
405
  instance_variables.each {|sym|
406
+ next if IGNORE_ATTRIBUTES.include?(sym)
400
407
  key = sym.to_s[1..-1] # removes first '@'
401
408
  iv[key] = instance_variable_get(sym)
402
409
  }
@@ -14,6 +14,11 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
+ require 'cool.io'
18
+ require 'yajl'
19
+
20
+ require 'fluent/input'
21
+
17
22
  module Fluent
18
23
  class ObjectSpaceInput < Input
19
24
  Plugin.register_input('object_space', self)
@@ -22,9 +27,9 @@ module Fluent
22
27
  super
23
28
  end
24
29
 
25
- config_param :emit_interval, :time, :default => 60
30
+ config_param :emit_interval, :time, default: 60
26
31
  config_param :tag, :string
27
- config_param :top, :integer, :default => 15
32
+ config_param :top, :integer, default: 15
28
33
 
29
34
  class TimerWatcher < Coolio::TimerWatcher
30
35
  def initialize(interval, repeat, log, &callback)
@@ -62,7 +67,7 @@ module Fluent
62
67
  def run
63
68
  @loop.run
64
69
  rescue
65
- log.error "unexpected error", :error=>$!.to_s
70
+ log.error "unexpected error", error: $!.to_s
66
71
  log.error_backtrace
67
72
  end
68
73
 
@@ -110,7 +115,7 @@ module Fluent
110
115
 
111
116
  router.emit(@tag, now, record)
112
117
  rescue => e
113
- log.error "object space failed to emit", :error => e.to_s, :error_class => e.class.to_s, :tag => @tag, :record => Yajl.dump(record)
118
+ log.error "object space failed to emit", error: e.to_s, error_class: e.class.to_s, tag: @tag, record: Yajl.dump(record)
114
119
  end
115
120
  end
116
121
  end