Warning: session_start(): Session cannot be started after headers have already been sent in /home/tvrreohg/public_html/manga.php on line 13
# frozen_string_literal: true
require_relative '../../puppet/util/tagging'
require_relative '../../puppet/util/classgen'
require_relative '../../puppet/util/psych_support'
require_relative '../../puppet/network/format_support'
# 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::PsychSupport
include Puppet::Util::Tagging
include Puppet::Network::FormatSupport
@levels = [:debug, :info, :notice, :warning, :err, :alert, :emerg, :crit]
@loglevel = 2
@desttypes = {}
# Create a new destination type.
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
require_relative 'log/destination'
require_relative 'log/destinations'
@destinations = {}
@queued = []
class << self
include Puppet::Util
include Puppet::Util::ClassGen
attr_reader :desttypes
end
# Reset log to basics. Basically just flushes and closes files and
# undefs other objects.
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
def self.close_all
@destinations.keys.each { |dest|
close(dest)
}
# TRANSLATORS "Log.close_all" is a method name and should not be translated
raise Puppet::DevError, _("Log.close_all failed to close %{destinations}") % { destinations: @destinations.keys.inspect } unless @destinations.empty?
end
# Flush any log destinations that support such operations.
def Log.flush
@destinations.each { |_type, dest|
dest.flush if dest.respond_to?(:flush)
}
end
def Log.autoflush=(v)
@destinations.each do |_type, dest|
dest.autoflush = v if dest.respond_to?(:autoflush=)
end
end
# Create a new log message. The primary role of this method is to
# avoid creating log messages below the loglevel.
def Log.create(hash)
raise Puppet::DevError, _("Logs require a level") unless hash.include?(:level)
raise Puppet::DevError, _("Invalid log level %{level}") % { level: hash[:level] } unless @levels.index(hash[:level])
@levels.index(hash[:level]) >= @loglevel ? Puppet::Util::Log.new(hash) : nil
end
def Log.destinations
@destinations
end
# Yield each valid level in turn
def Log.eachlevel
@levels.each { |level| yield level }
end
# Return the current log level.
def Log.level
@levels[@loglevel]
end
# Set the current log level.
def Log.level=(level)
level = level.intern unless level.is_a?(Symbol)
# loglevel is a 0-based index
loglevel = @levels.index(level)
raise Puppet::DevError, _("Invalid loglevel %{level}") % { level: level } unless loglevel
return if @loglevel == loglevel
# loglevel changed
@loglevel = loglevel
# Enable or disable Facter debugging
Puppet.runtime[:facter].debugging(level == :debug)
end
def Log.levels
@levels.dup
end
# Create a new log destination.
def Log.newdestination(dest)
# Each destination can only occur once.
if @destinations.find { |_name, obj| obj.name == dest }
return
end
_, type = @desttypes.find do |_name, klass|
klass.match?(dest)
end
if type.respond_to?(:suitable?) and !type.suitable?(dest)
return
end
raise Puppet::DevError, _("Unknown destination type %{dest}") % { dest: 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.
if destinations.empty? && dest.intern != :console
newdestination(:console)
end
# Re-raise (end exit Puppet) because we could not set up logging correctly.
raise detail
end
end
def Log.with_destination(destination, &block)
if @destinations.include?(destination)
yield
else
newdestination(destination)
begin
yield
ensure
close(destination)
end
end
end
def Log.coerce_string(str)
return Puppet::Util::CharacterEncoding.convert_to_utf_8(str) if str.valid_encoding?
# We only select the last 10 callers in the stack to avoid being spammy
message = _("Received a Log attribute with invalid encoding:%{log_message}") %
{ log_message: Puppet::Util::CharacterEncoding.convert_to_utf_8(str.dump) }
message += '\n' + _("Backtrace:\n%{backtrace}") % { backtrace: caller(1, 10).join("\n") }
message
end
private_class_method :coerce_string
# 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.
def Log.newmessage(msg)
return if @levels.index(msg.level) < @loglevel
msg.message = coerce_string(msg.message)
msg.source = coerce_string(msg.source)
queuemessage(msg) if @destinations.length == 0
@destinations.each do |_name, dest|
dest.handle(msg)
end
end
def Log.queuemessage(msg)
@queued.push(msg)
end
def Log.flushqueue
return unless @destinations.size >= 1
@queued.each do |msg|
Log.newmessage(msg)
end
@queued.clear
end
# 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
def Log.force_flushqueue
if @destinations.empty? and !@queued.empty?
newdestination(:console)
end
flushqueue
end
def Log.sendlevel?(level)
@levels.index(level) >= @loglevel
end
# Reopen all of our logs.
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
def self.setup_default
Log.newdestination(
if Puppet.features.syslog?
:syslog
else
Puppet.features.eventlog? ? :eventlog : Puppet[:puppetdlog]
end
)
end
# Is the passed level a valid log level?
def self.validlevel?(level)
@levels.include?(level)
end
def self.from_data_hash(data)
obj = allocate
obj.initialize_from_hash(data)
obj
end
# Log output using scope and level
#
# @param [Puppet::Parser::Scope] scope
# @param [Symbol] level log level
# @param [Array