2015-05-29 20:39:24 +09:00
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
|
|
# not use this file except in compliance with the License. You may obtain
|
|
|
|
# a copy of the License at
|
|
|
|
#
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
#
|
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
|
|
# License for the specific language governing permissions and limitations
|
|
|
|
# under the License.
|
|
|
|
#
|
|
|
|
|
|
|
|
"""Context and Formatter"""
|
|
|
|
|
|
|
|
import logging
|
2015-08-09 06:26:56 -06:00
|
|
|
import warnings
|
2015-05-29 20:39:24 +09:00
|
|
|
|
|
|
|
_LOG_MESSAGE_FORMAT = ('%(asctime)s.%(msecs)03d %(process)d '
|
|
|
|
'%(levelname)s %(name)s [%(clouds_name)s '
|
|
|
|
'%(username)s %(project_name)s] %(message)s')
|
|
|
|
_LOG_DATE_FORMAT = '%Y-%m-%d %H:%M:%S'
|
|
|
|
|
|
|
|
|
2015-08-09 06:26:56 -06:00
|
|
|
def set_warning_filter(log_level):
|
|
|
|
if log_level == logging.ERROR:
|
|
|
|
warnings.simplefilter("ignore")
|
|
|
|
elif log_level == logging.WARNING:
|
|
|
|
warnings.simplefilter("ignore")
|
|
|
|
elif log_level == logging.INFO:
|
|
|
|
warnings.simplefilter("once")
|
|
|
|
|
|
|
|
|
2015-05-29 20:39:24 +09:00
|
|
|
def setup_handler_logging_level(handler_type, level):
|
|
|
|
"""Setup of the handler for set the logging level
|
|
|
|
|
|
|
|
:param handler_type: type of logging handler
|
|
|
|
:param level: logging level
|
|
|
|
:return: None
|
|
|
|
"""
|
|
|
|
# Set the handler logging level of FileHandler(--log-file)
|
|
|
|
# and StreamHandler
|
|
|
|
for h in logging.getLogger('').handlers:
|
|
|
|
if type(h) is handler_type:
|
|
|
|
h.setLevel(level)
|
|
|
|
|
|
|
|
|
|
|
|
def setup_logging(shell, cloud_config):
|
|
|
|
"""Get one cloud configuration from configuration file and setup logging
|
|
|
|
|
|
|
|
:param shell: instance of openstackclient shell
|
|
|
|
:param cloud_config:
|
|
|
|
instance of the cloud specified by --os-cloud
|
|
|
|
in the configuration file
|
|
|
|
:return: None
|
|
|
|
"""
|
|
|
|
|
|
|
|
log_level = logging.WARNING
|
|
|
|
log_file = cloud_config.config.get('log_file', None)
|
|
|
|
if log_file:
|
|
|
|
# setup the logging level
|
|
|
|
get_log_level = cloud_config.config.get('log_level')
|
|
|
|
if get_log_level:
|
|
|
|
log_level = {
|
|
|
|
'error': logging.ERROR,
|
|
|
|
'info': logging.INFO,
|
|
|
|
'debug': logging.DEBUG,
|
|
|
|
}.get(get_log_level, logging.WARNING)
|
|
|
|
|
|
|
|
# setup the logging context
|
|
|
|
log_cont = _LogContext(
|
|
|
|
clouds_name=cloud_config.config.get('cloud'),
|
|
|
|
project_name=cloud_config.auth.get('project_name'),
|
|
|
|
username=cloud_config.auth.get('username'),
|
|
|
|
)
|
|
|
|
# setup the logging handler
|
|
|
|
log_handler = _setup_handler_for_logging(
|
|
|
|
logging.FileHandler,
|
|
|
|
log_level,
|
|
|
|
file_name=log_file,
|
|
|
|
context=log_cont,
|
|
|
|
)
|
|
|
|
if log_level == logging.DEBUG:
|
|
|
|
# DEBUG only.
|
|
|
|
# setup the operation_log
|
|
|
|
shell.enable_operation_logging = True
|
|
|
|
shell.operation_log.setLevel(logging.DEBUG)
|
|
|
|
shell.operation_log.addHandler(log_handler)
|
|
|
|
|
|
|
|
|
|
|
|
def _setup_handler_for_logging(handler_type, level, file_name, context):
|
|
|
|
"""Setup of the handler
|
|
|
|
|
|
|
|
Setup of the handler for addition of the logging handler,
|
|
|
|
changes of the logging format, change of the logging level,
|
|
|
|
|
|
|
|
:param handler_type: type of logging handler
|
|
|
|
:param level: logging level
|
|
|
|
:param file_name: name of log-file
|
|
|
|
:param context: instance of _LogContext()
|
|
|
|
:return: logging handler
|
|
|
|
"""
|
|
|
|
|
|
|
|
root_logger = logging.getLogger('')
|
|
|
|
handler = None
|
|
|
|
# Setup handler for FileHandler(--os-cloud)
|
|
|
|
handler = logging.FileHandler(
|
|
|
|
filename=file_name,
|
|
|
|
)
|
|
|
|
formatter = _LogContextFormatter(
|
|
|
|
context=context,
|
|
|
|
fmt=_LOG_MESSAGE_FORMAT,
|
|
|
|
datefmt=_LOG_DATE_FORMAT,
|
|
|
|
)
|
|
|
|
handler.setFormatter(formatter)
|
|
|
|
handler.setLevel(level)
|
|
|
|
|
|
|
|
# If both `--log-file` and `--os-cloud` are specified,
|
|
|
|
# the log is output to each file.
|
|
|
|
root_logger.addHandler(handler)
|
|
|
|
|
|
|
|
return handler
|
|
|
|
|
|
|
|
|
|
|
|
class _LogContext(object):
|
|
|
|
"""Helper class to represent useful information about a logging context"""
|
|
|
|
|
|
|
|
def __init__(self, clouds_name=None, project_name=None, username=None):
|
|
|
|
"""Initialize _LogContext instance
|
|
|
|
|
|
|
|
:param clouds_name: one of the cloud name in configuration file
|
|
|
|
:param project_name: the project name in cloud(clouds_name)
|
|
|
|
:param username: the user name in cloud(clouds_name)
|
|
|
|
"""
|
|
|
|
|
|
|
|
self.clouds_name = clouds_name
|
|
|
|
self.project_name = project_name
|
|
|
|
self.username = username
|
|
|
|
|
|
|
|
def to_dict(self):
|
|
|
|
return {
|
|
|
|
'clouds_name': self.clouds_name,
|
|
|
|
'project_name': self.project_name,
|
|
|
|
'username': self.username
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class _LogContextFormatter(logging.Formatter):
|
|
|
|
"""Customize the logging format for logging handler"""
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
self.context = kwargs.pop('context', None)
|
|
|
|
logging.Formatter.__init__(self, *args, **kwargs)
|
|
|
|
|
|
|
|
def format(self, record):
|
|
|
|
d = self.context.to_dict()
|
|
|
|
for k, v in d.items():
|
|
|
|
setattr(record, k, v)
|
|
|
|
return logging.Formatter.format(self, record)
|