lumberjack 1.2.4 → 1.2.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -8,30 +8,30 @@ module Lumberjack
8
8
  # production.log.1, then production.log.2, etc.
9
9
  class SizeRollingLogFile < RollingLogFile
10
10
  attr_reader :max_size
11
-
11
+
12
12
  # Create an new log device to the specified file. The maximum size of the log file is specified with
13
13
  # the :max_size option. The unit can also be specified: "32K", "100M", "2G" are all valid.
14
14
  def initialize(path, options = {})
15
15
  @manual = options[:manual]
16
16
  @max_size = options[:max_size]
17
17
  if @max_size.is_a?(String)
18
- if @max_size.match(/^(\d+(\.\d+)?)([KMG])?$/i)
18
+ if @max_size =~ /^(\d+(\.\d+)?)([KMG])?$/i
19
19
  @max_size = $~[1].to_f
20
20
  units = $~[3].to_s.upcase
21
21
  case units
22
22
  when "K"
23
23
  @max_size *= 1024
24
24
  when "M"
25
- @max_size *= 1024 ** 2
25
+ @max_size *= 1024**2
26
26
  when "G"
27
- @max_size *= 1024 ** 3
27
+ @max_size *= 1024**3
28
28
  end
29
29
  @max_size = @max_size.round
30
30
  else
31
31
  raise ArgumentError.new("illegal value for :max_size (#{@max_size})")
32
32
  end
33
33
  end
34
-
34
+
35
35
  super
36
36
  end
37
37
 
@@ -44,15 +44,15 @@ module Lumberjack
44
44
  rescue SystemCallError
45
45
  false
46
46
  end
47
-
47
+
48
48
  protected
49
-
49
+
50
50
  # Calculate the next archive file name extension.
51
51
  def next_archive_number # :nodoc:
52
52
  max = 0
53
53
  Dir.glob("#{path}.*").each do |filename|
54
- if filename.match(/\.\d+$/)
55
- suffix = filename.split('.').last.to_i
54
+ if /\.\d+\z/ =~ filename
55
+ suffix = filename.split(".").last.to_i
56
56
  max = suffix if suffix > max
57
57
  end
58
58
  end
@@ -71,7 +71,7 @@ module Lumberjack
71
71
  @template = template
72
72
  else
73
73
  additional_lines = (options[:additional_lines] || DEFAULT_ADDITIONAL_LINES_TEMPLATE)
74
- @template = Template.new(template, :additional_lines => additional_lines, :time_format => options[:time_format])
74
+ @template = Template.new(template, additional_lines: additional_lines, time_format: options[:time_format])
75
75
  end
76
76
  end
77
77
 
@@ -133,14 +133,10 @@ module Lumberjack
133
133
  protected
134
134
 
135
135
  # Set the underlying stream.
136
- def stream=(stream)
137
- @stream = stream
138
- end
136
+ attr_writer :stream
139
137
 
140
138
  # Get the underlying stream.
141
- def stream
142
- @stream
143
- end
139
+ attr_reader :stream
144
140
 
145
141
  private
146
142
 
@@ -149,10 +145,10 @@ module Lumberjack
149
145
  lines = lines.first if lines.is_a?(Array) && lines.size == 1
150
146
 
151
147
  out = nil
152
- if lines.is_a?(Array)
153
- out = "#{lines.join(Lumberjack::LINE_SEPARATOR)}#{Lumberjack::LINE_SEPARATOR}"
148
+ out = if lines.is_a?(Array)
149
+ "#{lines.join(Lumberjack::LINE_SEPARATOR)}#{Lumberjack::LINE_SEPARATOR}"
154
150
  else
155
- out = "#{lines}#{Lumberjack::LINE_SEPARATOR}"
151
+ "#{lines}#{Lumberjack::LINE_SEPARATOR}"
156
152
  end
157
153
 
158
154
  begin
@@ -170,9 +166,13 @@ module Lumberjack
170
166
  end
171
167
  end
172
168
  end
173
- stream.flush rescue nil
169
+ begin
170
+ stream.flush
171
+ rescue
172
+ nil
173
+ end
174
174
  rescue => e
175
- $stderr.write("#{e.class.name}: #{e.message}#{' at ' + e.backtrace.first if e.backtrace}")
175
+ $stderr.write("#{e.class.name}: #{e.message}#{" at " + e.backtrace.first if e.backtrace}")
176
176
  $stderr.write(out)
