diff options
Diffstat (limited to 'lib/puppet/util/log.rb')
-rw-r--r-- | lib/puppet/util/log.rb | 282 |
1 files changed, 6 insertions, 276 deletions
diff --git a/lib/puppet/util/log.rb b/lib/puppet/util/log.rb index 90d722900..997aa1810 100644 --- a/lib/puppet/util/log.rb +++ b/lib/puppet/util/log.rb @@ -1,11 +1,13 @@ require 'syslog' require 'puppet/util/tagging' +require 'puppet/util/classgen' # Pass feedback to the user. Log levels are modeled after syslog's, and it is # expected that that will be the most common log destination. Supports # multiple destinations, one of which is a remote server. class Puppet::Util::Log include Puppet::Util + extend Puppet::Util::ClassGen include Puppet::Util::Tagging @levels = [:debug,:info,:notice,:warning,:err,:alert,:emerg,:crit] @@ -13,58 +15,9 @@ class Puppet::Util::Log @desttypes = {} - # A type of log destination. - class Destination - class << self - attr_accessor :name - end - - def self.initvars - @matches = [] - end - - # Mark the things we're supposed to match. - def self.match(obj) - @matches ||= [] - @matches << obj - end - - # See whether we match a given thing. - def self.match?(obj) - # Convert single-word strings into symbols like :console and :syslog - if obj.is_a? String and obj =~ /^\w+$/ - obj = obj.downcase.intern - end - - @matches.each do |thing| - # Search for direct matches or class matches - return true if thing === obj or thing == obj.class.to_s - end - return false - end - - def name - if defined? @name - return @name - else - return self.class.name - end - end - - # Set how to handle a message. - def self.sethandler(&block) - define_method(:handle, &block) - end - - # Mark how to initialize our object. - def self.setinit(&block) - define_method(:initialize, &block) - end - end - # Create a new destination type. def self.newdesttype(name, options = {}, &block) - dest = genclass(name, :parent => Destination, :prefix => "Dest", + dest = genclass(name, :parent => Puppet::Util::Log::Destination, :prefix => "Dest", :block => block, :hash => @desttypes, :attributes => options @@ -74,6 +27,9 @@ class Puppet::Util::Log return dest end + require 'puppet/util/log/destination' + require 'puppet/util/log/destinations' + @destinations = {} class << self @@ -167,232 +123,6 @@ class Puppet::Util::Log @levels.dup end - newdesttype :syslog do - def close - Syslog.close - end - - def initialize - if Syslog.opened? - Syslog.close - end - name = Puppet[:name] - name = "puppet-#{name}" unless name =~ /puppet/ - - options = Syslog::LOG_PID | Syslog::LOG_NDELAY - - # XXX This should really be configurable. - str = Puppet[:syslogfacility] - begin - facility = Syslog.const_get("LOG_#{str.upcase}") - rescue NameError - raise Puppet::Error, "Invalid syslog facility %s" % str - end - - @syslog = Syslog.open(name, options, facility) - end - - def handle(msg) - # XXX Syslog currently has a bug that makes it so you - # cannot log a message with a '%' in it. So, we get rid - # of them. - if msg.source == "Puppet" - @syslog.send(msg.level, msg.to_s.gsub("%", '%%')) - else - @syslog.send(msg.level, "(%s) %s" % - [msg.source.to_s.gsub("%", ""), - msg.to_s.gsub("%", '%%') - ] - ) - end - end - end - - newdesttype :file do - match(/^\//) - - def close - if defined? @file - @file.close - @file = nil - end - end - - def flush - if defined? @file - @file.flush - end - end - - def initialize(path) - @name = path - # first make sure the directory exists - # We can't just use 'Config.use' here, because they've - # specified a "special" destination. - unless FileTest.exist?(File.dirname(path)) - Puppet.recmkdir(File.dirname(path)) - Puppet.info "Creating log directory %s" % File.dirname(path) - end - - # create the log file, if it doesn't already exist - file = File.open(path, File::WRONLY|File::CREAT|File::APPEND) - - @file = file - - @autoflush = Puppet[:autoflush] - end - - def handle(msg) - @file.puts("%s %s (%s): %s" % - [msg.time, msg.source, msg.level, msg.to_s]) - - @file.flush if @autoflush - end - end - - newdesttype :console do - - - RED = {:console => "[0;31m", :html => "FFA0A0"} - GREEN = {:console => "[0;32m", :html => "00CD00"} - YELLOW = {:console => "[0;33m", :html => "FFFF60"} - BLUE = {:console => "[0;34m", :html => "80A0FF"} - PURPLE = {:console => "[0;35m", :html => "FFA500"} - CYAN = {:console => "[0;36m", :html => "40FFFF"} - WHITE = {:console => "[0;37m", :html => "FFFFFF"} - HRED = {:console => "[1;31m", :html => "FFA0A0"} - HGREEN = {:console => "[1;32m", :html => "00CD00"} - HYELLOW = {:console => "[1;33m", :html => "FFFF60"} - HBLUE = {:console => "[1;34m", :html => "80A0FF"} - HPURPLE = {:console => "[1;35m", :html => "FFA500"} - HCYAN = {:console => "[1;36m", :html => "40FFFF"} - HWHITE = {:console => "[1;37m", :html => "FFFFFF"} - RESET = {:console => "[0m", :html => "" } - - @@colormap = { - :debug => WHITE, - :info => GREEN, - :notice => CYAN, - :warning => YELLOW, - :err => HPURPLE, - :alert => RED, - :emerg => HRED, - :crit => HRED - } - - def colorize(level, str) - case Puppet[:color] - when true, :ansi, "ansi", :yes, "yes"; console_color(level, str) - when :html, "html"; html_color(level, str) - else str - end - end - - def console_color(level, str) - @@colormap[level][:console] + str + RESET[:console] - end - - def html_color(level, str) - %{<span style="color: %s">%s</span>} % [@@colormap[level][:html], str] - end - - def initialize - # Flush output immediately. - $stdout.sync = true - end - - def handle(msg) - if msg.source == "Puppet" - puts colorize(msg.level, "%s: %s" % [msg.level, msg.to_s]) - else - puts colorize(msg.level, "%s: %s: %s" % [msg.level, msg.source, msg.to_s]) - end - end - end - - newdesttype :host do - def initialize(host) - Puppet.info "Treating %s as a hostname" % host - args = {} - if host =~ /:(\d+)/ - args[:Port] = $1 - args[:Server] = host.sub(/:\d+/, '') - else - args[:Server] = host - end - - @name = host - - @driver = Puppet::Network::Client::LogClient.new(args) - end - - def handle(msg) - unless msg.is_a?(String) or msg.remote - unless defined? @hostname - @hostname = Facter["hostname"].value - end - unless defined? @domain - @domain = Facter["domain"].value - if @domain - @hostname += "." + @domain - end - end - if msg.source =~ /^\// - msg.source = @hostname + ":" + msg.source - elsif msg.source == "Puppet" - msg.source = @hostname + " " + msg.source - else - msg.source = @hostname + " " + msg.source - end - begin - #puts "would have sent %s" % msg - #puts "would have sent %s" % - # CGI.escape(YAML.dump(msg)) - begin - tmp = CGI.escape(YAML.dump(msg)) - rescue => detail - puts "Could not dump: %s" % detail.to_s - return - end - # Add the hostname to the source - @driver.addlog(tmp) - rescue => detail - if Puppet[:trace] - puts detail.backtrace - end - Puppet.err detail - Puppet::Util::Log.close(self) - end - end - end - end - - # Log to a transaction report. - newdesttype :report do - match "Puppet::Transaction::Report" - - def initialize(report) - @report = report - end - - def handle(msg) - @report.newlog(msg) - end - end - - # Log to an array, just for testing. - newdesttype :array do - match "Array" - - def initialize(array) - @array = array - end - - def handle(msg) - @array << msg - end - end - # Create a new log destination. def Log.newdestination(dest) # Each destination can only occur once. |