class Log

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.

Public Class Methods

autoflush=(v) click to toggle source
# File lib/puppet/util/log.rb, line 71
def Log.autoflush=(v)
  @destinations.each do |type, dest|
    dest.autoflush = v if dest.respond_to?(:autoflush=)
  end
end
close(destination) click to toggle source

Reset log to basics. Basically just flushes and closes files and undefs other objects.

# File lib/puppet/util/log.rb, line 49
def Log.close(destination)
  if @destinations.include?(destination)
    @destinations[destination].flush if @destinations[destination].respond_to?(:flush)
    @destinations[destination].close if @destinations[destination].respond_to?(:close)
    @destinations.delete(destination)
  end
end
close_all() click to toggle source
# File lib/puppet/util/log.rb, line 57
def self.close_all
  destinations.keys.each { |dest|
    close(dest)
  }
  raise Puppet::DevError.new("Log.close_all failed to close #{@destinations.keys.inspect}") if !@destinations.empty?
end
create(hash) click to toggle source

Create a new log message. The primary role of this method is to avoid creating log messages below the loglevel.

# File lib/puppet/util/log.rb, line 79
def Log.create(hash)
  raise Puppet::DevError, "Logs require a level" unless hash.include?(:level)
  raise Puppet::DevError, "Invalid log level #{hash[:level]}" unless @levels.index(hash[:level])
  @levels.index(hash[:level]) >= @loglevel ? Puppet::Util::Log.new(hash) : nil
end
destinations() click to toggle source
# File lib/puppet/util/log.rb, line 85
def Log.destinations
  @destinations
end
eachlevel() { |level| ... } click to toggle source

Yield each valid level in turn

# File lib/puppet/util/log.rb, line 90
def Log.eachlevel
  @levels.each { |level| yield level }
end
flush() click to toggle source

Flush any log destinations that support such operations.

# File lib/puppet/util/log.rb, line 65
def Log.flush
  @destinations.each { |type, dest|
    dest.flush if dest.respond_to?(:flush)
  }
end
flushqueue() click to toggle source
# File lib/puppet/util/log.rb, line 165
def Log.flushqueue
  return unless @destinations.size >= 1
  @queued.each do |msg|
    Log.newmessage(msg)
  end
  @queued.clear
end
force_flushqueue() click to toggle source

Flush the logging queue. If there are no destinations available,

adds in a console logger before flushing the queue.

This is mainly intended to be used as a last-resort attempt

to ensure that logging messages are not thrown away before
the program is about to exit--most likely in a horrific
error scenario.

@return nil

# File lib/puppet/util/log.rb, line 180
def Log.force_flushqueue()
  if (@destinations.empty? and !(@queued.empty?))
    newdestination(:console)
  end
  flushqueue
end
level() click to toggle source

Return the current log level.

# File lib/puppet/util/log.rb, line 95
def Log.level
  @levels[@loglevel]
end
level=(level) click to toggle source

Set the current log level.

# File lib/puppet/util/log.rb, line 100
def Log.level=(level)
  level = level.intern unless level.is_a?(Symbol)

  raise Puppet::DevError, "Invalid loglevel #{level}" unless @levels.include?(level)

  @loglevel = @levels.index(level)
end
levels() click to toggle source
# File lib/puppet/util/log.rb, line 108
def Log.levels
  @levels.dup
end
new(args) click to toggle source
# File lib/puppet/util/log.rb, line 226
def initialize(args)
  self.level = args[:level]
  self.message = args[:message]
  self.source = args[:source] || "Puppet"

  @time = Time.now

  if tags = args[:tags]
    tags.each { |t| self.tag(t) }
  end

  [:file, :line].each do |attr|
    next unless value = args[attr]
    send(attr.to_s + "=", value)
  end

  Log.newmessage(self)
end
newdestination(dest) click to toggle source

Create a new log destination.