177
177
  $stderr.flush
178
178
  end
@@ -12,15 +12,15 @@ module Lumberjack
12
12
  #
13
13
  # Enumerable objects (including Hash and Array) will call the formatter recursively for each element.
14
14
  class Formatter
15
- require_relative "formatter/date_time_formatter.rb"
16
- require_relative "formatter/exception_formatter.rb"
17
- require_relative "formatter/id_formatter.rb"
18
- require_relative "formatter/inspect_formatter.rb"
19
- require_relative "formatter/object_formatter.rb"
20
- require_relative "formatter/pretty_print_formatter.rb"
21
- require_relative "formatter/string_formatter.rb"
22
- require_relative "formatter/strip_formatter.rb"
23
- require_relative "formatter/structured_formatter.rb"
15
+ require_relative "formatter/date_time_formatter"
16
+ require_relative "formatter/exception_formatter"
17
+ require_relative "formatter/id_formatter"
18
+ require_relative "formatter/inspect_formatter"
19
+ require_relative "formatter/object_formatter"
20
+ require_relative "formatter/pretty_print_formatter"
21
+ require_relative "formatter/string_formatter"
22
+ require_relative "formatter/strip_formatter"
23
+ require_relative "formatter/structured_formatter"
24
24
 
25
25
  class << self
26
26
  # Returns a new empty formatter with no mapping. For historical reasons, a formatter
@@ -30,7 +30,7 @@ module Lumberjack
30
30
  new.clear
31
31
  end
32
32
  end
33
-
33
+
34
34
  def initialize
35
35
  @class_formatters = {}
36
36
  @module_formatters = {}
@@ -72,10 +72,10 @@ module Lumberjack
72
72
  remove(klass)
73
73
  else
74
74
  if formatter.is_a?(Symbol)
75
- formatter_class_name = "#{formatter.to_s.gsub(/(^|_)([a-z])/){|m| $~[2].upcase}}Formatter"
75
+ formatter_class_name = "#{formatter.to_s.gsub(/(^|_)([a-z])/) { |m| $~[2].upcase }}Formatter"
76
76
  formatter = Formatter.const_get(formatter_class_name).new
77
77
  end
78
-
78
+
79
79
  Array(klass).each do |k|
80
80
  if k.class == Module
81
81
  @module_formatters[k] = formatter
@@ -106,7 +106,7 @@ module Lumberjack
106
106
  end
107
107
  self
108
108
  end
109
-
109
+
110
110
  # Remove all formatters including the default formatter. Can be chained to add method calls.
111
111
  def clear
112
112
  @class_formatters.clear
@@ -117,7 +117,7 @@ module Lumberjack
117
117
  # Format a message object as a string.
118
118
  def format(message)
119
119
  formatter = formatter_for(message.class)
120
- if formatter && formatter.respond_to?(:call)
120
+ if formatter&.respond_to?(:call)
121
121
  formatter.call(message)
122
122
  else
123
123
  message
@@ -135,7 +135,7 @@ module Lumberjack
135
135
  # Find the formatter for a class by looking it up using the class hierarchy.
136
136
  def formatter_for(klass) #:nodoc:
137
137
  check_modules = true
138
- while klass != nil do
138
+ until klass.nil?
139
139
  formatter = @class_formatters[klass.name]
140
140
  return formatter if formatter
141
141
 
@@ -5,13 +5,12 @@ module Lumberjack
5
5
  # Format a Date, Time, or DateTime object. If you don't specify a format in the constructor,
6
6
  # it will use the ISO-8601 format.
7
7
  class DateTimeFormatter
8
-
9
8
  attr_reader :format
10
-
9
+
11
10
  def initialize(format = nil)
12
11
  @format = format.dup.to_s.freeze unless format.nil?
13
12
  end
14
-
13
+
15
14
  def call(obj)
16
15
  if @format && obj.respond_to?(:strftime)
17
16
  obj.strftime(@format)
@@ -7,7 +7,6 @@ module Lumberjack
7
7
  # passed to this object and the returned array is what will be logged. You can
8
8
  # use this to clean out superfluous lines.
9
9
  class ExceptionFormatter
10
-
11
10
  attr_accessor :backtrace_cleaner
12
11
 
13
12
  def initialize(backtrace_cleaner = nil)
