diff options
author | Luke Kanies <luke@madstop.com> | 2009-07-05 23:10:02 -0700 |
---|---|---|
committer | test branch <puppet-dev@googlegroups.com> | 2010-02-17 06:50:53 -0800 |
commit | 379ac8fe91d25f9b77a47029484d60c09b8f8073 (patch) | |
tree | e6116066d1e1763718c4d078dfd36dfd192f684c | |
parent | b2d172878778156a6b6a9ff6088500eebec71a86 (diff) | |
download | puppet-379ac8fe91d25f9b77a47029484d60c09b8f8073.tar.gz puppet-379ac8fe91d25f9b77a47029484d60c09b8f8073.tar.xz puppet-379ac8fe91d25f9b77a47029484d60c09b8f8073.zip |
Moving log destination code into separate files
Signed-off-by: Luke Kanies <luke@madstop.com>
-rw-r--r-- | lib/puppet/util/log.rb | 282 | ||||
-rw-r--r-- | lib/puppet/util/log/destination.rb | 49 | ||||
-rw-r--r-- | lib/puppet/util/log/destinations.rb | 226 |
3 files changed, 281 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. diff --git a/lib/puppet/util/log/destination.rb b/lib/puppet/util/log/destination.rb new file mode 100644 index 000000000..85959072e --- /dev/null +++ b/lib/puppet/util/log/destination.rb @@ -0,0 +1,49 @@ +# A type of log destination. +class Puppet::Util::Log::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 + diff --git a/lib/puppet/util/log/destinations.rb b/lib/puppet/util/log/destinations.rb new file mode 100644 index 000000000..40e41c061 --- /dev/null +++ b/lib/puppet/util/log/destinations.rb @@ -0,0 +1,226 @@ +Puppet::Util::Log.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 + +Puppet::Util::Log.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 + +Puppet::Util::Log.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 false; str + when true, :ansi, "ansi"; console_color(level, str) + when :html, "html"; html_color(level, 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 + +Puppet::Util::Log.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. +Puppet::Util::Log.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. +Puppet::Util::Log.newdesttype :array do + match "Array" + + def initialize(array) + @array = array + end + + def handle(msg) + @array << msg + end +end + |