git-upstream/git_upstream/log.py

116 lines
3.1 KiB
Python

#
# Copyright (c) 2012, 2013, 2014 Hewlett-Packard Development Company, L.P.
#
# 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.
#
"""
Custom logging for git-upstream tool
Adds new 'NOTICE' level to standard logging library and provides helper
functions for verbose/quiet CLI args to retreive the appropriate level
for logging output to the console.
"""
import logging
import textwrap
# Add new NOTICE logging level
NOTICE = (logging.INFO + logging.WARN) // 2
logging.NOTICE = NOTICE
logging.addLevelName(NOTICE, "NOTICE")
def get_logger(name=None):
"""
Wrapper for standard logging.getLogger that ensures all loggers in this
application will have their name prefixed with 'git-upstream'.
"""
name = ".".join([x for x in ("git-upstream", name) if x])
logger = logging.getLogger(name)
return logger
# sorted in order of verbosity "['level', 'alias']"
_levels = [
['critical', 'fatal'],
['error'],
['warning', 'warn'],
['notice'],
['info'],
['debug']
]
def get_increment_level(count, default='warning'):
"""
Given a default level to start from, and a count to increment the logging
level by, return the associated level that is 'count' levels more verbose.
"""
idx = next((idx for idx, sublist in enumerate(_levels) if
default in sublist), None)
return _levels[min(idx + count, len(_levels) - 1)][0].upper()
class LevelFilterIgnoreAbove(logging.Filter):
def __init__(self, level):
self.level = level
def filter(self, record):
return record.levelno < self.level
class LevelFilterIgnoreBelow(logging.Filter):
def __init__(self, level):
self.level = level
def filter(self, record):
return record.levelno >= self.level
class DedentLogger(logging.Logger):
def _log(self, level, msg, args, **kwargs):
dedent = kwargs.pop('dedent', True)
if dedent:
msg = textwrap.dedent(msg.lstrip('\n'))
super(DedentLogger, self)._log(level, msg, args, **kwargs)
def notice(self, msg, *args, **kwargs):
"""
Supports same arguments as default methods available from
logging.Logger class
"""
if self.isEnabledFor(NOTICE):
self._log(NOTICE, msg, args, **kwargs)
# override default logger class for everything that imports this module
logging.setLoggerClass(DedentLogger)
class LogDedentMixin(object):
def __init__(self, *args, **kwargs):
self._log = get_logger('%s.%s' % (__name__, self.__class__.__name__))
super(LogDedentMixin, self).__init__(*args, **kwargs)
@property
def log(self):
return self._log