@@ -33,7 +32,6 @@ module Lumberjack
33
32
  trace
34
33
  end
35
34
  end
36
-
37
35
  end
38
36
  end
39
37
  end
@@ -9,11 +9,11 @@ module Lumberjack
9
9
  def initialize(id_attribute = :id)
10
10
  @id_attribute = id_attribute
11
11
  end
12
-
12
+
13
13
  def call(obj)
14
14
  if obj.respond_to?(@id_attribute)
15
15
  id = obj.send(@id_attribute)
16
- { "class" => obj.class.name, "id" => id }
16
+ {"class" => obj.class.name, "id" => id}
17
17
  else
18
18
  obj.to_s
19
19
  end
@@ -1,20 +1,20 @@
1
1
  # frozen_string_literals: true
2
2
 
3
- require 'pp'
4
- require 'stringio'
3
+ require "pp"
4
+ require "stringio"
5
5
 
6
6
  module Lumberjack
7
7
  class Formatter
8
8
  # Format an object with it's pretty print method.
9
9
  class PrettyPrintFormatter
10
10
  attr_accessor :width
11
-
11
+
12
12
  # Create a new formatter. The maximum width of the message can be specified with the width
13
13
  # parameter (defaults to 79 characters).
14
14
  def initialize(width = 79)
15
15
  @width = width
16
16
  end
17
-
17
+
18
18
  def call(obj)
19
19
  s = StringIO.new
20
20
  PP.pp(obj, s)
@@ -6,6 +6,9 @@ module Lumberjack
6
6
  class Formatter
7
7
  # Dereference arrays and hashes and recursively call formatters on each element.
8
8
  class StructuredFormatter
9
+ class RecusiveReferenceError < StandardError
10
+ end
11
+
9
12
  def initialize(formatter = nil)
10
13
  @formatter = formatter
11
14
  end
@@ -18,31 +21,43 @@ module Lumberjack
18
21
 
19
22
  def call_with_references(obj, references)
20
23
  if obj.is_a?(Hash)
21
- hash = {}
22
- references << obj.object_id
23
- obj.each do |name, value|
24
- next if references.include?(value.object_id)
25
- references << value
26
- hash[name.to_s] = call_with_references(value, references)
24
+ with_object_reference(obj, references) do
25
+ hash = {}
26
+ obj.each do |name, value|
27
+ value = call_with_references(value, references)
28
+ hash[name.to_s] = value unless value.is_a?(RecusiveReferenceError)
29
+ end
30
+ hash
27
31
  end
28
- references.delete(obj.object_id)
29
- hash
30
32
  elsif obj.is_a?(Enumerable) && obj.respond_to?(:size) && obj.size != Float::INFINITY
31
- array = []
32
- references << obj.object_id
33
- obj.each do |value|
34
- next if references.include?(value.object_id)
35
- references << value
36
- array << call_with_references(value, references)
33
+ with_object_reference(obj, references) do
34
+ array = []
35
+ obj.each do |value|
36
+ value = call_with_references(value, references)
37
+ array << value unless value.is_a?(RecusiveReferenceError)
38
+ end
39
+ array
37
40
  end
38
- references.delete(obj.object_id)
39
- array
40
41
  elsif @formatter
41
42
  @formatter.format(obj)
42
43
  else
43
44
  obj
44
45
  end
45
46
  end
47
+
48
+ def with_object_reference(obj, references)
49
+ if obj.is_a?(Enumerable)
50
+ return RecusiveReferenceError.new if references.include?(obj.object_id)
51
+ references << obj.object_id
52
+ begin
53
+ yield
54
+ ensure
55
+ references.delete(obj.object_id)
56
+ end
57
+ else
58
+ yield
59
+ end
60
+ end
46
61
  end
47
62
  end
48
63
  end
@@ -17,10 +17,10 @@ module Lumberjack
17
17
  @progname = progname
18
18
  @pid = pid
19
19
  # backward compatibility with 1.0 API where the last argument was the unit of work id
20
- if tags.nil? || tags.is_a?(Hash)
21
- @tags = tags
20
+ @tags = if tags.nil? || tags.is_a?(Hash)
21
+ tags
22
22
  else
23
- @tags = { UNIT_OF_WORK_ID => tags }
23
+ {UNIT_OF_WORK_ID => tags}
24
24
  end
25
25
  end
26
26
 
