/usr/lib/ruby/1.8/ramaze/log/rotatinginformer.rb is in libramaze-ruby1.8 2010.06.18-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | module Ramaze
module Logger
# A customized logger (based on Informer) that creates multiple log files based on time
class RotatingInformer
include Innate::Traited
include Logging
attr_accessor :time_format, :log_levels
attr_reader :base_dir
# parameter for Time.now.strftime
trait :timestamp => "%Y-%m-%d %H:%M:%S"
# This is how the final output is arranged.
trait :format => "[%time] %prefix %text"
# Create a new instance of RotatingInformer.
#
# base_dir is the directory where all log files will be stored
#
# time_format is the time format used to name the log files.
# Possible formats are identical to those
# accepted by Time.strftime
#
# log_levelse is an array describing what kind of messages
# that the log receives. The array may contain
# any or all of the symbols :debug, :error, :info and/or :warn
#
# Examples:
# RotatingInformer.new('logs')
# #=> Creates logs in directory called logs.
# The generated filenames will be in the
# form YYYY-MM-DD.log
# RotatingInformer.new('logs', '%Y-%m.txt')
# #=> Creates logs in directory called logs.
# The generated filenames will be in the
# form YYYY-MM.txt
# RotatingInformer.new('logs', '%Y-%m.txt', [:error])
# #=> Creates logs in directory called logs.
# The generated filenames will be in the
# form YYYY-MM.txt. Only errors will be
# logged to the files.
def initialize(base_dir, time_format = '%Y-%m-%d.log', log_levels = [:debug, :error, :info, :warn])
# Verify and set base directory
send :base_dir=, base_dir, true
@time_format = time_format
@log_levels = log_levels
# Keep track of log shutdown (to prevent StackErrors due to recursion)
@in_shutdown = false
end
# Set the base directory for log files
#
# If this method is called with the raise_exception
# parameter set to true the method will raise an exception
# if the specified directory does not exist or is unwritable.
#
# If raise_exception is set to false, the method will just
# silently fail if the specified directory does not exist
# or is unwritable
def base_dir=(directory, raise_exception = false)
# Expand directory path
base_dir = File.expand_path(directory)
# Verify that directory path exists
if File.exist?(base_dir)
# Verify that directory path is a directory
if File.directory?(base_dir)
# Verify that directory path is writable
if File.writable?(base_dir)
@base_dir = base_dir
else
raise Exception.new("#{base_dir} is not writable") if raise_exception
end
else
raise Exception.new("#{base_dir} is not a directory") if raise_exception
end
else
raise Exception.new("#{base_dir} does not exist.") if raise_exception
end
end
# Close the file we log to if it isn't closed already.
def shutdown
if @out.respond_to?(:close)
unless @in_shutdown
@in_shutdown = true
Log.debug("close, #{@out.inspect}")
@in_shutdown = false
end
@out.close
end
end
# Integration to Logging.
def log tag, *messages
return unless @log_levels.include?(tag)
# Update current log
update_current_log
messages.flatten!
prefix = tag.to_s.upcase.ljust(5)
messages.each do |message|
@out.puts(log_interpolate(prefix, message))
end
@out.flush if @out.respond_to?(:flush)
end
# Takes the prefix (tag), text and timestamp and applies it to
# the :format trait.
def log_interpolate prefix, text, time = timestamp
message = class_trait[:format].dup
vars = { '%time' => time, '%prefix' => prefix, '%text' => text }
vars.each{|from, to| message.gsub!(from, to) }
message
end
# This uses timestamp trait or a date in the format of
# %Y-%m-%d %H:%M:%S
# # => "2007-01-19 21:09:32"
def timestamp
mask = class_trait[:timestamp]
Time.now.strftime(mask || "%Y-%m-%d %H:%M:%S")
end
# is @out closed?
def closed?
@out.respond_to?(:closed?) && @out.closed?
end
private
# Checks whether current filename is still valid.
# If not, update the current log to point at the new
# filename
def update_current_log
out = File.join(@base_dir, Time.now.strftime(@time_format))
if @out.nil? || @out.path != out
# Close old log if necessary
shutdown unless @out.nil? || closed?
# Start new log
@out = File.open(out, 'ab+')
end
end
end
end
end
|