diff options
Diffstat (limited to 'openstackclient/common')
| -rw-r--r-- | openstackclient/common/context.py | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/openstackclient/common/context.py b/openstackclient/common/context.py new file mode 100644 index 00000000..b7b16e94 --- /dev/null +++ b/openstackclient/common/context.py @@ -0,0 +1,149 @@ +# 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 + +_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' + + +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) |