@@ -29,7 +29,7 @@ module Lumberjack
29
29
  end
30
30
 
31
31
  def to_s
32
- "[#{time.strftime(TIME_FORMAT)}.#{(time.usec / 1000.0).round.to_s.rjust(3, '0')} #{severity_label} #{progname}(#{pid})#{tags_to_s}] #{message}"
32
+ "[#{time.strftime(TIME_FORMAT)}.#{(time.usec / 1000.0).round.to_s.rjust(3, "0")} #{severity_label} #{progname}(#{pid})#{tags_to_s}] #{message}"
33
33
  end
34
34
 
35
35
  def inspect
@@ -46,10 +46,10 @@ module Lumberjack
46
46
  if tags
47
47
  tags[UNIT_OF_WORK_ID] = value
48
48
  else
49
- @tags = { UNIT_OF_WORK_ID => value }
49
+ @tags = {UNIT_OF_WORK_ID => value}
50
50
  end
51
51
  end
52
-
52
+
53
53
  # Return the tag with the specified name.
54
54
  def tag(name)
55
55
  tags[name.to_s] if tags
@@ -58,10 +58,8 @@ module Lumberjack
58
58
  private
59
59
 
60
60
  def tags_to_s
61
- tags_string = String.new
62
- if tags
63
- tags.each { |name, value| tags_string << " #{name}:#{value.inspect}" }
64
- end
61
+ tags_string = ""
62
+ tags&.each { |name, value| tags_string << " #{name}:#{value.inspect}" }
65
63
  tags_string
66
64
  end
67
65
  end
@@ -63,7 +63,7 @@ module Lumberjack
63
63
  # * :max_size - If the log device is a file path, it will be a Device::SizeRollingLogFile if this is set.
64
64
  #
65
65
  # All other options are passed to the device constuctor.
66
- def initialize(device = STDOUT, options = {})
66
+ def initialize(device = $stdout, options = {})
67
67
  options = options.dup
68
68
  self.level = options.delete(:level) || INFO
69
69
  self.progname = options.delete(:progname)
@@ -100,19 +100,19 @@ module Lumberjack
100
100
  thread_local_value(:lumberjack_logger_level) || @level
101
101
  end
102
102
 
103
- alias_method :sev_threshold, :level
103
+ alias sev_threshold level
104
104
 
105
105
  # Set the log level using either an integer level like Logger::INFO or a label like
106
106
  # :info or "info"
107
107
  def level=(value)
108
- if value.is_a?(Integer)
109
- @level = value
108
+ @level = if value.is_a?(Integer)
109
+ value
110
110
  else
111
- @level = Severity::label_to_level(value)
111
+ Severity.label_to_level(value)
112
112
  end
113
113
  end
114
114
 
115
- alias_method :sev_threshold=, :level=
115
+ alias sev_threshold= level=
116
116
 
117
117
  # Set the Lumberjack::Formatter used to format objects for logging as messages.
118
118
  def formatter=(value)
@@ -137,7 +137,7 @@ module Lumberjack
137
137
  # in an array under the "tagged" tag. So calling `logger.tagged("foo", "bar")` will result
138
138
  # in tags `{"tagged" => ["foo", "bar"]}`.
139
139
  def tagged_logger!
140
- self.extend(TaggedLoggerSupport)
140
+ extend(TaggedLoggerSupport)
141
141
  self
142
142
  end
143
143
 
@@ -156,10 +156,10 @@ module Lumberjack
156
156
  # logger.add_entry(:warn, "Request took a long time")
157
157
  # logger.add_entry(Logger::DEBUG){"Start processing with options #{options.inspect}"}
158
158
  def add_entry(severity, message, progname = nil, tags = nil)
159
- begin
159
+ begin
160
160
  severity = Severity.label_to_level(severity) unless severity.is_a?(Integer)
161
161
  return true unless device && severity && severity >= level
162
-
162
+
163
163
  return true if Thread.current[:lumberjack_logging]
164
164
  Thread.current[:lumberjack_logging] = true
165
165
 
@@ -173,10 +173,10 @@ module Lumberjack
173
173
  if current_tags.empty?
174
174
  tags = Tags.stringify_keys(tags) unless tags.nil?
175
175
  else
176
- if tags.nil?
177
- tags = current_tags.dup
176
+ tags = if tags.nil?
177
+ current_tags.dup
178
178
  else