# File lib/puppet/util/log.rb, line 113
def Log.newdestination(dest)
  # Each destination can only occur once.
  if @destinations.find { |name, obj| obj.name == dest }
    return
  end

  name, type = @desttypes.find do |name, klass|
    klass.match?(dest)
  end

  if type.respond_to?(:suitable?) and not type.suitable?(dest)
    return
  end

  raise Puppet::DevError, "Unknown destination type #{dest}" unless type

  begin
    if type.instance_method(:initialize).arity == 1
      @destinations[dest] = type.new(dest)
    else
      @destinations[dest] = type.new
    end
    flushqueue
    @destinations[dest]
  rescue => detail
    Puppet.log_exception(detail)

    # If this was our only destination, then add the console back in.
    newdestination(:console) if @destinations.empty? and (dest != :console and dest != "console")
  end
end
newdesttype(name, options = {}, &block) click to toggle source

Create a new destination type.

# File lib/puppet/util/log.rb, line 18
def self.newdesttype(name, options = {}, &block)

  dest = genclass(
    name,
    :parent     => Puppet::Util::Log::Destination,
    :prefix     => "Dest",
    :block      => block,
    :hash       => @desttypes,
    :attributes => options
  )
  dest.match(dest.name)

  dest
end
newmessage(msg) click to toggle source

Route the actual message. FIXME There are lots of things this method should do, like caching and a bit more. It’s worth noting that there’s a potential for a loop here, if the machine somehow gets the destination set as itself.

# File lib/puppet/util/log.rb, line 149
def Log.newmessage(msg)
  return if @levels.index(msg.level) < @loglevel

  queuemessage(msg) if @destinations.length == 0

  @destinations.each do |name, dest|
    threadlock(dest) do
      dest.handle(msg)
    end
  end
end
queuemessage(msg) click to toggle source
# File lib/puppet/util/log.rb, line 161
def Log.queuemessage(msg)
  @queued.push(msg)
end
reopen() click to toggle source

Reopen all of our logs.

# File lib/puppet/util/log.rb, line 192
def Log.reopen
  Puppet.notice "Reopening log files"
  types = @destinations.keys
  @destinations.each { |type, dest|
    dest.close if dest.respond_to?(:close)
  }
  @destinations.clear
  # We need to make sure we always end up with some kind of destination
  begin
    types.each { |type|
      Log.newdestination(type)
    }
  rescue => detail
    if @destinations.empty?
      Log.setup_default
      Puppet.err detail.to_s
    end
  end
end
sendlevel?(level) click to toggle source
# File lib/puppet/util/log.rb, line 187
def Log.sendlevel?(level)
  @levels.index(level) >= @loglevel
end
setup_default() click to toggle source
# File lib/puppet/util/log.rb, line 212
def self.setup_default
  Log.newdestination(
    (Puppet.features.syslog?   ? :syslog   :
    (Puppet.features.eventlog? ? :eventlog : Puppet[:puppetdlog])))
end
validlevel?(level) click to toggle source

Is the passed level a valid log level?

# File lib/puppet/util/log.rb, line 219
def self.validlevel?(level)
  @levels.include?(level)
end

Public Instance Methods

level=(level) click to toggle source
# File lib/puppet/util/log.rb, line 250
def level=(level)
  raise ArgumentError, "Puppet::Util::Log requires a log level" unless level
  raise ArgumentError, "Puppet::Util::Log requires a symbol or string" unless level.respond_to? "to_sym"
  @level = level.to_sym
  raise ArgumentError, "Invalid log level #{@level}" unless self.class.validlevel?(@level)

  # Tag myself with my log level
  tag(level)
end
message=(msg) click to toggle source
# File lib/puppet/util/log.rb, line 245
def message=(msg)
  raise ArgumentError, "Puppet::Util::Log requires a message" unless msg
  @message = msg.to_s
end
source=(source) click to toggle source

If they pass a source in to us, we make sure it is a string, and we retrieve any tags we can.

# File lib/puppet/util/log.rb, line 262
def source=(source)
  if source.respond_to?(:source_descriptors)
    descriptors = source.source_descriptors
    @source = descriptors[:path]

    descriptors[:tags].each { |t| tag(t) }

    [:file, :line].each do |param|
      next unless descriptors[param]
      send(param.to_s + "=", descriptors[param])
    end
  else
    @source = source.to_s
  end
end
to_report() click to toggle source
# File lib/puppet/util/log.rb, line 278
def to_report
  "#{time} #{source} (#{level}): #{to_s}"
end
to_s() click to toggle source
# File lib/puppet/util/log.rb, line 282
def to_s
  message
end