lib/backup/logger.rb in backup-3.0.27 vs lib/backup/logger.rb in backup-3.1.0
- old
+ new
@@ -1,152 +1,150 @@
# encoding: utf-8
+require 'backup/logger/console'
+require 'backup/logger/logfile'
+require 'backup/logger/syslog'
+
module Backup
module Logger
- class << self
- attr_accessor :quiet
-
- ##
- # Outputs a messages to the console and writes it to the backup.log
- def message(string)
- to_console loggify(string, :message, :green)
- to_file loggify(string, :message)
+ class Config
+ class Logger < Struct.new(:class, :options)
+ def enabled?
+ options.enabled?
+ end
end
- ##
- # Outputs an error to the console and writes it to the backup.log
- # Called when an Exception has caused the backup process to abort.
- def error(string)
- to_console loggify(string, :error, :red), true
- to_file loggify(string, :error)
- end
+ DSL = Struct.new(:console, :logfile, :syslog)
- ##
- # Outputs a notice to the console and writes it to the backup.log
- # Sets #has_warnings? true so :on_warning notifications will be sent
- def warn(string)
- @has_warnings = true
- to_console loggify(string, :warning, :yellow), true
- to_file loggify(string, :warning)
- end
+ attr_reader :loggers, :dsl
- # Outputs the data as if it were a regular 'puts' command,
- # but also logs it to the backup.log
- def normal(string)
- to_console loggify(string)
- to_file loggify(string)
+ def initialize
+ @loggers = [
+ Logger.new(Console, Console::Options.new),
+ Logger.new(Logfile, Logfile::Options.new),
+ Logger.new(Syslog, Syslog::Options.new)
+ ]
+ @dsl = DSL.new(*@loggers.map(&:options))
end
+ end
+ ##
+ # All messages sent to the Logger are stored in Logger.messages
+ # and sent to all enabled logger's #log method as Message objects.
+ class Message < Struct.new(:time, :level, :lines)
##
- # Silently logs data to the log file
- def silent(string)
- to_file loggify(string, :silent)
+ # Returns an Array of the message lines in the following format:
+ #
+ # [YYYY/MM/DD HH:MM:SS][level] message line text
+ def formatted_lines
+ timestamp = time.strftime("%Y/%m/%d %H:%M:%S")
+ lines.map {|line| "[#{ timestamp }][#{ level }] #{ line }" }
end
+ end
+ class << self
##
- # Returns an Array of all messages written to the log file for this session
- def messages
- @messages ||= []
- end
+ # Returns an Array of Message objects for all logged messages received.
+ # These are used to attach log files to Mail notifications.
+ attr_reader :messages
##
- # Returns true if any warnings have been issued
- def has_warnings?
- @has_warnings ||= false
+ # Allows the Logger to be configured.
+ #
+ # # shown with their default values
+ # Backup::Logger.configure do
+ # # Console options:
+ # console.quiet = false
+ #
+ # # Logfile options:
+ # logfile.enabled = true
+ # logfile.log_path = 'log'
+ # logfile.max_bytes = 500_000
+ #
+ # # Syslog options:
+ # syslog.enabled = false
+ # syslog.ident = 'backup'
+ # syslog.options = Syslog::LOG_PID
+ # syslog.facility = Syslog::LOG_LOCAL0
+ # syslog.info = Syslog::LOG_INFO
+ # syslog.warn = Syslog::LOG_WARNING
+ # syslog.error = Syslog::LOG_ERR
+ # end
+ #
+ # See each Logger's Option class for details.
+ # @see Console::Options
+ # @see Logfile::Options
+ # @see Syslog::Options
+ def configure(&block)
+ @config.dsl.instance_eval(&block)
end
- def clear!
- messages.clear
- @has_warnings = false
+ ##
+ # Sends a message to the Logger using the specified log level.
+ # +obj+ may be any Object that responds to #to_s (i.e. an Exception)
+ [:info, :warn, :error].each do |level|
+ define_method level, lambda {|obj| log(obj, level) }
end
- def truncate!(max_bytes = 500_000)
- log_file = File.join(Config.log_path, 'backup.log')
- return unless File.exist?(log_file)
-
- if File.stat(log_file).size > max_bytes
- FileUtils.mv(log_file, log_file + '~')
- File.open(log_file + '~', 'r') do |io_in|
- File.open(log_file, 'w') do |io_out|
- io_in.seek(-max_bytes, IO::SEEK_END) && io_in.gets
- while line = io_in.gets
- io_out.puts line
- end
- end
- end
- FileUtils.rm_f(log_file + '~')
- end
- end
-
- private
-
##
- # Returns the time in [YYYY/MM/DD HH:MM:SS] format
- def time
- Time.now.strftime("%Y/%m/%d %H:%M:%S")
+ # Returns true if any +:warn+ level messages have been received.
+ def has_warnings?
+ @has_warnings
end
##
- # Receives a String, or an Object that responds to #to_s (e.g. an
- # Exception), from one of the messaging methods and converts it into an
- # Array of Strings, split on newline separators. Each line is then
- # formatted into a log format based on the given options, and the Array
- # returned to be passed to to_console() and/or to_file().
- def loggify(string, type = false, color = false)
- lines = string.to_s.split("\n")
- if type
- type = send(color, type) if color
- time_now = time
- lines.map {|line| "[#{time_now}][#{type}] #{line}" }
- else
- lines
+ # The Logger is available as soon as Backup is loaded, and stores all
+ # messages it receives. Since the Logger may be configured via the
+ # command line and/or the user's +config.rb+, no messages are sent
+ # until configuration can be completed. (see CLI#perform)
+ #
+ # Once configuration is completed, this method is called to activate
+ # all enabled loggers and send them any messages that have been received
+ # up to this point. From this point onward, these loggers will be sent
+ # all messages as soon as they're received.
+ def start!
+ @config.loggers.each do |logger|
+ @loggers << logger.class.new(logger.options) if logger.enabled?
end
+ @messages.each do |message|
+ @loggers.each {|logger| logger.log(message) }
+ end
end
##
- # Receives an Array of Strings to be written to the console.
- def to_console(lines, stderr = false)
- return if quiet
- lines.each {|line| stderr ? Kernel.warn(line) : puts(line) }
+ # Called after each backup model/trigger has been performed.
+ def clear!
+ messages.clear
+ @has_warnings = false
end
##
- # Receives an Array of Strings to be written to the log file.
- def to_file(lines)
- File.open(File.join(Config.log_path, 'backup.log'), 'a') do |file|
- lines.each {|line| file.puts line }
- end
- messages.push(*lines)
+ # If errors are encountered by Backup::CLI while preparing to perform
+ # the backup jobs, this method is called to dump all messages to the
+ # console before Backup exits.
+ def abort!
+ console = Console.new
+ console.log(@messages.shift) until @messages.empty?
end
- ##
- # Invokes the #colorize method with the provided string
- # and the color code "32" (for green)
- def green(string)
- colorize(string, 32)
- end
+ private
- ##
- # Invokes the #colorize method with the provided string
- # and the color code "33" (for yellow)
- def yellow(string)
- colorize(string, 33)
+ def initialize!
+ @messages = []
+ @loggers = []
+ @config = Config.new
+ @has_warnings = false
end
- ##
- # Invokes the #colorize method the with provided string
- # and the color code "31" (for red)
- def red(string)
- colorize(string, 31)
+ def log(obj, level)
+ @has_warnings ||= level == :warn
+ message = Message.new(Time.now, level, obj.to_s.split("\n"))
+ @messages << message
+ @loggers.each {|logger| logger.log(message) }
end
- ##
- # Wraps the provided string in colorizing tags to provide
- # easier to view output to the client
- def colorize(string, code)
- "\e[#{code}m#{string}\e[0m"
- end
-
end
+
+ initialize!
end
end