179
- tags = current_tags.merge(Tags.stringify_keys(tags))
179
+ current_tags.merge(Tags.stringify_keys(tags))
180
180
  end
181
181
  end
182
182
  tags = Tags.expand_runtime_values(tags)
@@ -203,7 +203,7 @@ module Lumberjack
203
203
  add_entry(severity, message, progname)
204
204
  end
205
205
 
206
- alias_method :log, :add
206
+ alias log add
207
207
 
208
208
  # Flush the logging device. Messages are not guaranteed to be written until this method is called.
209
209
  def flush
@@ -238,6 +238,11 @@ module Lumberjack
238
238
  level <= FATAL
239
239
  end
240
240
 
241
+ # Set the log level to fatal.
242
+ def fatal!
243
+ self.level = FATAL
244
+ end
245
+
241
246
  # Log an +ERROR+ message. The message can be passed in either the +message+ argument or in a block.
242
247
  def error(message_or_progname_or_tags = nil, progname_or_tags = nil, &block)
243
248
  call_add_entry(ERROR, message_or_progname_or_tags, progname_or_tags, &block)
@@ -248,6 +253,11 @@ module Lumberjack
248
253
  level <= ERROR
249
254
  end
250
255
 
256
+ # Set the log level to error.
257
+ def error!
258
+ self.level = ERROR
259
+ end
260
+
251
261
  # Log a +WARN+ message. The message can be passed in either the +message+ argument or in a block.
252
262
  def warn(message_or_progname_or_tags = nil, progname_or_tags = nil, &block)
253
263
  call_add_entry(WARN, message_or_progname_or_tags, progname_or_tags, &block)
@@ -258,6 +268,11 @@ module Lumberjack
258
268
  level <= WARN
259
269
  end
260
270
 
271
+ # Set the log level to warn.
272
+ def warn!
273
+ self.level = WARN
274
+ end
275
+
261
276
  # Log an +INFO+ message. The message can be passed in either the +message+ argument or in a block.
262
277
  def info(message_or_progname_or_tags = nil, progname_or_tags = nil, &block)
263
278
  call_add_entry(INFO, message_or_progname_or_tags, progname_or_tags, &block)
@@ -268,6 +283,11 @@ module Lumberjack
268
283
  level <= INFO
269
284
  end
270
285
 
286
+ # Set the log level to info.
287
+ def info!
288
+ self.level = INFO
289
+ end
290
+
271
291
  # Log a +DEBUG+ message. The message can be passed in either the +message+ argument or in a block.
272
292
  def debug(message_or_progname_or_tags = nil, progname_or_tags = nil, &block)
273
293
  call_add_entry(DEBUG, message_or_progname_or_tags, progname_or_tags, &block)
@@ -278,6 +298,11 @@ module Lumberjack
278
298
  level <= DEBUG
279
299
  end
280
300
 
301
+ # Set the log level to debug.
302
+ def debug!
303
+ self.level = DEBUG
304
+ end
305
+
281
306
  # Log a message when the severity is not known. Unknown messages will always appear in the log.
282
307
  # The message can be passed in either the +message+ argument or in a block.
283
308
  def unknown(message_or_progname_or_tags = nil, progname_or_tags = nil, &block)
@@ -300,7 +325,7 @@ module Lumberjack
300
325
  def silence(temporary_level = ERROR, &block)
301
326
  if silencer
302
327
  unless temporary_level.is_a?(Integer)
303
- temporary_level = Severity::label_to_level(temporary_level)
328
+ temporary_level = Severity.label_to_level(temporary_level)
304
329
  end
305
330
  push_thread_local_value(:lumberjack_logger_level, temporary_level, &block)
306
331
  else
@@ -324,30 +349,67 @@ module Lumberjack
324
349
  end
325
350
 
326
351
  # Set a hash of tags on logger. If a block is given, the tags will only be set
327
- # for the duration of the block.
352
+ # for the duration of the block. If this method is called inside such a block,
353
+ # the tags will only be defined on the tags in that block. When the parent block
354
+ # exits, all the tags will be reverted. If there is no block, then the tags will
355
+ # be defined as global and apply to all log statements.
328
356
  def tag(tags, &block)
329
357
  tags = Tags.stringify_keys(tags)
358
+ thread_tags = thread_local_value(:lumberjack_logger_tags)
330
359
  if block
