141 lines
4.5 KiB
Python
141 lines
4.5 KiB
Python
# 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.
|
|
#
|
|
"""Logging Module.
|
|
|
|
This module handles logging to the standard python logging subsystem and to the
|
|
console.
|
|
"""
|
|
|
|
from __future__ import absolute_import
|
|
|
|
import logging
|
|
import os
|
|
import sys
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
class DebugFormatter(logging.Formatter):
|
|
|
|
"""Log formatter.
|
|
|
|
Outputs any 'data' values passed in the 'extra' parameter if provided.
|
|
|
|
**Example**:
|
|
|
|
.. code-block:: python
|
|
|
|
LOG.debug("My message", extra={'data': locals()})
|
|
"""
|
|
|
|
def format(self, record):
|
|
"""Print out any 'extra' data provided in logs."""
|
|
if hasattr(record, 'data'):
|
|
return "%s. DEBUG DATA=%s" % (logging.Formatter.format(self,
|
|
record), record.__dict__['data'])
|
|
return logging.Formatter.format(self, record)
|
|
|
|
|
|
def init_logging(config, default_config=None):
|
|
"""Configure logging based on log config file.
|
|
|
|
Turn on console logging if no logging files found
|
|
|
|
:param config: object with configuration namespace (ex. argparse parser)
|
|
:keyword default_config: path to a python logging configuration file
|
|
"""
|
|
if config.get('logconfig') and os.path.isfile(config.get('logconfig')):
|
|
logging.config.fileConfig(config['logconfig'],
|
|
disable_existing_loggers=False)
|
|
elif default_config and os.path.isfile(default_config):
|
|
logging.config.fileConfig(default_config,
|
|
disable_existing_loggers=False)
|
|
else:
|
|
init_console_logging(config)
|
|
|
|
|
|
def find_console_handler(logger):
|
|
"""Return a stream handler, if it exists."""
|
|
for handler in logger.handlers:
|
|
if (isinstance(handler, logging.StreamHandler) and
|
|
handler.stream == sys.stderr):
|
|
return handler
|
|
|
|
|
|
def log_level(config):
|
|
"""Get debug settings from configuration.
|
|
|
|
--debug: turn on additional debug code/inspection (implies
|
|
logging.DEBUG)
|
|
--verbose: turn up logging output (logging.DEBUG)
|
|
--quiet: turn down logging output (logging.WARNING)
|
|
default is logging.INFO
|
|
|
|
:param config: object with configuration namespace (ex. argparse parser)
|
|
"""
|
|
if config.get('debug') is True:
|
|
return logging.DEBUG
|
|
elif config.get('verbose') is True:
|
|
return logging.DEBUG
|
|
elif config.get('quiet') is True:
|
|
return logging.WARNING
|
|
else:
|
|
return logging.INFO
|
|
|
|
|
|
def get_debug_formatter(config):
|
|
"""Get debug formatter based on configuration.
|
|
|
|
:param config: configuration namespace (ex. argparser)
|
|
|
|
--debug: log line numbers and file data also
|
|
--verbose: standard debug
|
|
--quiet: turn down logging output (logging.WARNING)
|
|
default is logging.INFO
|
|
|
|
:param config: object with configuration namespace (ex. argparse parser)
|
|
"""
|
|
if config.get('debug') is True:
|
|
return DebugFormatter('%(pathname)s:%(lineno)d: %(levelname)-8s '
|
|
'%(message)s')
|
|
elif config.get('verbose') is True:
|
|
return logging.Formatter(
|
|
'%(name)-30s: %(levelname)-8s %(message)s')
|
|
elif config.get('quiet') is True:
|
|
return logging.Formatter('%(message)s')
|
|
else:
|
|
return logging.Formatter('%(message)s')
|
|
|
|
|
|
def init_console_logging(config):
|
|
"""Enable logging to the console.
|
|
|
|
:param config: object with configuration namespace (ex. argparse parser)
|
|
"""
|
|
# define a Handler which writes messages to the sys.stderr
|
|
console = find_console_handler(logging.getLogger())
|
|
if not console:
|
|
console = logging.StreamHandler()
|
|
logging_level = log_level(config)
|
|
console.setLevel(logging_level)
|
|
|
|
# set a format which is simpler for console use
|
|
formatter = get_debug_formatter(config)
|
|
# tell the handler to use this format
|
|
console.setFormatter(formatter)
|
|
# add the handler to the root logger
|
|
logging.getLogger().addHandler(console)
|
|
logging.getLogger().setLevel(logging_level)
|
|
global LOG # pylint: disable=W0603
|
|
LOG = logging.getLogger(__name__) # reset
|