class Report
This class is used to report what happens on a client. There are two types of data in a report; Logs and Metrics.
-
Logs - are the output that each change produces.
-
Metrics - are all of the numerical data involved in the transaction.
Use {Puppet::Reports} class to create a new custom report type. This class is indirectly used as a source of data to report in such a registered report.
##Metrics There are three types of metrics in each report, and each type of metric has one or more values.
-
Time: Keeps track of how long things took.
-
Total: Total time for the configuration run
-
File:
-
Exec:
-
User:
-
Group:
-
Config Retrieval: How long the configuration took to retrieve
-
Service:
-
Package:
-
-
Resources: Keeps track of the following stats:
-
Total: The total number of resources being managed
-
Skipped: How many resources were skipped, because of either tagging or scheduling restrictions
-
Scheduled: How many resources met any scheduling restrictions
-
Out of Sync: How many resources were out of sync
-
Applied: How many resources were attempted to be fixed
-
Failed: How many resources were not successfully fixed
-
Restarted: How many resources were restarted because their dependencies changed
-
Failed Restarts: How many resources could not be restarted
-
-
Changes: The total number of changes in the transaction.
@api public
Constants
- TOTAL
Attributes
Whether a cached catalog was used in the run, and if so, the reason that it was used. @return [String] One of the values: 'not_used', 'explicitly_requested', or 'on_failure'
A master generated catalog uuid, useful for connecting a single catalog to multiple reports.
The id of the code input to the compiler.
The version of the configuration @todo Uncertain what this is? @return [???] the configuration version
@!attribute [r] corrective_change
@return [Boolean] true if the report contains any events and resources that had corrective changes, including noop corrective changes.
The name of the environment the host is in @return [String] the environment name
The host name for which the report is generated @return [String] the host name
The name of the environment the agent initially started in @return [String] the environment name
The id of the job responsible for this run.
A list of log messages. @return [Array<Puppet::Util::Log>] logged messages
A hash of metric name to metric value. @return [Hash<{String => Object}>] A map of metric name to value. @todo Uncertain if all values are numbers - now marked as Object
.
Whether the puppet run was started in noop mode @return [Boolean]
Whether there are changes that we decided not to apply because of noop @return [Boolean]
@return [String] The Puppet
version in String form. @see Puppet::version()
@return [Integer] report format version number. This value is constant for
a given version of Puppet; it is incremented when a new release of Puppet changes the API for the various objects that make up a report.
A hash with a map from resource to status @return [Hash{String => Puppet::Resource::Status}] Resource name to status.
@return [Boolean] true if one or more resources attempted to generate
resources and failed
Contains the name and port of the server that was successfully contacted @return [String] a string of the format 'servername:port'
The status of the client run is an enumeration: 'failed', 'changed' or 'unchanged' @return [String] the status of the run - one of the values 'failed', 'changed', or 'unchanged'
The time when the report data was generated. @return [Time] A time object indicating when the report data was generated
@return [Boolean] true if the transaction completed it's evaluate
An agent generated transaction uuid, useful for connecting catalog and report @return [String] uuid
Public Class Methods
# File lib/puppet/transaction/report.rb 143 def self.from_data_hash(data) 144 obj = self.allocate 145 obj.initialize_from_hash(data) 146 obj 147 end
@api private
# File lib/puppet/transaction/report.rb 224 def initialize(configuration_version=nil, environment=nil, transaction_uuid=nil, job_id=nil, start_time=Time.now) 225 @metrics = {} 226 @logs = [] 227 @resource_statuses = {} 228 @external_times ||= {} 229 @host = Puppet[:node_name_value] 230 @time = start_time 231 @report_format = 12 232 @puppet_version = Puppet.version 233 @configuration_version = configuration_version 234 @transaction_uuid = transaction_uuid 235 @code_id = nil 236 @job_id = job_id 237 @catalog_uuid = nil 238 @cached_catalog_status = nil 239 @server_used = nil 240 @environment = environment 241 @status = 'failed' # assume failed until the report is finalized 242 @noop = Puppet[:noop] 243 @noop_pending = false 244 @corrective_change = false 245 @transaction_completed = false 246 end
Public Instance Methods
@api private
# File lib/puppet/transaction/report.rb 154 def <<(msg) 155 @logs << msg 156 self 157 end
@api private
# File lib/puppet/transaction/report.rb 169 def add_metric(name, hash) 170 metric = Puppet::Util::Metric.new(name) 171 172 hash.each do |metric_name, value| 173 metric.newvalue(metric_name, value) 174 end 175 176 @metrics[metric.name] = metric 177 metric 178 end
@api private
# File lib/puppet/transaction/report.rb 181 def add_resource_status(status) 182 @resource_statuses[status.resource] = status 183 end
@api private
# File lib/puppet/transaction/report.rb 160 def add_times(name, value, accumulate = true) 161 if @external_times[name] && accumulate 162 @external_times[name] += value 163 else 164 @external_times[name] = value 165 end 166 end
# File lib/puppet/transaction/report.rb 149 def as_logging_destination(&block) 150 Puppet::Util::Log.with_destination(self, &block) 151 end
@api private
# File lib/puppet/transaction/report.rb 186 def compute_status(resource_metrics, change_metric) 187 if resources_failed_to_generate || 188 !transaction_completed || 189 (resource_metrics["failed"] || 0) > 0 || 190 (resource_metrics["failed_to_restart"] || 0) > 0 191 'failed' 192 elsif change_metric > 0 193 'changed' 194 else 195 'unchanged' 196 end 197 end
Computes a single number that represents the report's status. The computation is based on the contents of this report's metrics. The resulting number is a bitmask where individual bits represent the presence of different metrics.
-
0x2 set if there are changes
-
0x4 set if there are resource failures or resources that failed to restart
@return [Integer] A bitmask where 0x2 is set if there are changes, and 0x4 is set of there are failures. @api public
# File lib/puppet/transaction/report.rb 416 def exit_status 417 status = 0 418 if @metrics["changes"] && @metrics["changes"][TOTAL] && 419 @metrics["resources"] && @metrics["resources"]["failed"] && 420 @metrics["resources"]["failed_to_restart"] 421 status |= 2 if @metrics["changes"][TOTAL] > 0 422 status |= 4 if @metrics["resources"]["failed"] > 0 423 status |= 4 if @metrics["resources"]["failed_to_restart"] > 0 424 else 425 status = -1 426 end 427 status 428 end
@api private
# File lib/puppet/transaction/report.rb 210 def finalize_report 211 prune_internal_data 212 calculate_report_corrective_change 213 214 resource_metrics = add_metric(:resources, calculate_resource_metrics) 215 add_metric(:time, calculate_time_metrics) 216 change_metric = calculate_change_metric 217 add_metric(:changes, {TOTAL => change_metric}) 218 add_metric(:events, calculate_event_metrics) 219 @status = compute_status(resource_metrics, change_metric) 220 @noop_pending = @resource_statuses.any? { |name,res| has_noop_events?(res) } 221 end
@api private
# File lib/puppet/transaction/report.rb 200 def has_noop_events?(resource) 201 resource.events.any? { |event| event.status == 'noop' } 202 end
@api private
# File lib/puppet/transaction/report.rb 249 def initialize_from_hash(data) 250 @puppet_version = data['puppet_version'] 251 @report_format = data['report_format'] 252 @configuration_version = data['configuration_version'] 253 @transaction_uuid = data['transaction_uuid'] 254 @environment = data['environment'] 255 @status = data['status'] 256 @transaction_completed = data['transaction_completed'] 257 @noop = data['noop'] 258 @noop_pending = data['noop_pending'] 259 @host = data['host'] 260 @time = data['time'] 261 @corrective_change = data['corrective_change'] 262 263 if data['server_used'] 264 @server_used = data['server_used'] 265 elsif data['master_used'] 266 @server_used = data['master_used'] 267 end 268 269 if data['catalog_uuid'] 270 @catalog_uuid = data['catalog_uuid'] 271 end 272 273 if data['job_id'] 274 @job_id = data['job_id'] 275 end 276 277 if data['code_id'] 278 @code_id = data['code_id'] 279 end 280 281 if data['cached_catalog_status'] 282 @cached_catalog_status = data['cached_catalog_status'] 283 end 284 285 if @time.is_a? String 286 @time = Time.parse(@time) 287 end 288 289 @metrics = {} 290 data['metrics'].each do |name, hash| 291 # Older versions contain tags that causes Psych to create instances directly 292 @metrics[name] = hash.is_a?(Puppet::Util::Metric) ? hash : Puppet::Util::Metric.from_data_hash(hash) 293 end 294 295 @logs = data['logs'].map do |record| 296 # Older versions contain tags that causes Psych to create instances directly 297 record.is_a?(Puppet::Util::Log) ? record : Puppet::Util::Log.from_data_hash(record) 298 end 299 300 @resource_statuses = {} 301 data['resource_statuses'].map do |key, rs| 302 @resource_statuses[key] = if rs == Puppet::Resource::EMPTY_HASH 303 nil 304 else 305 # Older versions contain tags that causes Psych to create instances directly 306 rs.is_a?(Puppet::Resource::Status) ? rs : Puppet::Resource::Status.from_data_hash(rs) 307 end 308 end 309 end
@return [String] the host name @api public
# File lib/puppet/transaction/report.rb 342 def name 343 host 344 end
@api private
# File lib/puppet/transaction/report.rb 205 def prune_internal_data 206 resource_statuses.delete_if {|name,res| res.resource_type == 'Whit'} 207 end
Provides a raw hash summary of this report. @return [Hash<{String => Object}>] A hash with metrics key to value map @api public
# File lib/puppet/transaction/report.rb 381 def raw_summary 382 report = { 383 "version" => { 384 "config" => configuration_version, 385 "puppet" => Puppet.version 386 }, 387 "application" => { 388 "run_mode" => Puppet.run_mode.name.to_s, 389 "initial_environment" => initial_environment, 390 "converged_environment" => environment 391 } 392 } 393 394 @metrics.each do |name, metric| 395 key = metric.name.to_s 396 report[key] = {} 397 metric.values.each do |metric_name, label, value| 398 report[key][metric_name.to_s] = value 399 end 400 report[key][TOTAL] = 0 unless key == "time" or report[key].include?(TOTAL) 401 end 402 (report["time"] ||= {})["last_run"] = Time.now.tv_sec 403 report 404 end
Provide a human readable textual summary of this report. @note This is intended for debugging purposes @return [String] A string with a textual summary of this report. @api public
# File lib/puppet/transaction/report.rb 351 def summary 352 report = raw_summary 353 354 ret = "" 355 report.keys.sort_by(&:to_s).each do |key| 356 ret += "#{Puppet::Util::Metric.labelize(key)}:\n" 357 358 report[key].keys.sort { |a,b| 359 # sort by label 360 if a == TOTAL 361 1 362 elsif b == TOTAL 363 -1 364 else 365 report[key][a].to_s <=> report[key][b].to_s 366 end 367 }.each do |label| 368 value = report[key][label] 369 next if value == 0 370 value = "%0.2f" % value if value.is_a?(Float) 371 ret += " %15s %s\n" % [Puppet::Util::Metric.labelize(label) + ":", value] 372 end 373 end 374 ret 375 end
# File lib/puppet/transaction/report.rb 311 def to_data_hash 312 hash = { 313 'host' => @host, 314 'time' => @time.iso8601(9), 315 'configuration_version' => @configuration_version, 316 'transaction_uuid' => @transaction_uuid, 317 'report_format' => @report_format, 318 'puppet_version' => @puppet_version, 319 'status' => @status, 320 'transaction_completed' => @transaction_completed, 321 'noop' => @noop, 322 'noop_pending' => @noop_pending, 323 'environment' => @environment, 324 'logs' => @logs.map { |log| log.to_data_hash }, 325 'metrics' => Hash[@metrics.map { |key, metric| [key, metric.to_data_hash] }], 326 'resource_statuses' => Hash[@resource_statuses.map { |key, rs| [key, rs.nil? ? nil : rs.to_data_hash] }], 327 'corrective_change' => @corrective_change, 328 } 329 330 # The following is include only when set 331 hash['server_used'] = @server_used unless @server_used.nil? 332 hash['catalog_uuid'] = @catalog_uuid unless @catalog_uuid.nil? 333 hash['code_id'] = @code_id unless @code_id.nil? 334 hash['job_id'] = @job_id unless @job_id.nil? 335 hash['cached_catalog_status'] = @cached_catalog_status unless @cached_catalog_status.nil? 336 hash 337 end
Private Instance Methods
# File lib/puppet/transaction/report.rb 439 def calculate_change_metric 440 resource_statuses.map { |name, status| status.change_count || 0 }.inject(0) { |a,b| a+b } 441 end
# File lib/puppet/transaction/report.rb 443 def calculate_event_metrics 444 metrics = Hash.new(0) 445 %w{total failure success}.each { |m| metrics[m] = 0 } 446 resource_statuses.each do |name, status| 447 metrics[TOTAL] += status.events.length 448 status.events.each do |event| 449 metrics[event.status] += 1 450 end 451 end 452 453 metrics 454 end
Mark the report as corrective, if there are any resource_status marked corrective.
# File lib/puppet/transaction/report.rb 433 def calculate_report_corrective_change 434 @corrective_change = resource_statuses.any? do |name, status| 435 status.corrective_change 436 end 437 end
# File lib/puppet/transaction/report.rb 456 def calculate_resource_metrics 457 metrics = {} 458 metrics[TOTAL] = resource_statuses.length 459 460 # force every resource key in the report to be present 461 # even if no resources is in this given state 462 Puppet::Resource::Status::STATES.each do |state| 463 metrics[state.to_s] = 0 464 end 465 466 resource_statuses.each do |name, status| 467 Puppet::Resource::Status::STATES.each do |state| 468 metrics[state.to_s] += 1 if status.send(state) 469 end 470 end 471 472 metrics 473 end
# File lib/puppet/transaction/report.rb 475 def calculate_time_metrics 476 metrics = Hash.new(0) 477 resource_statuses.each do |name, status| 478 metrics[status.resource_type.downcase] += status.evaluation_time if status.evaluation_time 479 end 480 481 @external_times.each do |name, value| 482 metrics[name.to_s.downcase] = value 483 end 484 485 metrics 486 end