From 673613c4a28bb187b2c5d06f6507e78d6ca1f23b Mon Sep 17 00:00:00 2001 From: Johannes Grassler Date: Mon, 1 Sep 2014 12:27:30 +0000 Subject: [PATCH] Add extended logging options. There is a range of extended logging options in Openstack services that use openstack.common.logger (Ceilometer, Cinder, Heat, Keystone, Nova). Adding heat::logging to support them. This change is identical to but it applies to puppet-heat instead of puppet-ceilometer. No blueprint/spec, as discussed in the IRC meeting on 08-11-2014. Change-Id: Ia120b799d676e516d8e593088f93d44891c20cbd (cherry picked from commit 2492ef5fb35258251b41fc692ff7e2b8043e9c0f) --- manifests/logging.pp | 208 ++++++++++++++++++++++++++++++ spec/classes/heat_logging_spec.rb | 107 +++++++++++++++ 2 files changed, 315 insertions(+) create mode 100644 manifests/logging.pp create mode 100644 spec/classes/heat_logging_spec.rb diff --git a/manifests/logging.pp b/manifests/logging.pp new file mode 100644 index 00000000..d18b5c2a --- /dev/null +++ b/manifests/logging.pp @@ -0,0 +1,208 @@ +# Class heat::logging +# +# heat extended logging configuration +# +# == parameters +# +# [*logging_context_format_string*] +# (optional) Format string to use for log messages with context. +# Defaults to undef. +# Example: '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s\ +# [%(request_id)s %(user_identity)s] %(instance)s%(message)s' +# +# [*logging_default_format_string*] +# (optional) Format string to use for log messages without context. +# Defaults to undef. +# Example: '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s\ +# [-] %(instance)s%(message)s' +# +# [*logging_debug_format_suffix*] +# (optional) Formatted data to append to log format when level is DEBUG. +# Defaults to undef. +# Example: '%(funcName)s %(pathname)s:%(lineno)d' +# +# [*logging_exception_prefix*] +# (optional) Prefix each line of exception output with this format. +# Defaults to undef. +# Example: '%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s' +# +# [*log_config_append*] +# The name of an additional logging configuration file. +# Defaults to undef. +# See https://docs.python.org/2/howto/logging.html +# +# [*default_log_levels*] +# (optional) Hash of logger (keys) and level (values) pairs. +# Defaults to undef. +# Example: +# { 'amqp' => 'WARN', 'amqplib' => 'WARN', 'boto' => 'WARN', +# 'qpid' => 'WARN', 'sqlalchemy' => 'WARN', 'suds' => 'INFO', +# 'iso8601' => 'WARN', +# 'requests.packages.urllib3.connectionpool' => 'WARN' } +# +# [*publish_errors*] +# (optional) Publish error events (boolean value). +# Defaults to undef (false if unconfigured). +# +# [*fatal_deprecations*] +# (optional) Make deprecations fatal (boolean value) +# Defaults to undef (false if unconfigured). +# +# [*instance_format*] +# (optional) If an instance is passed with the log message, format it +# like this (string value). +# Defaults to undef. +# Example: '[instance: %(uuid)s] ' +# +# [*instance_uuid_format*] +# (optional) If an instance UUID is passed with the log message, format +# it like this (string value). +# Defaults to undef. +# Example: instance_uuid_format='[instance: %(uuid)s] ' + +# [*log_date_format*] +# (optional) Format string for %%(asctime)s in log records. +# Defaults to undef. +# Example: 'Y-%m-%d %H:%M:%S' + +class heat::logging( + $logging_context_format_string = undef, + $logging_default_format_string = undef, + $logging_debug_format_suffix = undef, + $logging_exception_prefix = undef, + $log_config_append = undef, + $default_log_levels = undef, + $publish_errors = undef, + $fatal_deprecations = undef, + $instance_format = undef, + $instance_uuid_format = undef, + $log_date_format = undef, +) { + + if $logging_context_format_string { + heat_config { + 'DEFAULT/logging_context_format_string' : + value => $logging_context_format_string; + } + } + else { + heat_config { + 'DEFAULT/logging_context_format_string' : ensure => absent; + } + } + + if $logging_default_format_string { + heat_config { + 'DEFAULT/logging_default_format_string' : + value => $logging_default_format_string; + } + } + else { + heat_config { + 'DEFAULT/logging_default_format_string' : ensure => absent; + } + } + + if $logging_debug_format_suffix { + heat_config { + 'DEFAULT/logging_debug_format_suffix' : + value => $logging_debug_format_suffix; + } + } + else { + heat_config { + 'DEFAULT/logging_debug_format_suffix' : ensure => absent; + } + } + + if $logging_exception_prefix { + heat_config { + 'DEFAULT/logging_exception_prefix' : value => $logging_exception_prefix; + } + } + else { + heat_config { + 'DEFAULT/logging_exception_prefix' : ensure => absent; + } + } + + if $log_config_append { + heat_config { + 'DEFAULT/log_config_append' : value => $log_config_append; + } + } + else { + heat_config { + 'DEFAULT/log_config_append' : ensure => absent; + } + } + + if $default_log_levels { + heat_config { + 'DEFAULT/default_log_levels' : + value => join(sort(join_keys_to_values($default_log_levels, '=')), ','); + } + } + else { + heat_config { + 'DEFAULT/default_log_levels' : ensure => absent; + } + } + + if $publish_errors { + heat_config { + 'DEFAULT/publish_errors' : value => $publish_errors; + } + } + else { + heat_config { + 'DEFAULT/publish_errors' : ensure => absent; + } + } + + if $fatal_deprecations { + heat_config { + 'DEFAULT/fatal_deprecations' : value => $fatal_deprecations; + } + } + else { + heat_config { + 'DEFAULT/fatal_deprecations' : ensure => absent; + } + } + + if $instance_format { + heat_config { + 'DEFAULT/instance_format' : value => $instance_format; + } + } + else { + heat_config { + 'DEFAULT/instance_format' : ensure => absent; + } + } + + if $instance_uuid_format { + heat_config { + 'DEFAULT/instance_uuid_format' : value => $instance_uuid_format; + } + } + else { + heat_config { + 'DEFAULT/instance_uuid_format' : ensure => absent; + } + } + + if $log_date_format { + heat_config { + 'DEFAULT/log_date_format' : value => $log_date_format; + } + } + else { + heat_config { + 'DEFAULT/log_date_format' : ensure => absent; + } + } + + +} diff --git a/spec/classes/heat_logging_spec.rb b/spec/classes/heat_logging_spec.rb new file mode 100644 index 00000000..c025d5eb --- /dev/null +++ b/spec/classes/heat_logging_spec.rb @@ -0,0 +1,107 @@ +require 'spec_helper' + +describe 'heat::logging' do + + let :params do + { + } + end + + let :log_params do + { + :logging_context_format_string => '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s', + :logging_default_format_string => '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s', + :logging_debug_format_suffix => '%(funcName)s %(pathname)s:%(lineno)d', + :logging_exception_prefix => '%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s', + :log_config_append => '/etc/heat/logging.conf', + :publish_errors => true, + :default_log_levels => { + 'amqp' => 'WARN', 'amqplib' => 'WARN', 'boto' => 'WARN', + 'qpid' => 'WARN', 'sqlalchemy' => 'WARN', 'suds' => 'INFO', + 'iso8601' => 'WARN', + 'requests.packages.urllib3.connectionpool' => 'WARN' }, + :fatal_deprecations => true, + :instance_format => '[instance: %(uuid)s] ', + :instance_uuid_format => '[instance: %(uuid)s] ', + :log_date_format => '%Y-%m-%d %H:%M:%S', + } + end + + shared_examples_for 'heat-logging' do + + context 'with extended logging options' do + before { params.merge!( log_params ) } + it_configures 'logging params set' + end + + context 'without extended logging options' do + it_configures 'logging params unset' + end + + end + + shared_examples_for 'logging params set' do + it 'enables logging params' do + should contain_heat_config('DEFAULT/logging_context_format_string').with_value( + '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s') + + should contain_heat_config('DEFAULT/logging_default_format_string').with_value( + '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s') + + should contain_heat_config('DEFAULT/logging_debug_format_suffix').with_value( + '%(funcName)s %(pathname)s:%(lineno)d') + + should contain_heat_config('DEFAULT/logging_exception_prefix').with_value( + '%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s') + + should contain_heat_config('DEFAULT/log_config_append').with_value( + '/etc/heat/logging.conf') + should contain_heat_config('DEFAULT/publish_errors').with_value( + true) + + should contain_heat_config('DEFAULT/default_log_levels').with_value( + 'amqp=WARN,amqplib=WARN,boto=WARN,iso8601=WARN,qpid=WARN,requests.packages.urllib3.connectionpool=WARN,sqlalchemy=WARN,suds=INFO') + + should contain_heat_config('DEFAULT/fatal_deprecations').with_value( + true) + + should contain_heat_config('DEFAULT/instance_format').with_value( + '[instance: %(uuid)s] ') + + should contain_heat_config('DEFAULT/instance_uuid_format').with_value( + '[instance: %(uuid)s] ') + + should contain_heat_config('DEFAULT/log_date_format').with_value( + '%Y-%m-%d %H:%M:%S') + end + end + + + shared_examples_for 'logging params unset' do + [ :logging_context_format_string, :logging_default_format_string, + :logging_debug_format_suffix, :logging_exception_prefix, + :log_config_append, :publish_errors, + :default_log_levels, :fatal_deprecations, + :instance_format, :instance_uuid_format, + :log_date_format, ].each { |param| + it { should contain_heat_config("DEFAULT/#{param}").with_ensure('absent') } + } + end + + context 'on Debian platforms' do + let :facts do + { :osfamily => 'Debian' } + end + + it_configures 'heat-logging' + end + + context 'on RedHat platforms' do + let :facts do + { :osfamily => 'RedHat' } + end + + it_configures 'heat-logging' + end + +end