class Logging::Appenders::RollingFile::Roller
Not intended for general consumption, but the Roller class is used internally by the RollingFile appender to roll dem log files according to the user's desires.
Constants
- RGXP
The magic regex for finding user-defined roller patterns.
Attributes
Public Class Methods
Create a new roller. See the RollingFile#initialize documentation for the list of options.
name - The appender name as a String opts - The options Hash
# File lib/logging/appenders/rolling_file.rb, line 261 def initialize( name, opts ) # raise an error if a filename was not given @fn = opts.fetch(:filename, name) raise ArgumentError, 'no filename was given' if @fn.nil? if (m = RGXP.match @fn) @roll_by = ("#{m[2]}%d" == m[1]) ? :number : :date else age = opts.fetch(:age, nil) size = opts.fetch(:size, nil) @roll_by = case opts.fetch(:roll_by, nil) when 'number'; :number when 'date'; :date else (age && !size) ? :date : :number end ext = ::File.extname(@fn) bn = ::File.join(::File.dirname(@fn), ::File.basename(@fn, ext)) @fn = if :date == @roll_by && %w[daily weekly monthly].include?(age) "#{bn}{{.%Y%m%d}}#{ext}" elsif :date == @roll_by "#{bn}{{.%Y%m%d-%H%M%S}}#{ext}" else "#{bn}{{.%d}}#{ext}" end end @fn = ::File.expand_path(@fn) ::Logging::Appenders::File.assert_valid_logfile(filename) @roll = false @keep = opts.fetch(:keep, nil) @keep = Integer(keep) unless keep.nil? end
Public Instance Methods
Returns the file name to use as the temporary copy location. We are using copy-and-truncate semantics for rolling files so that the IO file descriptor remains valid during rolling.
# File lib/logging/appenders/rolling_file.rb, line 313 def copy_file return @copy_file if defined? @copy_file @copy_file = filename + '._copy_' @copy_file.freeze end
Returns the regular log file name without any roller text.
# File lib/logging/appenders/rolling_file.rb, line 304 def filename return @filename if defined? @filename @filename = (@fn =~ RGXP ? @fn.sub(RGXP, '') : @fn.dup) @filename.freeze end
Returns the format String used to generate rolled file names. Depending upon the `roll_by` type (:date or :number), this String will be processed by `sprintf` or `Time#strftime`.
# File lib/logging/appenders/rolling_file.rb, line 331 def format return @format if defined? @format m = RGXP.match @fn @format = @fn.sub(RGXP, m[1]) @format.freeze end
Returns the glob pattern used to find rolled log files. We use this list for pruning older log files and doing the numbered rolling.
# File lib/logging/appenders/rolling_file.rb, line 321 def glob return @glob if defined? @glob m = RGXP.match @fn @glob = @fn.sub(RGXP, (m[2] ? "#{m[2]}*" : '*')) @glob.freeze end
Roll the list of log files optionally removing older files. The “older files” are determined by the mtime of the log files. So touching log files or otherwise messing with them will screw this up.
files - The Array of filename Strings
Returns nil
# File lib/logging/appenders/rolling_file.rb, line 394 def roll_by_date( files ) length = files.length if keep && length >= keep files = files.sort do |a,b| a = ::File.mtime(a) b = ::File.mtime(b) b <=> a end files.last(length-keep+1).each { |fn| ::File.delete fn } end # rename the copied log file ::File.rename(copy_file, Time.now.strftime(format)) end
Roll the list of log files optionally removing older files. The “older files” are determined by extracting the number from the log file name and order by the number.
files - The Array of filename Strings
Returns nil
# File lib/logging/appenders/rolling_file.rb, line 363 def roll_by_number( files ) @number_rgxp ||= Regexp.new(@fn.sub(RGXP, '\2(\d+)')) # sort the files in reverse order based on their count number files = files.sort do |a,b| a = Integer(@number_rgxp.match(a)[1]) b = Integer(@number_rgxp.match(b)[1]) b <=> a end # for each file, roll its count number one higher files.each do |fn| cnt = Integer(@number_rgxp.match(fn)[1]) if keep && cnt >= keep ::File.delete fn next end ::File.rename fn, sprintf(format, cnt+1) end # finally rename the copied log file ::File.rename(copy_file, sprintf(format, 1)) end
Roll the log files. This method will collect the list of rolled files and then pass that list to either `roll_by_number` or `roll_by_date` to perform the actual rolling.
Returns nil
# File lib/logging/appenders/rolling_file.rb, line 343 def roll_files return unless roll && ::File.exist?(copy_file) files = Dir.glob(glob) files.delete copy_file self.send "roll_by_#{roll_by}", files nil ensure self.roll = false end