From 4806091b670e7462287b0b02d7288334716e30f0 Mon Sep 17 00:00:00 2001 From: sanjay Date: Thu, 28 Jan 2016 14:34:31 +0530 Subject: [PATCH 1/7] added support to individual log formats for different log levels --- .gitignore | 65 +++++++++++++++++++++++++ coloredlogs/__init__.py | 34 +++++++++++-- coloredlogs/demo.py | 55 +++++++++++++++++++++ dist/coloredlogs-5.0.1.internal.tar.gz | Bin 0 -> 23578 bytes 4 files changed, 150 insertions(+), 4 deletions(-) create mode 100644 .gitignore create mode 100644 dist/coloredlogs-5.0.1.internal.tar.gz diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6614dd0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,65 @@ +# Created by .ignore support plugin (hsz.mobi) +### Python template +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +#dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +#Pycharm +.idea/* + + diff --git a/coloredlogs/__init__.py b/coloredlogs/__init__.py index be116c4..6b939e0 100644 --- a/coloredlogs/__init__.py +++ b/coloredlogs/__init__.py @@ -124,7 +124,7 @@ """ # Semi-standard module versioning. -__version__ = '5.0' +__version__ = '5.0.1.internal' # Standard library modules. import collections @@ -197,6 +197,8 @@ def install(level=None, **kw): :param fmt: Set the logging format (a string like those accepted by :class:`~logging.Formatter`, defaults to :data:`DEFAULT_LOG_FORMAT`). + :param overridefmt: A dictionary with custom level logging formats + :defaults to data:`DEFAULT_LOG_FORMAT`). :param datefmt: Set the date/time format (a string, defaults to :data:`DEFAULT_DATE_FORMAT`). :param level_styles: A dictionary with custom level styles (defaults to @@ -290,7 +292,8 @@ def install(level=None, **kw): handler.setLevel(level_to_number(level)) # Prepare the arguments to the formatter. The caller is # allowed to customize `fmt' and/or `datefmt' as desired. - formatter_options = dict(fmt=kw.get('fmt'), datefmt=kw.get('datefmt')) + formatter_options = dict(fmt=kw.get('fmt'), datefmt=kw.get('datefmt'), + overridefmt=kw.get('overridefmt')) # Come up with a default log format? if not formatter_options['fmt']: # Use the log format defined by the environment variable @@ -327,7 +330,10 @@ def install(level=None, **kw): if value is not None: formatter_options[name] = value # Create a (possibly colored) formatter. + if not use_colors: + formatter_options.pop('overridefmt') formatter_type = ColoredFormatter if use_colors else logging.Formatter + handler.setFormatter(formatter_type(**formatter_options)) # Install the stream handler. logger.setLevel(logging.NOTSET) @@ -652,8 +658,9 @@ def walk_propagation_tree(logger): class ColoredFormatter(logging.Formatter): """Log :class:`~logging.Formatter` that uses `ANSI escape sequences`_ to create colored logs.""" + formatters = {} - def __init__(self, fmt=None, datefmt=None, level_styles=None, field_styles=None): + def __init__(self, fmt=None, datefmt=None, level_styles=None, field_styles=None, overridefmt=None): """ Initialize a :class:`ColoredFormatter` object. @@ -674,12 +681,28 @@ def __init__(self, fmt=None, datefmt=None, level_styles=None, field_styles=None) # that Sphinx doesn't embed the default values in the generated # documentation (because the result is awkward to read). fmt = fmt or DEFAULT_LOG_FORMAT + datefmt = datefmt or DEFAULT_DATE_FORMAT # Initialize instance attributes. self.level_styles = self.nn.normalize_keys(DEFAULT_LEVEL_STYLES if level_styles is None else level_styles) self.field_styles = self.nn.normalize_keys(DEFAULT_FIELD_STYLES if field_styles is None else field_styles) # Rewrite the format string to inject ANSI escape sequences and # initialize the superclass with the rewritten format string. + if overridefmt is not None and isinstance(overridefmt, dict): + try: + for level in ['INFO', 'WARNING', 'DEBUG', 'CRITICAL', 'ERROR']: + if overridefmt.get(level) is not None: + _fmt = overridefmt[level].get('fmt') + _datefmt = overridefmt[level].get('datefmt') + self.formatters[level] = logging.Formatter( + self.colorize_format(_fmt), + _datefmt) + + except Exception: + self.formatters = {} + logging.Formatter.__init__(self, self.colorize_format(fmt), datefmt) + + logging.Formatter.__init__(self, self.colorize_format(fmt), datefmt) def colorize_format(self, fmt): @@ -746,7 +769,10 @@ def format(self, record): record = copy.copy(record) record.msg = ansi_wrap(coerce_string(record.msg), **style) # Delegate the remaining formatting to the base formatter. - return logging.Formatter.format(self, record) + if self.formatters.get(record.levelname): + return self.formatters.get(record.levelname).format(record) + else: + return logging.Formatter.format(self, record) class HostNameFilter(logging.Filter): diff --git a/coloredlogs/demo.py b/coloredlogs/demo.py index 5042008..a5d17b2 100644 --- a/coloredlogs/demo.py +++ b/coloredlogs/demo.py @@ -45,3 +45,58 @@ class RandomException(Exception): logger.exception(e) time.sleep(DEMO_DELAY) logger.info("Done, exiting ..") + + +def demonstrate_colored_logging_with_different_formatters(): + """A simple demonstration of the `coloredlogs` package.""" + # Initialize colored output to the terminal, default to the + # DEBUG logging level but enable the user the customize it. + FORMATS = { + "INFO": {'fmt': "%(asctime)s - %(levelname)s - " + "%(module)s - %(message)s"}, + "DEBUG": {'fmt': "%(asctime)s - %(levelname)s - " + "%(module)s::%(funcName)s @ %(lineno)d - %(message)s"}, + "WARNING": {'fmt': "%(message)s"} + } + FIELD_STYLES = dict( + asctime=dict(color='green'), + hostname=dict(color='magenta'), + levelname=dict(color='blue', bold=False), + programname=dict(color='cyan'), + name=dict(color='blue'), + module=dict(color='cyan'), + lineno=dict(color='magenta') + ) + + LEVEL_STYLES = { + 'DEBUG': {"color": "blue"}, + 'INFO': {"color": "green"}, + 'WARNING': {"color": "yellow"}, + 'ERROR': {"color": "red"}, + 'CRITICAL': {"color": 'red'} + } + fmt = ( + "%(asctime)s - %(levelname)s - " + "%(module)s - %(message)s" + ) + coloredlogs.install(level=os.environ.get('COLOREDLOGS_LOG_LEVEL', 'DEBUG'), + # fmt=fmt, + field_styles=FIELD_STYLES, + level_styles=LEVEL_STYLES, + overridefmt=FORMATS) + # Print some examples with different timestamps. + for level in ['debug', 'verbose', 'info', 'warn', 'error', 'critical']: + if hasattr(logger, level): + getattr(logger, level)("message with level %r", level) + time.sleep(DEMO_DELAY) + # Show how exceptions are logged. + try: + class RandomException(Exception): + pass + raise RandomException("Something went horribly wrong!") + except Exception as e: + logger.exception(e) + time.sleep(DEMO_DELAY) + logger.info("Done, exiting ..") +# demonstrate_colored_logging() +demonstrate_colored_logging_with_different_formatters() \ No newline at end of file diff --git a/dist/coloredlogs-5.0.1.internal.tar.gz b/dist/coloredlogs-5.0.1.internal.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..c761649f6b4186b9c5f0bb786ad84ceb643be8c8 GIT binary patch literal 23578 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 X*x1znwrrgq!VrgN Date: Thu, 28 Jan 2016 14:53:33 +0530 Subject: [PATCH 2/7] updated error cases --- coloredlogs/__init__.py | 16 ++++++++-------- coloredlogs/demo.py | 5 +++-- dist/coloredlogs-5.0.1.internal.tar.gz | Bin 23578 -> 23795 bytes 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/coloredlogs/__init__.py b/coloredlogs/__init__.py index 6b939e0..bcc9d36 100644 --- a/coloredlogs/__init__.py +++ b/coloredlogs/__init__.py @@ -689,19 +689,19 @@ def __init__(self, fmt=None, datefmt=None, level_styles=None, field_styles=None, # Rewrite the format string to inject ANSI escape sequences and # initialize the superclass with the rewritten format string. if overridefmt is not None and isinstance(overridefmt, dict): - try: - for level in ['INFO', 'WARNING', 'DEBUG', 'CRITICAL', 'ERROR']: + + for level in ['INFO', 'WARNING', 'DEBUG', + 'CRITICAL', 'ERROR', 'VERBOSE']: + try: if overridefmt.get(level) is not None: - _fmt = overridefmt[level].get('fmt') - _datefmt = overridefmt[level].get('datefmt') + _fmt = overridefmt[level].get('fmt', fmt) + _datefmt = overridefmt[level].get('datefmt', datefmt) self.formatters[level] = logging.Formatter( self.colorize_format(_fmt), _datefmt) - except Exception: - self.formatters = {} - logging.Formatter.__init__(self, self.colorize_format(fmt), datefmt) - + except Exception: + self.formatters.pop(level) logging.Formatter.__init__(self, self.colorize_format(fmt), datefmt) diff --git a/coloredlogs/demo.py b/coloredlogs/demo.py index a5d17b2..9114a21 100644 --- a/coloredlogs/demo.py +++ b/coloredlogs/demo.py @@ -55,8 +55,9 @@ def demonstrate_colored_logging_with_different_formatters(): "INFO": {'fmt': "%(asctime)s - %(levelname)s - " "%(module)s - %(message)s"}, "DEBUG": {'fmt': "%(asctime)s - %(levelname)s - " - "%(module)s::%(funcName)s @ %(lineno)d - %(message)s"}, - "WARNING": {'fmt': "%(message)s"} + "%(module)s::%(funcName)s @ %(lineno)d - %(message)s"}, + "WARNING": {'fmt': "%(asctime)s - %(message)s"} + # "WARNING": {} } FIELD_STYLES = dict( asctime=dict(color='green'), diff --git a/dist/coloredlogs-5.0.1.internal.tar.gz b/dist/coloredlogs-5.0.1.internal.tar.gz index c761649f6b4186b9c5f0bb786ad84ceb643be8c8..942cd2c6693516ea85b7fa7f00c4b8d1edf402df 100644 GIT binary patch delta 23607 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 delta 23424 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 From fcb59190e75a17c1b17af3371bfbc4a366a3520f Mon Sep 17 00:00:00 2001 From: sanjay Date: Thu, 28 Jan 2016 15:05:30 +0530 Subject: [PATCH 3/7] updated error cases --- coloredlogs/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/coloredlogs/__init__.py b/coloredlogs/__init__.py index bcc9d36..57c99d5 100644 --- a/coloredlogs/__init__.py +++ b/coloredlogs/__init__.py @@ -331,7 +331,7 @@ def install(level=None, **kw): formatter_options[name] = value # Create a (possibly colored) formatter. if not use_colors: - formatter_options.pop('overridefmt') + formatter_options.pop('overridefmt', None) formatter_type = ColoredFormatter if use_colors else logging.Formatter handler.setFormatter(formatter_type(**formatter_options)) @@ -701,7 +701,7 @@ def __init__(self, fmt=None, datefmt=None, level_styles=None, field_styles=None, _datefmt) except Exception: - self.formatters.pop(level) + self.formatters.pop(level, None) logging.Formatter.__init__(self, self.colorize_format(fmt), datefmt) From 0c165028b2204d22148ad1cafc506657e965957b Mon Sep 17 00:00:00 2001 From: sanjay Date: Fri, 19 May 2017 18:14:07 +0530 Subject: [PATCH 4/7] #PR 15, pep8 fix --- coloredlogs/demo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coloredlogs/demo.py b/coloredlogs/demo.py index 523f490..b35487c 100644 --- a/coloredlogs/demo.py +++ b/coloredlogs/demo.py @@ -102,4 +102,4 @@ class RandomException(Exception): time.sleep(DEMO_DELAY) logger.info("Done, exiting ..") demonstrate_colored_logging() -demonstrate_colored_logging_with_different_formatters() \ No newline at end of file +demonstrate_colored_logging_with_different_formatters() From 0582e6a62a1e1ab2e40d499e70fb1af9f498a6ef Mon Sep 17 00:00:00 2001 From: sanjay Date: Fri, 19 May 2017 23:00:05 +0530 Subject: [PATCH 5/7] #PR 15, fix flake8 issues --- coloredlogs/__init__.py | 6 +++--- coloredlogs/demo.py | 37 +++++++++++++++++-------------------- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/coloredlogs/__init__.py b/coloredlogs/__init__.py index d518d36..fed2361 100644 --- a/coloredlogs/__init__.py +++ b/coloredlogs/__init__.py @@ -834,9 +834,9 @@ def __init__(self, fmt=None, datefmt=None, level_styles=None, field_styles=None, _fmt = overridefmt[level].get('fmt', fmt) _datefmt = overridefmt[level].get('datefmt', datefmt) self.formatters[level] = logging.Formatter( - self.colorize_format(_fmt), - _datefmt) - + self.colorize_format(_fmt), + _datefmt + ) except Exception: self.formatters.pop(level, None) diff --git a/coloredlogs/demo.py b/coloredlogs/demo.py index b35487c..54b1c1c 100644 --- a/coloredlogs/demo.py +++ b/coloredlogs/demo.py @@ -48,7 +48,8 @@ class RandomException(Exception): def demonstrate_colored_logging_with_different_formatters(): - """A simple demonstration of the `coloredlogs` package.""" + """Interactively demonstrate the :mod:`coloredlogs` package with different formatters + """ # Initialize colored output to the terminal, default to the # DEBUG logging level but enable the user the customize it. FORMATS = { @@ -60,29 +61,25 @@ def demonstrate_colored_logging_with_different_formatters(): # "WARNING": {} } FIELD_STYLES = dict( - asctime=dict(color='green'), - hostname=dict(color='magenta'), - levelname=dict(color='blue', bold=False), - programname=dict(color='cyan'), - name=dict(color='blue'), - module=dict(color='cyan'), - lineno=dict(color='magenta') + asctime=dict(color='green'), + hostname=dict(color='magenta'), + levelname=dict(color='blue', bold=False), + programname=dict(color='cyan'), + name=dict(color='blue'), + module=dict(color='cyan'), + lineno=dict(color='magenta') ) LEVEL_STYLES = { - 'DEBUG': {"color": "blue"}, - 'INFO': {"color": "green"}, - 'WARNING': {"color": "yellow"}, - 'ERROR': {"color": "red"}, - 'CRITICAL': {"color": 'red'}, - 'FATAL': {"color": 'red'} - } - fmt = ( - "%(asctime)s - %(levelname)s - " - "%(module)s - %(message)s" - ) + 'DEBUG': {"color": "blue"}, + 'INFO': {"color": "green"}, + 'WARNING': {"color": "yellow"}, + 'ERROR': {"color": "red"}, + 'CRITICAL': {"color": 'red'}, + 'FATAL': {"color": 'red'} + } + coloredlogs.install(level=os.environ.get('COLOREDLOGS_LOG_LEVEL', 'DEBUG'), - # fmt=fmt, field_styles=FIELD_STYLES, level_styles=LEVEL_STYLES, overridefmt=FORMATS) From 2e4967df372dc609a2d0362c2f67fbede4a7146a Mon Sep 17 00:00:00 2001 From: sanjay Date: Fri, 19 May 2017 23:17:44 +0530 Subject: [PATCH 6/7] #15 - fix make check failures --- coloredlogs/__init__.py | 4 ++-- coloredlogs/demo.py | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/coloredlogs/__init__.py b/coloredlogs/__init__.py index fed2361..40a0d74 100644 --- a/coloredlogs/__init__.py +++ b/coloredlogs/__init__.py @@ -787,8 +787,6 @@ def walk_propagation_tree(logger): class ColoredFormatter(logging.Formatter): - formatters = {} - """ Log :class:`~logging.Formatter` that uses `ANSI escape sequences`_ to create colored logs. @@ -797,6 +795,8 @@ class ColoredFormatter(logging.Formatter): when you call :func:`coloredlogs.install()`. """ + formatters = {} + def __init__(self, fmt=None, datefmt=None, level_styles=None, field_styles=None, overridefmt=None): """ Initialize a :class:`ColoredFormatter` object. diff --git a/coloredlogs/demo.py b/coloredlogs/demo.py index 54b1c1c..9231195 100644 --- a/coloredlogs/demo.py +++ b/coloredlogs/demo.py @@ -48,10 +48,10 @@ class RandomException(Exception): def demonstrate_colored_logging_with_different_formatters(): - """Interactively demonstrate the :mod:`coloredlogs` package with different formatters - """ + """Interactively demonstrate the :mod:`coloredlogs` package with different formatters""" # Initialize colored output to the terminal, default to the # DEBUG logging level but enable the user the customize it. + FORMATS = { "INFO": {'fmt': "%(asctime)s - %(levelname)s - " "%(module)s - %(message)s"}, @@ -98,5 +98,7 @@ class RandomException(Exception): logger.exception(e) time.sleep(DEMO_DELAY) logger.info("Done, exiting ..") + + demonstrate_colored_logging() demonstrate_colored_logging_with_different_formatters() From b1c9ca53dfa29f8902e29462a22500bf9a71270a Mon Sep 17 00:00:00 2001 From: sanjay Date: Thu, 22 Jun 2017 15:38:15 +0530 Subject: [PATCH 7/7] #15 add cli formatter tests --- coloredlogs/cli.py | 5 ++++- coloredlogs/tests.py | 9 +++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/coloredlogs/cli.py b/coloredlogs/cli.py index 701e1f7..7898ed3 100644 --- a/coloredlogs/cli.py +++ b/coloredlogs/cli.py @@ -49,6 +49,7 @@ # Modules included in our package. from coloredlogs.converter import capture, convert from coloredlogs.demo import demonstrate_colored_logging +from coloredlogs.demo import demonstrate_colored_logging_with_different_formatters # Initialize a logger for this module. logger = logging.getLogger(__name__) @@ -60,7 +61,7 @@ def main(): try: # Parse the command line arguments. options, arguments = getopt.getopt(sys.argv[1:], 'cdh', [ - 'convert', 'to-html', 'demo', 'help', + 'convert', 'to-html', 'demo', 'demo-with-formatter', 'help', ]) # Map command line options to actions. for option, value in options: @@ -69,6 +70,8 @@ def main(): arguments = [] elif option in ('-d', '--demo'): actions.append(demonstrate_colored_logging) + elif option in ('-f', '--demo-with-formatter'): + actions.append(demonstrate_colored_logging_with_different_formatters) elif option in ('-h', '--help'): usage(__doc__) return diff --git a/coloredlogs/tests.py b/coloredlogs/tests.py index 33a339c..b26e3b3 100644 --- a/coloredlogs/tests.py +++ b/coloredlogs/tests.py @@ -380,6 +380,15 @@ def test_cli_demo(self): for name in 'debug', 'info', 'warning', 'error', 'critical': assert name.upper() in output + def test_cli_demo_with_formatters(self): + """Test the command line colored logging demonstration.""" + with CaptureOutput() as capturer: + main('coloredlogs', '--demo-with-formatter') + output = capturer.get_text() + # Make sure the output contains all of the expected logging level names. + for name in 'debug', 'info', 'error', 'critical': + assert name.upper() in output + def test_cli_conversion(self): """Test the command line HTML conversion.""" output = main('coloredlogs', '--convert', 'coloredlogs', '--demo', capture=True)