module Puppet::Util::Logging
Public Class Methods
Sets up Facter logging. This method causes Facter output to be forwarded to Puppet
.
# File lib/puppet/util/logging.rb 256 def self.setup_facter_logging! 257 # Only recent versions of Facter support this feature 258 return false unless Facter.respond_to? :on_message 259 260 # The current Facter log levels are: :trace, :debug, :info, :warn, :error, and :fatal. 261 # Convert to the corresponding levels in Puppet 262 Facter.on_message do |level, message| 263 case level 264 when :trace, :debug 265 level = :debug 266 when :info 267 # Same as Puppet 268 when :warn 269 level = :warning 270 when :error 271 level = :err 272 when :fatal 273 level = :crit 274 else 275 next 276 end 277 Puppet::Util::Log.create({:level => level, :source => 'Facter', :message => message}) 278 nil 279 end 280 true 281 end
Public Instance Methods
# File lib/puppet/util/logging.rb 215 def clear_deprecation_warnings 216 $unique_warnings.clear if $unique_warnings 217 $deprecation_warnings.clear if $deprecation_warnings 218 end
Output a debug log message if debugging is on (but only then) If the output is anything except a static string, give the debug a block - it will be called with all other arguments, and is expected to return the single string result.
Use a block at all times for increased performance.
@example This takes 40% of the time compared to not using a block
Puppet.debug { "This is a string that interpolated #{x} and #{y} }"
# File lib/puppet/util/logging.rb 34 def debug(*args) 35 return nil unless Puppet::Util::Log.level == :debug 36 if block_given? 37 send_log(:debug, yield(*args)) 38 else 39 send_log(:debug, args.join(" ")) 40 end 41 end
Logs a warning indicating that the Ruby code path is deprecated. Note that this method keeps track of the offending lines of code that triggered the deprecation warning, and will only log a warning once per offending line of code. It will also stop logging deprecation warnings altogether after 100 unique deprecation warnings have been logged. Finally, if Puppet includes 'deprecations', it will squelch all warning calls made via this method.
@param message [String] The message to log (logs via warning) @param key [String] Optional key to mark the message as unique. If not
passed in, the originating call line will be used instead.
# File lib/puppet/util/logging.rb 142 def deprecation_warning(message, key = nil) 143 issue_deprecation_warning(message, key, nil, nil, true) 144 end
# File lib/puppet/util/logging.rb 112 def format_backtrace(exception, combined_trace, puppet_trace) 113 puppetstack = exception.respond_to?(:puppetstack) ? exception.puppetstack : [] 114 115 if combined_trace and exception.backtrace 116 Puppet::Util.format_backtrace_array(exception.backtrace, puppetstack) 117 elsif puppet_trace && !puppetstack.empty? 118 Puppet::Util.format_backtrace_array(puppetstack) 119 else 120 [] 121 end 122 end
# File lib/puppet/util/logging.rb 91 def format_exception(exception, message = :default, combined_trace = true, puppet_trace = false) 92 arr = [] 93 case message 94 when :default 95 arr << exception.message 96 when nil 97 # don't log anything if they passed a nil; they are just calling for the optional backtrace logging 98 else 99 arr << message 100 end 101 102 arr += format_backtrace(exception, combined_trace, puppet_trace) 103 104 if exception.respond_to?(:original) and exception.original 105 arr << _("Wrapped exception:") 106 arr << format_exception(exception.original, :default, combined_trace, puppet_trace) 107 end 108 109 arr.flatten.join("\n") 110 end
# File lib/puppet/util/logging.rb 202 def get_deprecation_offender() 203 # we have to put this in its own method to simplify testing; we need to be able to mock the offender results in 204 # order to test this class, and our framework does not appear to enjoy it if you try to mock Kernel.caller 205 # 206 # let's find the offending line; we need to jump back up the stack a few steps to find the method that called 207 # the deprecated method 208 if Puppet[:trace] 209 caller(3) 210 else 211 [caller(3, 1).first] 212 end 213 end
# File lib/puppet/util/logging.rb 124 def log_and_raise(exception, message) 125 log_exception(exception, message) 126 raise exception, message + "\n" + exception.to_s, exception.backtrace 127 end
utility method that can be called, e.g., from spec_helper config.after, when tracking down calls to deprecated code. Parameters:
- deprecations_file
-
relative or absolute path of a file to log the deprecations to
- pattern
-
(default nil) if specified, will only log deprecations whose message matches the provided pattern
# File lib/puppet/util/logging.rb 228 def log_deprecations_to_file(deprecations_file, pattern = nil) 229 # this method may get called lots and lots of times (e.g., from spec_helper config.after) without the global 230 # list of deprecation warnings being cleared out. We don't want to keep logging the same offenders over and over, 231 # so, we need to keep track of what we've logged. 232 # 233 # It'd be nice if we could just clear out the list of deprecation warnings, but then the very next spec might 234 # find the same offender, and we'd end up logging it again. 235 $logged_deprecation_warnings ||= {} 236 237 # Deprecation messages are UTF-8 as they are produced by Ruby 238 Puppet::FileSystem.open(deprecations_file, nil, "a:UTF-8") do |f| 239 if ($deprecation_warnings) then 240 $deprecation_warnings.each do |offender, message| 241 if (! $logged_deprecation_warnings.has_key?(offender)) then 242 $logged_deprecation_warnings[offender] = true 243 if ((pattern.nil?) || (message =~ pattern)) then 244 f.puts(message) 245 f.puts(offender) 246 f.puts() 247 end 248 end 249 end 250 end 251 end 252 end
Log
an exception via Puppet.err. Will also log the backtrace if Puppet is set. Parameters:
- exception
-
an Exception to log
- message
-
an optional String overriding the message to be logged; by default, we log Exception.message.
If you pass a String here, your string will be logged instead. You may also pass nil if you don't wish to log a message at all; in this case it is likely that you are only calling this method in order to take advantage of the backtrace logging.
# File lib/puppet/util/logging.rb 50 def log_exception(exception, message = :default, options = {}) 51 level = options[:level] || :err 52 combined_trace = Puppet[:trace] || options[:trace] 53 puppet_trace = Puppet[:puppet_trace] || options[:puppet_trace] 54 55 if message == :default && exception.is_a?(Puppet::ParseErrorWithIssue) 56 # Retain all detailed info and keep plain message and stacktrace separate 57 backtrace = build_exception_trace(exception, combined_trace, puppet_trace) 58 Puppet::Util::Log.create({ 59 :level => level, 60 :source => log_source, 61 :message => exception.basic_message, 62 :issue_code => exception.issue_code, 63 :backtrace => backtrace.empty? ? nil : backtrace, 64 :file => exception.file, 65 :line => exception.line, 66 :pos => exception.pos, 67 :environment => exception.environment, 68 :node => exception.node 69 }.merge(log_metadata)) 70 else 71 send_log(level, format_exception(exception, message, combined_trace, puppet_trace)) 72 end 73 end
Logs a warning whose origin comes from Puppet
source rather than somewhere internal within Puppet
. Otherwise the same as deprecation_warning
()
@param message [String] The message to log (logs via warning) @param options [Hash] @option options [String] :file File we are warning from @option options [Integer] :line Line number we are warning from @option options [String] :key (:file + :line) Alternative key used to mark
warning as unique
Either :file and :line and/or :key must be passed.
# File lib/puppet/util/logging.rb 157 def puppet_deprecation_warning(message, options = {}) 158 key = options[:key] 159 file = options[:file] 160 line = options[:line] 161 #TRANSLATORS the literals ":file", ":line", and ":key" should not be translated 162 raise Puppet::DevError, _("Need either :file and :line, or :key") if (key.nil?) && (file.nil? || line.nil?) 163 164 key ||= "#{file}:#{line}" 165 issue_deprecation_warning(message, key, file, line, false) 166 end
# File lib/puppet/util/logging.rb 10 def send_log(level, message) 11 Puppet::Util::Log.create({:level => level, :source => log_source, :message => message}.merge(log_metadata)) 12 end
Logs a (non deprecation) warning once for a given key.
@param kind [String] The kind of warning. The
kind must be one of the defined kinds for the Puppet[:disable_warnings] setting.
@param message [String] The message to log (logs via warning) @param key [String] Key used to make this warning unique @param file [String,:default,nil] the File related to the warning @param line [Integer,:default,nil] the Line number related to the warning
warning as unique
@param level [Symbol] log level to use, defaults to :warning
Either :file and :line and/or :key must be passed.
# File lib/puppet/util/logging.rb 180 def warn_once(kind, key, message, file = nil, line = nil, level = :warning) 181 return if Puppet[:disable_warnings].include?(kind) 182 $unique_warnings ||= {} 183 if $unique_warnings.length < 100 then 184 if (! $unique_warnings.has_key?(key)) then 185 $unique_warnings[key] = message 186 call_trace = if file == :default and line == :default 187 # Suppress the file and line number output 188 '' 189 else 190 error_location_str = Puppet::Util::Errors.error_location(file, line) 191 if error_location_str.empty? 192 "\n " + _('(file & line not available)') 193 else 194 "\n %{error_location}" % { error_location: error_location_str } 195 end 196 end 197 send_log(level, "#{message}#{call_trace}") 198 end 199 end 200 end
Private Instance Methods
# File lib/puppet/util/logging.rb 75 def build_exception_trace(exception, combined_trace = true, puppet_trace = false) 76 built_trace = format_backtrace(exception, combined_trace, puppet_trace) 77 78 if exception.respond_to?(:original) 79 original = exception.original 80 unless original.nil? 81 built_trace << _('Wrapped exception:') 82 built_trace << original.message 83 built_trace += build_exception_trace(original, combined_trace, puppet_trace) 84 end 85 end 86 87 built_trace 88 end
# File lib/puppet/util/logging.rb 303 def is_resource? 304 defined?(Puppet::Type) && is_a?(Puppet::Type) 305 end
# File lib/puppet/util/logging.rb 307 def is_resource_parameter? 308 defined?(Puppet::Parameter) && is_a?(Puppet::Parameter) 309 end
# File lib/puppet/util/logging.rb 285 def issue_deprecation_warning(message, key, file, line, use_caller) 286 return if Puppet[:disable_warnings].include?('deprecations') 287 $deprecation_warnings ||= {} 288 if $deprecation_warnings.length < 100 289 key ||= (offender = get_deprecation_offender) 290 unless $deprecation_warnings.has_key?(key) 291 $deprecation_warnings[key] = message 292 # split out to allow translation 293 call_trace = if use_caller 294 _("(location: %{location})") % { location: (offender || get_deprecation_offender).join('; ') } 295 else 296 Puppet::Util::Errors.error_location_with_unknowns(file, line) 297 end 298 warning("%{message}\n %{call_trace}" % { message: message, call_trace: call_trace }) 299 end 300 end 301 end
# File lib/puppet/util/logging.rb 311 def log_metadata 312 [:file, :line, :tags].inject({}) do |result, attr| 313 result[attr] = send(attr) if respond_to?(attr) 314 result 315 end 316 end
# File lib/puppet/util/logging.rb 318 def log_source 319 # We need to guard the existence of the constants, since this module is used by the base Puppet module. 320 (is_resource? or is_resource_parameter?) and respond_to?(:path) and return path.to_s 321 to_s 322 end