diff --git a/manifests/api.pp b/manifests/api.pp index cfad3a9..619168b 100644 --- a/manifests/api.pp +++ b/manifests/api.pp @@ -34,11 +34,11 @@ # # [*verbose*] # (optional) Rather to log the tuskar api service at verbose level. -# Default: false +# Default: undef # # [*debug*] # (optional) Rather to log the tuskar api service at debug level. -# Default: false +# Default: undef # # [*bind_host*] # (optional) The address of the host to bind to. @@ -51,12 +51,12 @@ # [*log_file*] # (optional) The path of file used for logging # If set to boolean false, it will not log to any file. -# Default: /var/log/tuskar/tuskar-api.log +# Default: undef # -# [*log_dir*] -# (optional) directory to which tuskar logs are sent. -# If set to boolean false, it will not log to any directory. -# Defaults to '/var/log/tuskar' +# [*log_dir*] +# (optional) directory to which tuskar logs are sent. +# If set to boolean false, it will not log to any directory. +# Defaults to undef # # [*keystone_tenant*] # (optional) Tenant to authenticate to. @@ -72,11 +72,15 @@ # # [*use_syslog*] # (optional) Use syslog for logging. -# Defaults to false. +# Defaults to undef. +# +# [*use_stderr*] +# (optional) Use stderr for logging +# Defaults to undef # # [*log_facility*] # (optional) Syslog facility to receive log lines. -# Defaults to 'LOG_USER'. +# Defaults to undef. # # [*purge_config*] # (optional) Whether to set only the specified config options @@ -89,24 +93,26 @@ # class tuskar::api( $keystone_password, - $verbose = false, - $debug = false, + $verbose = undef, + $debug = undef, + $use_syslog = undef, + $log_facility = undef, + $log_dir = undef, + $use_stderr = undef, + $log_file = undef, $bind_host = '0.0.0.0', $bind_port = '8585', - $log_file = '/var/log/tuskar/tuskar-api.log', - $log_dir = '/var/log/tuskar', $keystone_tenant = 'services', $keystone_user = 'tuskar', $identity_uri = 'http://127.0.0.1:35357', $enabled = true, - $use_syslog = false, - $log_facility = 'LOG_USER', $purge_config = false, $manage_service = true, $package_ensure = 'present', ) inherits tuskar { require ::keystone::python + include ::tuskar::logging include ::tuskar::params Tuskar_config<||> ~> Exec['post-tuskar_config'] @@ -131,8 +137,6 @@ class tuskar::api( # basic service config tuskar_config { - 'DEFAULT/verbose': value => $verbose; - 'DEFAULT/debug': value => $debug; 'DEFAULT/tuskar_api_bind_ip': value => $bind_host; 'DEFAULT/tuskar_api_port': value => $bind_port; 'keystone_authtoken/identity_uri': value => $identity_uri; @@ -141,39 +145,6 @@ class tuskar::api( 'keystone_authtoken/admin_tenant_name': value => $keystone_tenant; } - # Logging - if $log_file { - tuskar_config { - 'DEFAULT/log_file': value => $log_file; - } - } else { - tuskar_config { - 'DEFAULT/log_file': ensure => absent; - } - } - - if $log_dir { - tuskar_config { - 'DEFAULT/log_dir': value => $log_dir; - } - } else { - tuskar_config { - 'DEFAULT/log_dir': ensure => absent; - } - } - - # Syslog - if $use_syslog { - tuskar_config { - 'DEFAULT/use_syslog' : value => true; - 'DEFAULT/syslog_log_facility' : value => $log_facility; - } - } else { - tuskar_config { - 'DEFAULT/use_syslog': value => false; - } - } - resources { 'tuskar_config': purge => $purge_config, } diff --git a/manifests/logging.pp b/manifests/logging.pp new file mode 100644 index 0000000..0d7e454 --- /dev/null +++ b/manifests/logging.pp @@ -0,0 +1,265 @@ +# Class tuskar::logging +# +# tuskar 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 '/var/log/tuskar' +# +# [*log_file*] +# (optional) The path of file used for logging +# If set to boolean false, it will not log to any file. +# Default to '/var/log/tuskar/tuskar-api.log' +# +# [*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 tuskar::logging( + $use_syslog = false, + $use_stderr = true, + $log_facility = 'LOG_USER', + $log_dir = '/var/log/tuskar', + $log_file = '/var/log/tuskar/tuskar-api.log', + $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, +) { + + # NOTE(spredzy): In order to keep backward compatibility we rely on the pick function + # to use tuskar:: first then tuskar::logging::. + $use_syslog_real = pick($::tuskar::api::use_syslog,$use_syslog) + $use_stderr_real = pick($::tuskar::api::use_stderr,$use_stderr) + $log_facility_real = pick($::tuskar::api::log_facility,$log_facility) + $log_dir_real = pick($::tuskar::api::log_dir,$log_dir) + $log_file_real = pick($::tuskar::api::log_file,$log_file) + $verbose_real = pick($::tuskar::api::verbose,$verbose) + $debug_real = pick($::tuskar::api::debug,$debug) + + tuskar_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/log_file' : value => $log_file_real; + 'DEFAULT/syslog_log_facility': value => $log_facility_real; + } + + if $logging_context_format_string { + tuskar_config { + 'DEFAULT/logging_context_format_string' : + value => $logging_context_format_string; + } + } + else { + tuskar_config { + 'DEFAULT/logging_context_format_string' : ensure => absent; + } + } + + if $logging_default_format_string { + tuskar_config { + 'DEFAULT/logging_default_format_string' : + value => $logging_default_format_string; + } + } + else { + tuskar_config { + 'DEFAULT/logging_default_format_string' : ensure => absent; + } + } + + if $logging_debug_format_suffix { + tuskar_config { + 'DEFAULT/logging_debug_format_suffix' : + value => $logging_debug_format_suffix; + } + } + else { + tuskar_config { + 'DEFAULT/logging_debug_format_suffix' : ensure => absent; + } + } + + if $logging_exception_prefix { + tuskar_config { + 'DEFAULT/logging_exception_prefix' : value => $logging_exception_prefix; + } + } + else { + tuskar_config { + 'DEFAULT/logging_exception_prefix' : ensure => absent; + } + } + + if $log_config_append { + tuskar_config { + 'DEFAULT/log_config_append' : value => $log_config_append; + } + } + else { + tuskar_config { + 'DEFAULT/log_config_append' : ensure => absent; + } + } + + if $default_log_levels { + tuskar_config { + 'DEFAULT/default_log_levels' : + value => join(sort(join_keys_to_values($default_log_levels, '=')), ','); + } + } + else { + tuskar_config { + 'DEFAULT/default_log_levels' : ensure => absent; + } + } + + if $publish_errors { + tuskar_config { + 'DEFAULT/publish_errors' : value => $publish_errors; + } + } + else { + tuskar_config { + 'DEFAULT/publish_errors' : ensure => absent; + } + } + + if $fatal_deprecations { + tuskar_config { + 'DEFAULT/fatal_deprecations' : value => $fatal_deprecations; + } + } + else { + tuskar_config { + 'DEFAULT/fatal_deprecations' : ensure => absent; + } + } + + if $instance_format { + tuskar_config { + 'DEFAULT/instance_format' : value => $instance_format; + } + } + else { + tuskar_config { + 'DEFAULT/instance_format' : ensure => absent; + } + } + + if $instance_uuid_format { + tuskar_config { + 'DEFAULT/instance_uuid_format' : value => $instance_uuid_format; + } + } + else { + tuskar_config { + 'DEFAULT/instance_uuid_format' : ensure => absent; + } + } + + if $log_date_format { + tuskar_config { + 'DEFAULT/log_date_format' : value => $log_date_format; + } + } + else { + tuskar_config { + 'DEFAULT/log_date_format' : ensure => absent; + } + } + + +} diff --git a/spec/classes/tuskar_api_spec.rb b/spec/classes/tuskar_api_spec.rb index b6c4f34..ca45d6b 100644 --- a/spec/classes/tuskar_api_spec.rb +++ b/spec/classes/tuskar_api_spec.rb @@ -17,6 +17,10 @@ describe 'tuskar::api' do context 'with default parameters' do + it 'contains the logging class' do + is_expected.to contain_class('tuskar::logging') + end + it 'installs tuskar-api package and service' do is_expected.to contain_service('tuskar-api').with( :name => platform_params[:api_service_name], diff --git a/spec/classes/tuskar_logging_spec.rb b/spec/classes/tuskar_logging_spec.rb new file mode 100644 index 0000000..e1dedab --- /dev/null +++ b/spec/classes/tuskar_logging_spec.rb @@ -0,0 +1,146 @@ +require 'spec_helper' + +describe 'tuskar::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/tuskar/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', + :log_file => '/var/log/foo/bar.log', + :verbose => true, + :debug => true, + } + end + + shared_examples_for 'tuskar-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 tuskar logging settins with default values' do + is_expected.to contain_tuskar_config('DEFAULT/use_syslog').with(:value => 'false') + is_expected.to contain_tuskar_config('DEFAULT/use_stderr').with(:value => 'true') + is_expected.to contain_tuskar_config('DEFAULT/log_dir').with(:value => '/var/log/tuskar') + is_expected.to contain_tuskar_config('DEFAULT/log_file').with(:value => '/var/log/tuskar/tuskar-api.log') + is_expected.to contain_tuskar_config('DEFAULT/verbose').with(:value => 'false') + is_expected.to contain_tuskar_config('DEFAULT/debug').with(:value => 'false') + end + end + + shared_examples 'basic non-default logging settings' do + it 'configures tuskar logging settins with non-default values' do + is_expected.to contain_tuskar_config('DEFAULT/use_syslog').with(:value => 'true') + is_expected.to contain_tuskar_config('DEFAULT/use_stderr').with(:value => 'false') + is_expected.to contain_tuskar_config('DEFAULT/syslog_log_facility').with(:value => 'LOG_FOO') + is_expected.to contain_tuskar_config('DEFAULT/log_dir').with(:value => '/var/log') + is_expected.to contain_tuskar_config('DEFAULT/log_file').with(:value => '/var/log/foo/bar.log') + is_expected.to contain_tuskar_config('DEFAULT/verbose').with(:value => 'true') + is_expected.to contain_tuskar_config('DEFAULT/debug').with(:value => 'true') + end + end + + shared_examples_for 'logging params set' do + it 'enables logging params' do + is_expected.to contain_tuskar_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_tuskar_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_tuskar_config('DEFAULT/logging_debug_format_suffix').with_value( + '%(funcName)s %(pathname)s:%(lineno)d') + + is_expected.to contain_tuskar_config('DEFAULT/logging_exception_prefix').with_value( + '%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s') + + is_expected.to contain_tuskar_config('DEFAULT/log_config_append').with_value( + '/etc/tuskar/logging.conf') + is_expected.to contain_tuskar_config('DEFAULT/publish_errors').with_value( + true) + + is_expected.to contain_tuskar_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_tuskar_config('DEFAULT/fatal_deprecations').with_value( + true) + + is_expected.to contain_tuskar_config('DEFAULT/instance_format').with_value( + '[instance: %(uuid)s] ') + + is_expected.to contain_tuskar_config('DEFAULT/instance_uuid_format').with_value( + '[instance: %(uuid)s] ') + + is_expected.to contain_tuskar_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_tuskar_config("DEFAULT/#{param}").with_ensure('absent') } + } + end + + context 'on Debian platforms' do + let :facts do + { :osfamily => 'Debian' } + end + + it_configures 'tuskar-logging' + end + + context 'on RedHat platforms' do + let :facts do + { :osfamily => 'RedHat' } + end + + it_configures 'tuskar-logging' + end + +end