logging 2.0.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.travis.yml +8 -5
- data/History.txt +59 -0
- data/LICENSE +22 -0
- data/README.md +20 -41
- data/Rakefile +2 -2
- data/examples/appenders.rb +1 -1
- data/examples/layouts.rb +1 -1
- data/examples/lazy.rb +1 -1
- data/examples/mdc.rb +2 -2
- data/examples/rails4.rb +21 -0
- data/examples/reusing_layouts.rb +51 -0
- data/lib/logging.rb +99 -9
- data/lib/logging/appender.rb +13 -34
- data/lib/logging/appenders/buffering.rb +130 -59
- data/lib/logging/appenders/console.rb +68 -57
- data/lib/logging/appenders/file.rb +43 -22
- data/lib/logging/appenders/io.rb +22 -16
- data/lib/logging/appenders/rolling_file.rb +60 -26
- data/lib/logging/appenders/string_io.rb +1 -1
- data/lib/logging/appenders/syslog.rb +3 -4
- data/lib/logging/color_scheme.rb +1 -1
- data/lib/logging/diagnostic_context.rb +100 -73
- data/lib/logging/layout.rb +144 -16
- data/lib/logging/layouts/parseable.rb +50 -12
- data/lib/logging/layouts/pattern.rb +8 -9
- data/lib/logging/log_event.rb +19 -12
- data/lib/logging/logger.rb +117 -95
- data/lib/logging/proxy.rb +1 -1
- data/lib/logging/rails_compat.rb +4 -13
- data/lib/logging/version.rb +1 -1
- data/logging.gemspec +31 -32
- data/script/console +8 -0
- data/test/appenders/{test_periodic_flushing.rb → test_async_flushing.rb} +67 -14
- data/test/appenders/test_buffered_io.rb +19 -18
- data/test/appenders/test_console.rb +55 -12
- data/test/appenders/test_file.rb +48 -28
- data/test/appenders/test_rolling_file.rb +18 -12
- data/test/appenders/test_syslog.rb +6 -0
- data/test/benchmark.rb +42 -18
- data/test/layouts/test_json.rb +14 -1
- data/test/layouts/test_nested_exceptions.rb +124 -0
- data/test/layouts/test_pattern.rb +16 -3
- data/test/layouts/test_yaml.rb +15 -1
- data/test/performance.rb +66 -0
- data/test/setup.rb +26 -30
- data/test/test_appender.rb +2 -4
- data/test/test_layout.rb +49 -0
- data/test/test_log_event.rb +10 -2
- data/test/test_logger.rb +20 -3
- data/test/test_logging.rb +75 -4
- data/test/test_mapped_diagnostic_context.rb +15 -6
- data/test/test_nested_diagnostic_context.rb +6 -1
- metadata +23 -17
@@ -1,81 +1,92 @@
|
|
1
|
-
|
2
1
|
module Logging::Appenders
|
3
2
|
|
4
|
-
#
|
5
|
-
#
|
6
|
-
|
7
|
-
|
8
|
-
return self['stdout'] || ::Logging::Appenders::Stdout.new
|
9
|
-
end
|
10
|
-
::Logging::Appenders::Stdout.new(*args)
|
11
|
-
end
|
12
|
-
|
13
|
-
# This class provides an Appender that can write to STDOUT.
|
14
|
-
#
|
15
|
-
class Stdout < ::Logging::Appenders::IO
|
3
|
+
# This class is provides an Appender base class for writing to the standard IO
|
4
|
+
# stream - STDOUT and STDERR. This class should not be instantiated directly.
|
5
|
+
# The `Stdout` and `Stderr` subclasses should be used.
|
6
|
+
class Console < ::Logging::Appenders::IO
|
16
7
|
|
17
8
|
# call-seq:
|
18
9
|
# Stdout.new( name = 'stdout' )
|
19
|
-
#
|
10
|
+
# Stderr.new( :layout => layout )
|
20
11
|
# Stdout.new( name = 'stdout', :level => 'info' )
|
21
12
|
#
|
22
|
-
# Creates a new Stdout Appender. The name 'stdout' will be
|
23
|
-
# another is given. Optionally, a layout can be given for the
|
24
|
-
# to use (otherwise a basic appender will be created) and a log
|
25
|
-
# can be specified.
|
13
|
+
# Creates a new Stdout/Stderr Appender. The name 'stdout'/'stderr' will be
|
14
|
+
# used unless another is given. Optionally, a layout can be given for the
|
15
|
+
# appender to use (otherwise a basic appender will be created) and a log
|
16
|
+
# level can be specified.
|
26
17
|
#
|
27
18
|
# Options:
|
28
19
|
#
|
29
|
-
# :layout
|
30
|
-
# :level
|
20
|
+
# :layout => the layout to use when formatting log events
|
21
|
+
# :level => the level at which to log
|
31
22
|
#
|
32
23
|
def initialize( *args )
|
33
|
-
|
34
|
-
|
24
|
+
name = self.class.name.split("::").last.downcase
|
25
|
+
|
26
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
27
|
+
name = args.shift unless args.empty?
|
35
28
|
|
36
|
-
|
29
|
+
io = open_fd
|
30
|
+
opts[:encoding] = io.external_encoding
|
37
31
|
|
38
|
-
super(name,
|
32
|
+
super(name, io, opts)
|
39
33
|
end
|
40
|
-
end # Stdout
|
41
34
|
|
35
|
+
# Reopen the connection to the underlying logging destination. If the
|
36
|
+
# connection is currently closed then it will be opened. If the connection
|
37
|
+
# is currently open then it will be closed and immediately reopened.
|
38
|
+
def reopen
|
39
|
+
@mutex.synchronize {
|
40
|
+
if defined? @io && @io
|
41
|
+
flush
|
42
|
+
@io.close rescue nil
|
43
|
+
end
|
44
|
+
@io = open_fd
|
45
|
+
}
|
46
|
+
super
|
47
|
+
self
|
48
|
+
end
|
42
49
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
50
|
+
private
|
51
|
+
|
52
|
+
def open_fd
|
53
|
+
case self.class.name
|
54
|
+
when "Logging::Appenders::Stdout"
|
55
|
+
fd = STDOUT.fileno
|
56
|
+
encoding = STDOUT.external_encoding
|
57
|
+
when "Logging::Appenders::Stderr"
|
58
|
+
fd = STDERR.fileno
|
59
|
+
encoding = STDERR.external_encoding
|
60
|
+
else
|
61
|
+
raise RuntimeError, "Please do not use the `Logging::Appenders::Console` class directly - " +
|
62
|
+
"use `Logging::Appenders::Stdout` and `Logging::Appenders::Stderr` instead" +
|
63
|
+
" [class #{self.class.name}]"
|
64
|
+
end
|
65
|
+
|
66
|
+
mode = ::File::WRONLY | ::File::APPEND
|
67
|
+
::IO.for_fd(fd, mode: mode, encoding: encoding)
|
48
68
|
end
|
49
|
-
::Logging::Appenders::Stderr.new(*args)
|
50
69
|
end
|
51
70
|
|
52
|
-
# This class provides an Appender that can write to
|
53
|
-
|
54
|
-
class Stderr < ::Logging::Appenders::IO
|
55
|
-
|
56
|
-
# call-seq:
|
57
|
-
# Stderr.new( name = 'stderr' )
|
58
|
-
# Stderr.new( :layout => layout )
|
59
|
-
# Stderr.new( name = 'stderr', :level => 'warn' )
|
60
|
-
#
|
61
|
-
# Creates a new Stderr Appender. The name 'stderr' will be used unless
|
62
|
-
# another is given. Optionally, a layout can be given for the appender
|
63
|
-
# to use (otherwise a basic appender will be created) and a log level
|
64
|
-
# can be specified.
|
65
|
-
#
|
66
|
-
# Options:
|
67
|
-
#
|
68
|
-
# :layout => the layout to use when formatting log events
|
69
|
-
# :level => the level at which to log
|
70
|
-
#
|
71
|
-
def initialize( *args )
|
72
|
-
opts = Hash === args.last ? args.pop : {}
|
73
|
-
name = args.empty? ? 'stderr' : args.shift
|
71
|
+
# This class provides an Appender that can write to STDOUT.
|
72
|
+
Stdout = Class.new(Console)
|
74
73
|
|
75
|
-
|
74
|
+
# This class provides an Appender that can write to STDERR.
|
75
|
+
Stderr = Class.new(Console)
|
76
76
|
|
77
|
-
|
77
|
+
# Accessor / Factory for the Stdout appender.
|
78
|
+
def self.stdout( *args )
|
79
|
+
if args.empty?
|
80
|
+
return self['stdout'] || ::Logging::Appenders::Stdout.new
|
78
81
|
end
|
79
|
-
|
80
|
-
end
|
82
|
+
::Logging::Appenders::Stdout.new(*args)
|
83
|
+
end
|
81
84
|
|
85
|
+
# Accessor / Factory for the Stderr appender.
|
86
|
+
def self.stderr( *args )
|
87
|
+
if args.empty?
|
88
|
+
return self['stderr'] || ::Logging::Appenders::Stderr.new
|
89
|
+
end
|
90
|
+
::Logging::Appenders::Stderr.new(*args)
|
91
|
+
end
|
92
|
+
end
|
@@ -2,14 +2,12 @@
|
|
2
2
|
module Logging::Appenders
|
3
3
|
|
4
4
|
# Accessor / Factory for the File appender.
|
5
|
-
#
|
6
5
|
def self.file( *args )
|
7
|
-
|
6
|
+
fail ArgumentError, '::Logging::Appenders::File needs a name as first argument.' if args.empty?
|
8
7
|
::Logging::Appenders::File.new(*args)
|
9
8
|
end
|
10
9
|
|
11
10
|
# This class provides an Appender that can write to a File.
|
12
|
-
#
|
13
11
|
class File < ::Logging::Appenders::IO
|
14
12
|
|
15
13
|
# call-seq:
|
@@ -21,15 +19,14 @@ module Logging::Appenders
|
|
21
19
|
# writable.
|
22
20
|
#
|
23
21
|
# An +ArgumentError+ is raised if any of these assertions fail.
|
24
|
-
#
|
25
22
|
def self.assert_valid_logfile( fn )
|
26
23
|
if ::File.exist?(fn)
|
27
|
-
if
|
24
|
+
if !::File.file?(fn)
|
28
25
|
raise ArgumentError, "#{fn} is not a regular file"
|
29
|
-
elsif
|
26
|
+
elsif !::File.writable?(fn)
|
30
27
|
raise ArgumentError, "#{fn} is not writeable"
|
31
28
|
end
|
32
|
-
elsif
|
29
|
+
elsif !::File.writable?(::File.dirname(fn))
|
33
30
|
raise ArgumentError, "#{::File.dirname(fn)} is not writable"
|
34
31
|
end
|
35
32
|
true
|
@@ -45,41 +42,65 @@ module Logging::Appenders
|
|
45
42
|
# created. If the :truncate option is set to +true+ then the file will
|
46
43
|
# be truncated before writing begins; otherwise, log messages will be
|
47
44
|
# appended to the file.
|
48
|
-
#
|
49
45
|
def initialize( name, opts = {} )
|
50
|
-
@
|
51
|
-
raise ArgumentError, 'no filename was given' if @
|
46
|
+
@filename = opts.fetch(:filename, name)
|
47
|
+
raise ArgumentError, 'no filename was given' if @filename.nil?
|
52
48
|
|
53
|
-
@
|
54
|
-
self.class.assert_valid_logfile(@
|
55
|
-
@mode = opts.fetch(:truncate, false) ? 'w' : 'a'
|
49
|
+
@filename = ::File.expand_path(@filename).freeze
|
50
|
+
self.class.assert_valid_logfile(@filename)
|
56
51
|
|
57
52
|
self.encoding = opts.fetch(:encoding, self.encoding)
|
58
|
-
@mode = "#{@mode}:#{self.encoding}" if self.encoding
|
59
53
|
|
60
|
-
|
54
|
+
io = open_file
|
55
|
+
super(name, io, opts)
|
56
|
+
|
57
|
+
truncate if opts.fetch(:truncate, false)
|
61
58
|
end
|
62
59
|
|
63
60
|
# Returns the path to the logfile.
|
64
|
-
|
65
|
-
def filename() @fn.dup end
|
61
|
+
attr_reader :filename
|
66
62
|
|
67
63
|
# Reopen the connection to the underlying logging destination. If the
|
68
64
|
# connection is currently closed then it will be opened. If the connection
|
69
65
|
# is currently open then it will be closed and immediately opened.
|
70
|
-
#
|
71
66
|
def reopen
|
72
67
|
@mutex.synchronize {
|
73
|
-
if defined? @io
|
68
|
+
if defined? @io && @io
|
74
69
|
flush
|
75
70
|
@io.close rescue nil
|
76
71
|
end
|
77
|
-
@io =
|
72
|
+
@io = open_file
|
78
73
|
}
|
79
74
|
super
|
80
75
|
self
|
81
76
|
end
|
82
77
|
|
83
|
-
end # FileAppender
|
84
|
-
end # Logging::Appenders
|
85
78
|
|
79
|
+
protected
|
80
|
+
|
81
|
+
def truncate
|
82
|
+
@mutex.synchronize {
|
83
|
+
begin
|
84
|
+
@io.flock(::File::LOCK_EX)
|
85
|
+
@io.truncate(0)
|
86
|
+
ensure
|
87
|
+
@io.flock(::File::LOCK_UN)
|
88
|
+
end
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
92
|
+
def open_file
|
93
|
+
mode = ::File::WRONLY | ::File::APPEND
|
94
|
+
::File.open(filename, mode: mode, external_encoding: encoding)
|
95
|
+
rescue Errno::ENOENT
|
96
|
+
create_file
|
97
|
+
end
|
98
|
+
|
99
|
+
def create_file
|
100
|
+
mode = ::File::WRONLY | ::File::APPEND | ::File::CREAT | ::File::EXCL
|
101
|
+
::File.open(filename, mode: mode, external_encoding: encoding)
|
102
|
+
rescue Errno::EEXIST
|
103
|
+
open_file
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
data/lib/logging/appenders/io.rb
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
module Logging::Appenders
|
3
3
|
|
4
4
|
# Accessor / Factory for the IO appender.
|
5
|
-
#
|
6
5
|
def self.io( *args )
|
7
6
|
return ::Logging::Appenders::IO if args.empty?
|
8
7
|
::Logging::Appenders::IO.new(*args)
|
@@ -10,14 +9,12 @@ module Logging::Appenders
|
|
10
9
|
|
11
10
|
# This class provides an Appender that can write to any IO stream
|
12
11
|
# configured for writing.
|
13
|
-
#
|
14
12
|
class IO < ::Logging::Appender
|
15
13
|
include Buffering
|
16
14
|
|
17
15
|
# The method that will be used to close the IO stream. Defaults to :close
|
18
16
|
# but can be :close_read, :close_write or nil. When nil, the IO stream
|
19
17
|
# will not be closed when the appender's close method is called.
|
20
|
-
#
|
21
18
|
attr_accessor :close_method
|
22
19
|
|
23
20
|
# call-seq:
|
@@ -26,15 +23,13 @@ module Logging::Appenders
|
|
26
23
|
#
|
27
24
|
# Creates a new IO Appender using the given name that will use the _io_
|
28
25
|
# stream as the logging destination.
|
29
|
-
#
|
30
26
|
def initialize( name, io, opts = {} )
|
31
|
-
unless io.respond_to? :
|
27
|
+
unless io.respond_to? :write
|
32
28
|
raise TypeError, "expecting an IO object but got '#{io.class.name}'"
|
33
29
|
end
|
34
30
|
|
35
31
|
@io = io
|
36
|
-
@io.sync = true if io.respond_to? :sync=
|
37
|
-
@io.flush rescue nil # syswrite also complains if in unbuffered mode and buffer isn't empty
|
32
|
+
@io.sync = true if io.respond_to? :sync=
|
38
33
|
@close_method = :close
|
39
34
|
|
40
35
|
super(name, opts)
|
@@ -48,37 +43,48 @@ module Logging::Appenders
|
|
48
43
|
# destination if the _footer_ flag is set to +true+. Log events will
|
49
44
|
# no longer be written to the logging destination after the appender
|
50
45
|
# is closed.
|
51
|
-
#
|
52
46
|
def close( *args )
|
53
47
|
return self if @io.nil?
|
54
48
|
super
|
55
49
|
|
56
50
|
io, @io = @io, nil
|
57
51
|
unless [STDIN, STDERR, STDOUT].include?(io)
|
58
|
-
io.send(@close_method) if @close_method
|
52
|
+
io.send(@close_method) if @close_method && io.respond_to?(@close_method)
|
59
53
|
end
|
60
54
|
rescue IOError
|
61
55
|
ensure
|
62
56
|
return self
|
63
57
|
end
|
64
58
|
|
59
|
+
# Reopen the connection to the underlying logging destination. If the
|
60
|
+
# connection is currently closed then it will be opened. If the connection
|
61
|
+
# is currently open then it will be closed and immediately opened. If
|
62
|
+
# supported, the IO will have its sync mode set to `true` so that all writes
|
63
|
+
# are immediately flushed to the underlying operating system.
|
64
|
+
def reopen
|
65
|
+
super
|
66
|
+
@io.sync = true if @io.respond_to? :sync=
|
67
|
+
self
|
68
|
+
end
|
65
69
|
|
66
70
|
private
|
67
71
|
|
68
72
|
# This method is called by the buffering code when messages need to be
|
69
73
|
# written to the logging destination.
|
70
|
-
#
|
71
74
|
def canonical_write( str )
|
72
75
|
return self if @io.nil?
|
73
|
-
str = str.force_encoding(encoding) if encoding
|
74
|
-
@io.
|
76
|
+
str = str.force_encoding(encoding) if encoding && str.encoding != encoding
|
77
|
+
@mutex.synchronize { @io.write str }
|
75
78
|
self
|
76
79
|
rescue StandardError => err
|
80
|
+
handle_internal_error(err)
|
81
|
+
end
|
82
|
+
|
83
|
+
def handle_internal_error( err )
|
84
|
+
return err if off?
|
77
85
|
self.level = :off
|
78
86
|
::Logging.log_internal {"appender #{name.inspect} has been disabled"}
|
79
87
|
::Logging.log_internal_error(err)
|
80
88
|
end
|
81
|
-
|
82
|
-
|
83
|
-
end # Logging::Appenders
|
84
|
-
|
89
|
+
end
|
90
|
+
end
|
@@ -2,7 +2,7 @@ module Logging::Appenders
|
|
2
2
|
|
3
3
|
# Accessor / Factory for the RollingFile appender.
|
4
4
|
def self.rolling_file( *args )
|
5
|
-
|
5
|
+
fail ArgumentError, '::Logging::Appenders::RollingFile needs a name as first argument.' if args.empty?
|
6
6
|
::Logging::Appenders::RollingFile.new(*args)
|
7
7
|
end
|
8
8
|
|
@@ -84,24 +84,32 @@ module Logging::Appenders
|
|
84
84
|
# 'date'.
|
85
85
|
#
|
86
86
|
def initialize( name, opts = {} )
|
87
|
-
@roller = Roller.new
|
87
|
+
@roller = Roller.new(
|
88
|
+
opts.fetch(:filename, name),
|
89
|
+
age: opts.fetch(:age, nil),
|
90
|
+
size: opts.fetch(:size, nil),
|
91
|
+
roll_by: opts.fetch(:roll_by, nil),
|
92
|
+
keep: opts.fetch(:keep, nil)
|
93
|
+
)
|
88
94
|
|
89
95
|
# grab our options
|
90
96
|
@size = opts.fetch(:size, nil)
|
91
97
|
@size = Integer(@size) unless @size.nil?
|
92
98
|
|
93
|
-
@age_fn = filename + '.age'
|
99
|
+
@age_fn = self.filename + '.age'
|
94
100
|
@age_fn_mtime = nil
|
95
101
|
@age = opts.fetch(:age, nil)
|
96
102
|
|
97
103
|
# create our `sufficiently_aged?` method
|
98
104
|
build_singleton_methods
|
99
|
-
FileUtils.touch(@age_fn) if @age &&
|
105
|
+
FileUtils.touch(@age_fn) if @age && !::File.file?(@age_fn)
|
100
106
|
|
101
107
|
# we are opening the file in read/write mode so that a shared lock can
|
102
108
|
# be used on the file descriptor => http://pubs.opengroup.org/onlinepubs/009695399/functions/fcntl.html
|
103
|
-
|
104
|
-
|
109
|
+
self.encoding = opts.fetch(:encoding, self.encoding)
|
110
|
+
|
111
|
+
io = open_file
|
112
|
+
super(name, io, opts)
|
105
113
|
|
106
114
|
# if the truncate flag was set to true, then roll
|
107
115
|
roll_now = opts.fetch(:truncate, false)
|
@@ -121,11 +129,11 @@ module Logging::Appenders
|
|
121
129
|
# is currently open then it will be closed and immediately opened.
|
122
130
|
def reopen
|
123
131
|
@mutex.synchronize {
|
124
|
-
if defined?
|
132
|
+
if defined? @io && @io
|
125
133
|
flush
|
126
134
|
@io.close rescue nil
|
127
135
|
end
|
128
|
-
@io =
|
136
|
+
@io = open_file
|
129
137
|
}
|
130
138
|
super
|
131
139
|
self
|
@@ -134,6 +142,20 @@ module Logging::Appenders
|
|
134
142
|
|
135
143
|
private
|
136
144
|
|
145
|
+
def open_file
|
146
|
+
mode = ::File::RDWR | ::File::APPEND
|
147
|
+
::File.open(filename, mode: mode, external_encoding: encoding)
|
148
|
+
rescue Errno::ENOENT
|
149
|
+
create_file
|
150
|
+
end
|
151
|
+
|
152
|
+
def create_file
|
153
|
+
mode = ::File::RDWR | ::File::APPEND | ::File::CREAT | ::File::EXCL
|
154
|
+
::File.open(filename, mode: mode, external_encoding: encoding)
|
155
|
+
rescue Errno::EEXIST
|
156
|
+
open_file
|
157
|
+
end
|
158
|
+
|
137
159
|
# Returns the file name to use as the temporary copy location. We are
|
138
160
|
# using copy-and-truncate semantics for rolling files so that the IO
|
139
161
|
# file descriptor remains valid during rolling.
|
@@ -141,6 +163,15 @@ module Logging::Appenders
|
|
141
163
|
@roller.copy_file
|
142
164
|
end
|
143
165
|
|
166
|
+
# Returns the modification time of the copy file if one exists. Otherwise
|
167
|
+
# returns `nil`.
|
168
|
+
def copy_file_mtime
|
169
|
+
return nil unless ::File.exist?(copy_file)
|
170
|
+
::File.mtime(copy_file)
|
171
|
+
rescue Errno::ENOENT
|
172
|
+
nil
|
173
|
+
end
|
174
|
+
|
144
175
|
# Write the given _event_ to the log file. The log file will be rolled
|
145
176
|
# if the maximum file size is exceeded or if the file is older than the
|
146
177
|
# maximum age.
|
@@ -148,14 +179,18 @@ module Logging::Appenders
|
|
148
179
|
return self if @io.nil?
|
149
180
|
|
150
181
|
str = str.force_encoding(encoding) if encoding && str.encoding != encoding
|
151
|
-
@
|
182
|
+
@mutex.synchronize {
|
183
|
+
@io.flock_sh { @io.write str }
|
184
|
+
}
|
152
185
|
|
153
186
|
if roll_required?
|
154
|
-
@
|
155
|
-
@
|
156
|
-
|
187
|
+
@mutex.synchronize {
|
188
|
+
@io.flock? {
|
189
|
+
@age_fn_mtime = nil
|
190
|
+
copy_truncate if roll_required?
|
191
|
+
}
|
192
|
+
@roller.roll_files
|
157
193
|
}
|
158
|
-
@roller.roll_files
|
159
194
|
end
|
160
195
|
self
|
161
196
|
rescue StandardError => err
|
@@ -166,7 +201,8 @@ module Logging::Appenders
|
|
166
201
|
|
167
202
|
# Returns +true+ if the log file needs to be rolled.
|
168
203
|
def roll_required?
|
169
|
-
|
204
|
+
mtime = copy_file_mtime
|
205
|
+
return false if mtime && (Time.now - mtime) < 180
|
170
206
|
|
171
207
|
# check if max size has been exceeded
|
172
208
|
s = @size ? ::File.size(filename) > @size : false
|
@@ -183,7 +219,7 @@ module Logging::Appenders
|
|
183
219
|
def copy_truncate
|
184
220
|
return unless ::File.exist?(filename)
|
185
221
|
FileUtils.concat filename, copy_file
|
186
|
-
@io.truncate
|
222
|
+
@io.truncate(0)
|
187
223
|
|
188
224
|
# touch the age file if needed
|
189
225
|
if @age
|
@@ -245,22 +281,22 @@ module Logging::Appenders
|
|
245
281
|
# Create a new roller. See the RollingFile#initialize documentation for
|
246
282
|
# the list of options.
|
247
283
|
#
|
248
|
-
#
|
249
|
-
#
|
284
|
+
# filename - the name of the file to roll
|
285
|
+
# age - the age of the file at which it should be rolled
|
286
|
+
# size - the size of the file in bytes at which it should be rolled
|
287
|
+
# roll_by - roll either by 'number' or 'date'
|
288
|
+
# keep - the number of log files to keep when rolling
|
250
289
|
#
|
251
|
-
def initialize(
|
290
|
+
def initialize( filename, age: nil, size: nil, roll_by: nil, keep: nil )
|
252
291
|
# raise an error if a filename was not given
|
253
|
-
@fn =
|
292
|
+
@fn = filename
|
254
293
|
raise ArgumentError, 'no filename was given' if @fn.nil?
|
255
294
|
|
256
295
|
if (m = RGXP.match @fn)
|
257
296
|
@roll_by = ("#{m[2]}%d" == m[1]) ? :number : :date
|
258
297
|
else
|
259
|
-
age = opts.fetch(:age, nil)
|
260
|
-
size = opts.fetch(:size, nil)
|
261
|
-
|
262
298
|
@roll_by =
|
263
|
-
case
|
299
|
+
case roll_by
|
264
300
|
when 'number'; :number
|
265
301
|
when 'date'; :date
|
266
302
|
else
|
@@ -283,8 +319,7 @@ module Logging::Appenders
|
|
283
319
|
::Logging::Appenders::File.assert_valid_logfile(filename)
|
284
320
|
|
285
321
|
@roll = false
|
286
|
-
@keep =
|
287
|
-
@keep = Integer(keep) unless keep.nil?
|
322
|
+
@keep = keep.nil? ? nil : Integer(keep)
|
288
323
|
end
|
289
324
|
|
290
325
|
attr_reader :keep, :roll_by
|
@@ -337,7 +372,6 @@ module Logging::Appenders
|
|
337
372
|
files.delete copy_file
|
338
373
|
|
339
374
|
self.send "roll_by_#{roll_by}", files
|
340
|
-
|
341
375
|
nil
|
342
376
|
ensure
|
343
377
|
self.roll = false
|