diff --git a/manifests/init.pp b/manifests/init.pp index 465cea9d..2d191889 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -18,11 +18,28 @@ # # [*debug*] # (optional) should the daemons log debug messages. -# Defaults to 'false' +# Defaults to undef # # [*verbose*] # (optional) should the daemons log verbose messages. -# Defaults to 'false' +# Defaults to undef +# +# [*use_syslog*] +# (Optional) Use syslog for logging. +# Defaults to undef +# +# [*use_stderr*] +# (optional) Use stderr for logging +# Defaults to undef +# +# [*log_facility*] +# (Optional) Syslog facility to receive log lines. +# Defaults to undef +# +# [*log_dir*] +# (optional) Directory where logs should be stored. +# If set to boolean false, it will not log to any directory. +# Defaults to undef # # [*root_helper*] # (optional) Command for designate rootwrap helper. @@ -65,8 +82,12 @@ class designate( $package_ensure = present, $common_package_name = undef, - $verbose = false, - $debug = false, + $verbose = undef, + $debug = undef, + $log_dir = undef, + $use_syslog = undef, + $use_stderr = undef, + $log_facility = undef, $root_helper = 'sudo designate-rootwrap /etc/designate/rootwrap.conf', $rabbit_host = '127.0.0.1', $rabbit_port = '5672', @@ -78,6 +99,7 @@ class designate( $notification_topics = 'notifications', ) { + include ::designate::logging include ::designate::params exec { 'post-designate_config': @@ -139,10 +161,7 @@ class designate( # default setting designate_config { - 'DEFAULT/debug' : value => $debug; - 'DEFAULT/verbose' : value => $verbose; 'DEFAULT/root_helper' : value => $root_helper; - 'DEFAULT/logdir' : value => $::designate::params::log_dir; 'DEFAULT/state_path' : value => $::designate::params::state_path; 'DEFAULT/notification_driver' : value => $notification_driver; 'DEFAULT/notification_topics' : value => $notification_topics; diff --git a/manifests/logging.pp b/manifests/logging.pp new file mode 100644 index 00000000..933ff0a0 --- /dev/null +++ b/manifests/logging.pp @@ -0,0 +1,257 @@ +# Class designate::logging +# +# designate logging configuration +# +# == parameters +# +# [*verbose*] +# (Optional) Should the daemons log verbose messages +# Defaults to 'false' +# +# [*debug*] +# (Optional) Should the daemons log debug messages +# Defaults to 'false' +# +# [*use_syslog*] +# (Optional) Use syslog for logging. +# Defaults to 'false' +# +# [*use_stderr*] +# (optional) Use stderr for logging +# Defaults to 'true' +# +# [*log_facility*] +# (Optional) Syslog facility to receive log lines. +# Defaults to 'LOG_USER' +# +# [*log_dir*] +# (optional) Directory where logs should be stored. +# If set to boolean false, it will not log to any directory. +# Defaults to $::designate::params::log_dir +# +# [*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 designate::logging( + $use_syslog = false, + $use_stderr = true, + $log_facility = 'LOG_USER', + $log_dir = $::designate::params::log_dir, + $verbose = false, + $debug = false, + $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, +) inherits ::designate::params { + + # NOTE(spredzy): In order to keep backward compatibility we rely on the pick function + # to use designate:: first then designate::logging::. + $use_syslog_real = pick($::designate::use_syslog,$use_syslog) + $use_stderr_real = pick($::designate::use_stderr,$use_stderr) + $log_facility_real = pick($::designate::log_facility,$log_facility) + $log_dir_real = pick($::designate::log_dir, $log_dir) + $verbose_real = pick($::designate::verbose,$verbose) + $debug_real = pick($::designate::debug,$debug) + + designate_config { + 'DEFAULT/debug' : value => $debug_real; + 'DEFAULT/verbose' : value => $verbose_real; + 'DEFAULT/use_stderr' : value => $use_stderr_real; + 'DEFAULT/use_syslog' : value => $use_syslog_real; + 'DEFAULT/log_dir' : value => $log_dir_real; + 'DEFAULT/syslog_log_facility': value => $log_facility_real; + } + + if $logging_context_format_string { + designate_config { + 'DEFAULT/logging_context_format_string' : + value => $logging_context_format_string; + } + } + else { + designate_config { + 'DEFAULT/logging_context_format_string' : ensure => absent; + } + } + + if $logging_default_format_string { + designate_config { + 'DEFAULT/logging_default_format_string' : + value => $logging_default_format_string; + } + } + else { + designate_config { + 'DEFAULT/logging_default_format_string' : ensure => absent; + } + } + + if $logging_debug_format_suffix { + designate_config { + 'DEFAULT/logging_debug_format_suffix' : + value => $logging_debug_format_suffix; + } + } + else { + designate_config { + 'DEFAULT/logging_debug_format_suffix' : ensure => absent; + } + } + + if $logging_exception_prefix { + designate_config { + 'DEFAULT/logging_exception_prefix' : value => $logging_exception_prefix; + } + } + else { + designate_config { + 'DEFAULT/logging_exception_prefix' : ensure => absent; + } + } + + if $log_config_append { + designate_config { + 'DEFAULT/log_config_append' : value => $log_config_append; + } + } + else { + designate_config { + 'DEFAULT/log_config_append' : ensure => absent; + } + } + + if $default_log_levels { + designate_config { + 'DEFAULT/default_log_levels' : + value => join(sort(join_keys_to_values($default_log_levels, '=')), ','); + } + } + else { + designate_config { + 'DEFAULT/default_log_levels' : ensure => absent; + } + } + + if $publish_errors { + designate_config { + 'DEFAULT/publish_errors' : value => $publish_errors; + } + } + else { + designate_config { + 'DEFAULT/publish_errors' : ensure => absent; + } + } + + if $fatal_deprecations { + designate_config { + 'DEFAULT/fatal_deprecations' : value => $fatal_deprecations; + } + } + else { + designate_config { + 'DEFAULT/fatal_deprecations' : ensure => absent; + } + } + + if $instance_format { + designate_config { + 'DEFAULT/instance_format' : value => $instance_format; + } + } + else { + designate_config { + 'DEFAULT/instance_format' : ensure => absent; + } + } + + if $instance_uuid_format { + designate_config { + 'DEFAULT/instance_uuid_format' : value => $instance_uuid_format; + } + } + else { + designate_config { + 'DEFAULT/instance_uuid_format' : ensure => absent; + } + } + + if $log_date_format { + designate_config { + 'DEFAULT/log_date_format' : value => $log_date_format; + } + } + else { + designate_config { + 'DEFAULT/log_date_format' : ensure => absent; + } + } + + +} diff --git a/spec/classes/designate_init_spec.rb b/spec/classes/designate_init_spec.rb index adc19dce..8a577e88 100644 --- a/spec/classes/designate_init_spec.rb +++ b/spec/classes/designate_init_spec.rb @@ -45,6 +45,7 @@ describe 'designate' do shared_examples_for 'a designate base installation' do + it { is_expected.to contain_class('designate::logging') } it { is_expected.to contain_class('designate::params') } it 'configures designate group' do @@ -84,8 +85,6 @@ describe 'designate' do end it 'configures debug and verbosity' do - is_expected.to contain_designate_config('DEFAULT/debug').with_value( params[:debug] ) - is_expected.to contain_designate_config('DEFAULT/verbose').with_value( params[:verbose] ) is_expected.to contain_designate_config('DEFAULT/root_helper').with_value( params[:root_helper] ) end diff --git a/spec/classes/designate_logging_spec.rb b/spec/classes/designate_logging_spec.rb new file mode 100644 index 00000000..b918649b --- /dev/null +++ b/spec/classes/designate_logging_spec.rb @@ -0,0 +1,142 @@ +require 'spec_helper' + +describe 'designate::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/designate/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', + :use_syslog => true, + :use_stderr => false, + :log_facility => 'LOG_FOO', + :log_dir => '/var/log', + :verbose => true, + :debug => true, + } + end + + shared_examples_for 'designate-logging' do + + context 'with basic logging options and default settings' do + it_configures 'basic default logging settings' + end + + context 'with basic logging options and non-default settings' do + before { params.merge!( log_params ) } + it_configures 'basic non-default logging settings' + end + + 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 'basic default logging settings' do + it 'configures designate logging settins with default values' do + is_expected.to contain_designate_config('DEFAULT/use_syslog').with(:value => 'false') + is_expected.to contain_designate_config('DEFAULT/use_stderr').with(:value => 'true') + is_expected.to contain_designate_config('DEFAULT/verbose').with(:value => 'false') + is_expected.to contain_designate_config('DEFAULT/debug').with(:value => 'false') + end + end + + shared_examples 'basic non-default logging settings' do + it 'configures designate logging settins with non-default values' do + is_expected.to contain_designate_config('DEFAULT/use_syslog').with(:value => 'true') + is_expected.to contain_designate_config('DEFAULT/use_stderr').with(:value => 'false') + is_expected.to contain_designate_config('DEFAULT/syslog_log_facility').with(:value => 'LOG_FOO') + is_expected.to contain_designate_config('DEFAULT/log_dir').with(:value => '/var/log') + is_expected.to contain_designate_config('DEFAULT/verbose').with(:value => 'true') + is_expected.to contain_designate_config('DEFAULT/debug').with(:value => 'true') + end + end + + shared_examples_for 'logging params set' do + it 'enables logging params' do + is_expected.to contain_designate_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') + + is_expected.to contain_designate_config('DEFAULT/logging_default_format_string').with_value( + '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s') + + is_expected.to contain_designate_config('DEFAULT/logging_debug_format_suffix').with_value( + '%(funcName)s %(pathname)s:%(lineno)d') + + is_expected.to contain_designate_config('DEFAULT/logging_exception_prefix').with_value( + '%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s') + + is_expected.to contain_designate_config('DEFAULT/log_config_append').with_value( + '/etc/designate/logging.conf') + is_expected.to contain_designate_config('DEFAULT/publish_errors').with_value( + true) + + is_expected.to contain_designate_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') + + is_expected.to contain_designate_config('DEFAULT/fatal_deprecations').with_value( + true) + + is_expected.to contain_designate_config('DEFAULT/instance_format').with_value( + '[instance: %(uuid)s] ') + + is_expected.to contain_designate_config('DEFAULT/instance_uuid_format').with_value( + '[instance: %(uuid)s] ') + + is_expected.to contain_designate_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 { is_expected.to contain_designate_config("DEFAULT/#{param}").with_ensure('absent') } + } + end + + context 'on Debian platforms' do + let :facts do + { :osfamily => 'Debian' } + end + + it_configures 'designate-logging' + end + + context 'on RedHat platforms' do + let :facts do + { :osfamily => 'RedHat' } + end + + it_configures 'designate-logging' + end + +end