331
- thread_tags = thread_local_value(:lumberjack_logger_tags)
332
- value = (thread_tags ? thread_tags.merge(tags) : tags)
333
- push_thread_local_value(:lumberjack_logger_tags, value, &block)
360
+ merged_tags = (thread_tags ? thread_tags.merge(tags) : tags.dup)
361
+ push_thread_local_value(:lumberjack_logger_tags, merged_tags, &block)
362
+ elsif thread_tags
363
+ thread_tags.merge!(tags)
364
+ nil
334
365
  else
335
366
  @tags.merge!(tags)
367
+ nil
368
+ end
369
+ end
370
+
371
+ # Remove a tag from the current tag context. If this is called inside a block to a
372
+ # call to `tag`, the tags will only be removed for the duration of that block. Otherwise
373
+ # they will be removed from the global tags.
374
+ def remove_tag(*tag_names)
375
+ thread_tags = thread_local_value(:lumberjack_logger_tags)
376
+ if thread_tags
377
+ tag_names.each { |name| thread_tags.delete(name.to_s) }
378
+ else
379
+ tag_names.each { |name| @tags.delete(name.to_s) }
336
380
  end
337
381
  end
338
382
 
339
383
  # Return all tags in scope on the logger including global tags set on the Lumberjack
340
- # context, tags set on the logger, and tags set on the current block for the logger
384
+ # context, tags set on the logger, and tags set on the current block for the logger.
341
385
  def tags
342
386
  tags = {}
343
387
  context_tags = Lumberjack.context_tags
344
388
  tags.merge!(context_tags) if context_tags && !context_tags.empty?
345
- tags.merge!(@tags) if !@tags.empty?
389
+ tags.merge!(@tags) if !@tags.empty? && !thread_local_value(:lumberjack_logger_untagged)
346
390
  scope_tags = thread_local_value(:lumberjack_logger_tags)
347
391
  tags.merge!(scope_tags) if scope_tags && !scope_tags.empty?
348
392
  tags
349
393
  end
350
394
 
395
+ # Remove all tags on the current logger and logging context within a block.
396
+ # You can still set new block scoped tags within theuntagged block and provide
397
+ # tags on individual log methods.
398
+ def untagged(&block)
399
+ Lumberjack.use_context(nil) do
400
+ scope_tags = thread_local_value(:lumberjack_logger_tags)
401
+ untagged = thread_local_value(:lumberjack_logger_untagged)
402
+ begin
403
+ set_thread_local_value(:lumberjack_logger_untagged, true)
404
+ set_thread_local_value(:lumberjack_logger_tags, nil)
405
+ tag({}, &block)
406
+ ensure
407
+ set_thread_local_value(:lumberjack_logger_untagged, untagged)
408
+ set_thread_local_value(:lumberjack_logger_tags, scope_tags)
409
+ end
410
+ end
411
+ end
412
+
351
413
  private
352
414
 
353
415
  # Dereference arguments to log calls so we can have methods with compatibility with ::Logger
@@ -430,12 +492,12 @@ module Lumberjack
430
492
  end
431
493
 
432
494
  def write_to_device(entry) #:nodoc:
433
- begin
434
- device.write(entry)
435
- rescue => e
436
- $stderr.puts("#{e.class.name}: #{e.message}#{' at ' + e.backtrace.first if e.backtrace}")
437
- $stderr.puts(entry.to_s)
438
- end
495
+ device.write(entry)
496
+ rescue => e
497
+ # rubocop:disable Style/StderrPuts
498
+ $stderr.puts("#{e.class.name}: #{e.message}#{" at " + e.backtrace.first if e.backtrace}")
499
+ $stderr.puts(entry.to_s)
500
+ # rubocop:enable Style/StderrPuts
439
501
  end
440
502
 
441
503
  # Create a thread that will periodically call flush.
@@ -444,12 +506,12 @@ module Lumberjack
444
506
  begin
445
507
  logger = self
446
508
  Thread.new do
447
- while !closed?
509
+ until closed?
448
510
  begin
449
511
  sleep(flush_seconds)
450
512
  logger.flush if Time.now - logger.last_flushed_at >= flush_seconds
451
513
  rescue => e
452
- STDERR.puts("Error flushing log: #{e.inspect}")
514
+ warn("Error flushing log: #{e.inspect}")
453
515
  end
454
516
  end
455
517
  end