Giter Site home page Giter Site logo

xolox / python-coloredlogs Goto Github PK

View Code? Open in Web Editor NEW
533.0 10.0 42.0 945 KB

Colored terminal output for Python's logging module

Home Page: https://coloredlogs.readthedocs.io

License: MIT License

Python 97.11% Makefile 1.60% Shell 1.29%
python logging terminal ansi-colors syslog cron html

python-coloredlogs's Introduction

coloredlogs: Colored terminal output for Python's logging module

image

image

The coloredlogs package enables colored terminal output for Python's logging module. The ColoredFormatter class inherits from logging.Formatter and uses ANSI escape sequences to render your logging messages in color. It uses only standard colors so it should work on any UNIX terminal. It's currently tested on Python 2.7, 3.5+ and PyPy (2 and 3). On Windows coloredlogs automatically tries to enable native ANSI support (on up-to-date Windows 10 installations) and falls back on using colorama (if installed). Here is a screen shot of the demo that is printed when the command coloredlogs --demo is executed:

image

Note that the screenshot above includes custom logging levels defined by my verboselogs package: if you install both coloredlogs and verboselogs it will Just Work (verboselogs is of course not required to use coloredlogs).

Installation

The coloredlogs package is available on PyPI which means installation should be as simple as:

$ pip install coloredlogs

There's actually a multitude of ways to install Python packages (e.g. the per user site-packages directory, virtual environments or just installing system wide) and I have no intention of getting into that discussion here, so if this intimidates you then read up on your options before returning to these instructions ๐Ÿ˜‰.

Optional dependencies

Native ANSI support on Windows requires an up-to-date Windows 10 installation. If this is not working for you then consider installing the colorama package:

$ pip install colorama

Once colorama is installed it will be used automatically.

Usage

Here's an example of how easy it is to get started:

import coloredlogs, logging

# Create a logger object.
logger = logging.getLogger(__name__)

# By default the install() function installs a handler on the root logger,
# this means that log messages from your code and log messages from the
# libraries that you use will all show up on the terminal.
coloredlogs.install(level='DEBUG')

# If you don't want to see log messages from libraries, you can pass a
# specific logger object to the install() function. In this case only log
# messages originating from that logger will show up on the terminal.
coloredlogs.install(level='DEBUG', logger=logger)

# Some examples.
logger.debug("this is a debugging message")
logger.info("this is an informational message")
logger.warning("this is a warning message")
logger.error("this is an error message")
logger.critical("this is a critical message")

Format of log messages

The ColoredFormatter class supports user defined log formats so you can use any log format you like. The default log format is as follows:

%(asctime)s %(hostname)s %(name)s[%(process)d] %(levelname)s %(message)s

This log format results in the following output:

2015-10-23 03:32:22 peter-macbook coloredlogs.demo[30462] DEBUG message with level 'debug'
2015-10-23 03:32:23 peter-macbook coloredlogs.demo[30462] VERBOSE message with level 'verbose'
2015-10-23 03:32:24 peter-macbook coloredlogs.demo[30462] INFO message with level 'info'
...

You can customize the log format and styling using environment variables as well as programmatically, please refer to the online documentation for details.

Enabling millisecond precision

If you're switching from logging.basicConfig() to coloredlogs.install() you may notice that timestamps no longer include milliseconds. This is because coloredlogs doesn't output milliseconds in timestamps unless you explicitly tell it to. There are three ways to do that:

  1. The easy way is to pass the milliseconds argument to coloredlogs.install():

    coloredlogs.install(milliseconds=True)

    This became supported in release 7.1 (due to #16).

  2. Alternatively you can change the log format to include 'msecs':

    %(asctime)s,%(msecs)03d %(hostname)s %(name)s[%(process)d] %(levelname)s %(message)s

    Here's what the call to coloredlogs.install() would then look like:

    coloredlogs.install(fmt='%(asctime)s,%(msecs)03d %(hostname)s %(name)s[%(process)d] %(levelname)s %(message)s')

    Customizing the log format also enables you to change the delimiter that separates seconds from milliseconds (the comma above). This became possible in release 3.0 which added support for user defined log formats.

  3. If the use of %(msecs)d isn't flexible enough you can instead add %f to the date/time format, it will be replaced by the value of %(msecs)03d. Support for the %f directive was added to release 9.3 (due to #45).

Custom logging fields

The following custom log format fields are supported:

  • %(hostname)s provides the hostname of the local system.
  • %(programname)s provides the name of the currently running program.
  • %(username)s provides the username of the currently logged in user.

When coloredlogs.install() detects that any of these fields are used in the format string the applicable logging.Filter subclasses are automatically registered to populate the relevant log record fields.

Changing text styles and colors

The online documentation contains an example of customizing the text styles and colors.

Colored output from cron

When coloredlogs is used in a cron job, the output that's e-mailed to you by cron won't contain any ANSI escape sequences because coloredlogs realizes that it's not attached to an interactive terminal. If you'd like to have colors e-mailed to you by cron there are two ways to make it happen:

Modifying your crontab

Here's an example of a minimal crontab:

MAILTO="your-email-address@here"
CONTENT_TYPE="text/html"
* * * * * root coloredlogs --to-html your-command

The coloredlogs program is installed when you install the coloredlogs Python package. When you execute coloredlogs --to-html your-command it runs your-command under the external program script (you need to have this installed). This makes your-command think that it's attached to an interactive terminal which means it will output ANSI escape sequences which will then be converted to HTML by the coloredlogs program. Yes, this is a bit convoluted, but it works great :-)

Modifying your Python code

The ColoredCronMailer class provides a context manager that automatically enables HTML output when the $CONTENT_TYPE variable has been correctly set in the crontab.

This requires my capturer package which you can install using pip install 'coloredlogs[cron]'. The [cron] extra will pull in capturer 2.4 or newer which is required to capture the output while silencing it - otherwise you'd get duplicate output in the emails sent by cron.

The context manager can also be used to retroactively silence output that has already been produced, this can be useful to avoid spammy cron jobs that have nothing useful to do but still email their output to the system administrator every few minutes :-).

Contact

The latest version of coloredlogs is available on PyPI and GitHub. The online documentation is available on Read The Docs and includes a changelog. For bug reports please create an issue on GitHub. If you have questions, suggestions, etc. feel free to send me an e-mail at [email protected].

License

This software is licensed under the MIT license.

ยฉ 2020 Peter Odding.

python-coloredlogs's People

Contributors

althonos avatar anntzer avatar colonelpanic8 avatar cottsay avatar drewp avatar eblis avatar ghisvail avatar hugovk avatar johnthagen avatar ldesgoui avatar malikoth avatar mastak avatar ppinard avatar risicle avatar xolox avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-coloredlogs's Issues

Logging to files doesn't function the same with coloredlogs installed

With the following settings in my log_config.json I am able to log DEBUG to console and DEBUG to a file (without coloredlogs installed).

  "version": 1,
  "disable_existing_loggers": true,
  "formatters": {
    "standard": {
      "class": "logging.Formatter",
      "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    }
  },
  "handlers": {
    "console": {
      "class": "logging.StreamHandler",
      "formatter": "standard",
      "level": "DEBUG", # <---- Normally this setting is what decides the log level of your console (i.e. setting to DEBUG will show debug info in console). With coloredlogs it doesn't
      "stream": "ext://sys.stdout"
    },
    "timed_rotating_file_handler": {
      "class": "logging.handlers.TimedRotatingFileHandler",
      "encoding": "utf-8",
      "filename": "logs/MacEnvironmentSetup.log",
      "when": "midnight",
      "interval": 1,
      "backupCount": 2,
      "formatter": "standard",
      "level": "DEBUG"
    }
  },
  "loggers": {},
  "root": {
    "handlers": [
      "console",
      "timed_rotating_file_handler"
    ],
    "level": "DEBUG"
  }
}

If I use the same settings with coloredlogs installed, it will no longer direct DEBUG to the console. DEBUG now only shows up in the log file. This is the only line of code that I added in order to enable coloredlogs (aside from importing it): coloredlogs.install(milliseconds=True)

Is this a bug with coloredlogs, or is there a special way to set it up so that it can debug to the console as well? Thanks

AttributeError: 'str' object has no attribute 'items'

Hello,
When I try to run my python program I got an error like this:
AttributeError: 'str' object has no attribute 'items'
This error comes from <path_to_my_virtualenv>/lib/python3.5/site-packages/coloredlogs/init.py:994:
self.level_styles = self.nn.normalize_keys(DEFAULT_LEVEL_STYLES if level_styles is None else level_styles)

This is caused by the mismatch of the constructor of coloredlogs and the constructor of logging.Formatter.
This issue can be bypassed by explicitly specify each parameters of the coloredlogs constructor. Another alternative could be put the style parameter in fourth position.

Error when user provides a customized record_factory function for 10.0 version

Following the logging document https://docs.python.org/3/library/logging.html
Do:

old_factory = logging.getLogRecordFactory()

def record_factory(*args, **kwargs):
    record = old_factory(*args, **kwargs)
    record.custom_attribute = 0xdecafbad
    return record

logging.setLogRecordFactory(record_factory)

Then coloredlogs 10.0 throws error:

File "C:\anaconda3\envs\pt4\lib\site-packages\coloredlogs\__init__.py", line 1110, in format
    else logging.LogRecord
TypeError: __class__ must be set to a class, not 'function' object

Customize INFO log color

Hey,

I've just started playing around with updating the format of the logs depending on if the program logs to a file (non-interactive) vs. a terminal (interactive).

For logging to file it works great but when I want to log just the message to STDERR, the info logs don't really stand out from anything printed to STDOUT. This can be confusing to users.

So I was wondering about options to control coloring of the output - is it possible to customize the style of different log levels? Perhaps I could style the INFO logs in "blue" to make them stand out more

Thanks for a great package! ๐Ÿ“ฆ

Garbage on Windows console

The coloredlogs module does not support Windows yet, as in it uses only ANSI escape sequences which are simply not supported on Windows. There's a way to fix that but it's a bit of work (already on the to-do list though :-).

What's worse though is that sys.stderr.isatty() (obviously) returns True on Windows so coloredlogs prints ANSI escape sequences (despite them not being supported) and messes up the console output (as in, the output is almost unintelligible). This should definitely be fixed in the short term (before real/proper support for the Windows console is added).

Django integration

It is possible to completely integrate this wonderful package with django?

I'm using this, but I've to change the fmt because the hostname for example doesn't get injected.

LOGGING = {
  "version": 1,
  "disable_existing_loggers": False,
  "formatters": {
    "coloredlogs": {
      "()": "coloredlogs.ColoredFormatter",
      "fmt": "[%(asctime)s] %(name)s %(levelname)s %(message)s",
    },
  },
  "handlers": {
    "console": {
      "class": "logging.StreamHandler",
      "level": LOGGING_LEVEL,
      "formatter": "coloredlogs",
    },
  },
  "loggers": {
    "": {
      "handlers": [
        "console",
      ],
      "level": LOGGING_LEVEL,
    },
  },
}

Align log message types

The default log format misaligns log messages of different types:

2015-10-23 03:32:22 peter-macbook coloredlogs.demo[30462] DEBUG message with level 'debug'
2015-10-23 03:32:23 peter-macbook coloredlogs.demo[30462] VERBOSE message with level 'verbose'
2015-10-23 03:32:24 peter-macbook coloredlogs.demo[30462] INFO message with level 'info'

It would be great if by default coloredlogs worked like:

2015-10-23 03:32:22 peter-macbook coloredlogs.demo[30462] DEBUG   message with level 'debug'
2015-10-23 03:32:23 peter-macbook coloredlogs.demo[30462] VERBOSE message with level 'verbose'
2015-10-23 03:32:24 peter-macbook coloredlogs.demo[30462] INFO    message with level 'info'

[Failing test] ColoredLogsTestCase.test_plain_text_output_format

[   60s] + py.test-3.7 coloredlogs/tests.py -v -k 'not (test_cli_conversion or test_auto_install)'
[   61s] ============================= test session starts ==============================
[   61s] platform linux -- Python 3.7.2, pytest-3.10.1, py-1.7.0, pluggy-0.8.0 -- /usr/bin/python3
[   61s] cachedir: .pytest_cache
[   61s] rootdir: /home/abuild/rpmbuild/BUILD/coloredlogs-10.0, inifile:
[   61s] plugins: cov-2.6.0
...
[   61s] =================================== FAILURES ===================================
[   61s] ______________ ColoredLogsTestCase.test_plain_text_output_format _______________
[   61s] 
[   61s] self = <coloredlogs.tests.ColoredLogsTestCase testMethod=test_plain_text_output_format>
[   61s] test_method = <bound method ColoredLogsTestCase.test_plain_text_output_format of <coloredlogs.tests.ColoredLogsTestCase testMethod=test_plain_text_output_format>>
[   61s] args = (), kw = {}
[   61s] 
[   61s]     def skipTestWrapper(self, test_method, *args, **kw):
[   61s]         """
[   61s]         Wrap test methods to translate exceptions into skipped tests.
[   61s]     
[   61s]         :param test_method: The test method to wrap.
[   61s]         :param args: The positional arguments to the test method.
[   61s]         :param kw: The keyword arguments to the test method.
[   61s]         :returns: The return value of the test method.
[   61s]     
[   61s]         When a :class:`TestCase` object is initialized, :func:`__init__()`
[   61s]         wraps all of the ``test_*`` methods with :func:`skipTestWrapper()`.
[   61s]     
[   61s]         When a test method raises an exception, :func:`skipTestWrapper()` will
[   61s]         catch the exception and call :func:`shouldSkipTest()` to decide whether
[   61s]         to translate the exception into a skipped test.
[   61s]     
[   61s]         When :func:`shouldSkipTest()` returns :data:`True` the exception is
[   61s]         swallowed and :exc:`unittest.SkipTest` is raised instead of the
[   61s]         original exception.
[   61s]         """
[   61s]         try:
[   61s] >           return test_method(*args, **kw)
[   61s] 
[   61s] /usr/lib/python3.7/site-packages/humanfriendly/testing.py:678: 
[   61s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   61s] 
[   61s] self = <coloredlogs.tests.ColoredLogsTestCase testMethod=test_plain_text_output_format>
[   61s] 
[   61s]     def test_plain_text_output_format(self):
[   61s]         """Inspect the plain text output of coloredlogs."""
[   61s]         logger = VerboseLogger(random_string(25))
[   61s]         stream = StringIO()
[   61s]         install(level=logging.NOTSET, logger=logger, stream=stream)
[   61s]         # Test that filtering on severity works.
[   61s]         logger.setLevel(logging.INFO)
[   61s]         logger.debug("No one should see this message.")
[   61s]         assert len(stream.getvalue().strip()) == 0
[   61s]         # Test that the default output format looks okay in plain text.
[   61s]         logger.setLevel(logging.NOTSET)
[   61s]         for method, severity in ((logger.debug, 'DEBUG'),
[   61s]                                  (logger.info, 'INFO'),
[   61s]                                  (logger.verbose, 'VERBOSE'),
[   61s]                                  (logger.warning, 'WARNING'),
[   61s]                                  (logger.error, 'ERROR'),
[   61s]                                  (logger.critical, 'CRITICAL')):
[   61s]             # Prepare the text.
[   61s]             text = "This is a message with severity %r." % severity.lower()
[   61s]             # Log the message with the given severity.
[   61s]             method(text)
[   61s]             # Get the line of output generated by the handler.
[   61s]             output = stream.getvalue()
[   61s]             lines = output.splitlines()
[   61s] >           last_line = lines[-1]
[   61s] E           IndexError: list index out of range
[   61s] 
[   61s] coloredlogs/tests.py:396: IndexError
[   61s] ----------------------------- Captured stderr call -----------------------------
[   61s]

Official package for openSUSE/Tumbleweed.

[Feature request] Logbook support

1. Request

It would be nice, if you add logbook support โ€” a popular alternative default logging module.

2. Justification

I don't find Python modules, that support logbook. If I use modules for custom colored output as pyfancy or colorama, I can highlight messages, but not CRITICAL, ERROR, WARNING, NOTICE, INFO and DEBUG words, example:

NOTICE

It would be nice, if would be possible to highlight all logbook output.

Thanks.

do not works with setting explicit logger

This works on the app with few lines of codes:
coloredlogs.install(logger=logger, level=logging.DEBUG, fmt=fmt_term, datefmt=datefmt)
but at my big app setting explicit logger looks like disabling coloring at all;

this color my logs - but for all libraries - that I do not need:
coloredlogs.install(fmt=fmt_term, datefmt=datefmt)

coloredlogs cli tool issue

โžœ  workspace  coloredlogs --to-html test2.py
script: illegal option -- e
usage: script [-adkpqr] [-t time] [file [command ...]]

I'm getting the following error running on Mac OS X 10.11 with ZSH shell. Running without the --e flag also does something pretty weird. I think it like flushes STDOUT and then prints a bunch of blank lines. Unclear.

test2.py is as follows:

# Create a logger object.
import logging
logger = logging.getLogger('your-module')

# Initialize coloredlogs.
import coloredlogs
coloredlogs.install(level='DEBUG')

# Some examples.
logger.debug("this is a debugging message")
logger.info("this is an informational message")
logger.warn("this is a warning message")
logger.error("this is an error message")
logger.critical("this is a critical message")

straight from the examples :)

Always prints out library debug prints

I am getting very janky behavior from this library.

The closest thing I can get to it doing what I want is having a formatted message print verbosely through every library I have installed and that is without specifying a program name or a logger.

When I specify a logger, I lose all of my formatting together, and it STILL prints out every library print on top of that.

Specifying the program name had no effect on the print filtering.

I was reading some of the old closed issues that had similar problems, but I think they are still problems.

To recreate this issue, just test this logger with any library (like tensorflow for example) and try to only get your application to print to the logger.

Termination and spaces

In the present version, colouring of the different fields (name, loglevel, hostname, etc.) seems to be dependent on placement of white spaces. I.e. if no white spaces are placed between fields, consecutive fields will have the colour of the first in string. Is that intended behaviour? It can be seen using the following code:

import coloredlogs, logging
from logging import debug, info, error, warning as warn
coloredlogs.install(level='DEBUG', fmt=formatstring, datefmt='%d.%m.%y %H:%M' )
debug("debug")
info("info")
warn("warn")
error("error")

where two different format strings are used (note the spaces around levelanme, name and process string formatters):

formatstring='[ %(levelname)-8s ] (%(asctime)s %(name)s @ %(hostname)s [%(process)d]'   # with spaces
formatstring='[%(levelname)-8s] (%(asctime)s %(name)s@%(hostname)s[%(process)d]'       # without spaces

The result is something like this (note the color of the levelname and the blurred hostname field):

with spaces
without spaces

Better to use logger = logging.getLogger(__name__) in example?

In the example on the PyPI page:

...
# Create a logger object.
logger = logging.getLogger('your-module')
...

Would this be better to write as:

...
# Create a logger object.
logger = logging.getLogger(__name__)
...

I've always thought this was best practice and also removes a DRY problem. Happy to PR if you think this would be an improvement.

pipenv lock edge case problem in setup.py

It appears the setup.py file is configured incorrectly and causes problems when trying to pipenv lock. It is better to return a list of strings with the appropriate format as recommended by the setuptools documentation.

python-coloredlogs/setup.py

Lines 135 to 137 in 399af2a

install_requires=get_install_requires(),
extras_require=get_extras_require(),
tests_require=get_requirements('requirements-tests.txt'),

This issue describes the problem in detail: pypa/pipenv#1578 (comment)

This is is not very easy to reproduce on many machines, but is apparently a very common issue that pops up in pipenv.

AttributeError: 'Logger' object has no attribute 'success'

In testing the new 'success' logger level, I'm getting the following with stack trace:

โžœ  ~ pip install --upgrade coloredlogs
Requirement already up-to-date: coloredlogs in ./.anyenv/envs/pyenv/versions/3.6.1/lib/python3.6/site-packages
Requirement already up-to-date: humanfriendly>=3.2 in ./.anyenv/envs/pyenv/versions/3.6.1/lib/python3.6/site-packages (from coloredlogs)
โžœ  ~ pip list | grep coloredlog
coloredlogs (7.3)
โžœ  ~ ipython                   
Python 3.6.1 (default, Jun  7 2017, 13:01:33) 
Type 'copyright', 'credits' or 'license' for more information
IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import coloredlogs, logging

In [2]: logger = logging.getLogger(__name__)

In [3]: coloredlogs.install(level='DEBUG')

In [4]: coloredlogs.install(level='DEBUG')

In [5]: logger.debug('foobar')
2017-08-08 06:40:05 namib __main__[6157] DEBUG foobar

In [6]: logger.success('foobar')
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-6-ec77b2ea1cba> in <module>()
----> 1 logger.success('foobar')

AttributeError: 'Logger' object has no attribute 'success'

For sanity's sake I grepped the source code and indeed the success level is in the DEFAULT_LEVEL_STYLES dict.

Also, this works:

In [1]: import coloredlogs, logging

In [2]: coloredlogs.level_to_number('debug')
Out[2]: 10

In [3]: coloredlogs.level_to_number('success')
Out[3]: 20

Not quite sure what to make of this...

Feature request: Summarize similar logs

Since you said, you wanted coloredlogs to be 'logging done right', I thought, you might appreciate this unanswered question I hand on logging multiple similar messages.

To summarize: Logging multiple very similar messages in a loop should be summarized in the logs without adding every single message.

import logging
for i in range(999):
    logging.info("much of the same")   # fills logs very quickly

Should give something like:

> INFO:root:foo much of the sam (occured 999 times)

It seems to be a feature that no one else has. Thought you might like the challenge.

Default coloredlogs datetime output differs from standard formatter's behavior

When I install coloredlogs formatter by
coloredlogs.install(level='DEBUG', fmt='%(asctime)s %(name)s %(levelname)s -- %(message)s')
(asctime)'s output loses milliseconds (which are very important for most of a projects.

2016-03-07 22:55:10,880 ScriptManager WARNING -- Bla-bla-bla
vs.
2016-03-07 22:55:35:16 ScriptManager WARNING -- Bla-bla-bla

It should be nice to have the same format logic as standard formatter has. I use coloredlogs as optional dependency and I expect the log output to look the same with or without it installed (except colors, of course;)).

BTW, is there any way to enable milliseconds? I tried to play with datefmt a bit, but couldn't figure out what to pass to it.

deadlock between import and coloredlogs on Python 2.7

I have a scenario where our application is hanging on startup.
We start some background threads early on to monitor background processes. These log messages received from those processes.
We then import some configurable modules that can take some time to import. And some of them log messages on import (instantiating singleton objects).

Unfortunately, this means they are holding the import lock. But on Python 2.7, copy.copy runs an import of copyreg every single time it is called. And coloredlogs calls copy.copy when formatting a log. So it then blocks waiting for the import lock, and when the main thread tries to log, it tries to grab the logging lock that is being held in the background thread, deadlocking.

I have a gist that demonstrates this as a small commandline program.

'NoneType' object is not callable

Hi Peter, I've noticed the following exception happening:

Traceback (most recent call last):
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/logging/__init__.py", line 859, in emit
    msg = self.format(record)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/logging/__init__.py", line 732, in format
    return fmt.format(record)
  File "/Users/geo/code/cx/lib/python2.7/site-packages/coloredlogs/__init__.py", line 891, in format
    copy = Empty()
TypeError: 'NoneType' object is not callable

I'm using a 3rd party package, happybase, and in the __del__ method, it's calling close, which is doing this:

    def close(self):
        """Close the underyling transport to the HBase instance.

        This method closes the underlying Thrift transport (TCP connection).
        """
        if not self.transport.is_open():
            return

        if logger is not None:
            # If called from __del__(), module variables may no longer
            # exist.

            logger.debug(
                "Closing Thrift transport to %s:%d",
                self.host, self.port)

        self.transport.close()

From what I've been able to tell, Empty() no longer exists, because the garbage collector already disposes it. Would adding such an if test to format, like the guys from happybase did, be the way to go?

v7.3: Windows build requirements error (with fix)

I just ran into this while installing via setup.py install on a windows system w/Python 2.7.13:

Processing dependencies for coloredlogs==7.3 Searching for r Reading https://pypi.python.org/simple/r/ No local packages or working download links found for r error: Could not find suitable distribution for Requirement.parse('r')

The problem:
setup.py, function: get_install_requires()

You check for win32 to determine if you need to add colorama as a dependency. The problem is you use install_requires.extend with 'colorama' as the arg. extend, however, expects an iterable, so it turns "colorama" into ["c", "o", "l", "o", "r", "a", "m", "a"].

The fix:

File: setup.py

Change:
install_requires.extend('colorama')
to either:
install_requires.append('colorama')
or:
install_requires.extend(['colorama'])

coloredlogs.install Does NOT Honor the Command Line Parser click's --debug or --quite Options

Hi,

It seems that coloredlogs.install does NOT honor the command line parser click's --debug or --quite options:

Given:

from coloredlogs import install as coloredlogs_install

    log.debug("debug")
    log.info("info")
    log.warning("warning")
    log.error("error")
    log.critical("critical")

    coloredlogs_install()
    log.info("coloredlogs_installed")

    log.debug("debug2")
    log.info("info2")
    log.warning("warning2")
    log.error("error2")
    log.critical("critical2")

If I run my script with click decorated --debug option:

2019-02-17 03:28:19,961 [DEBUG] debug
2019-02-17 03:28:19,961 [INFO] info
2019-02-17 03:28:19,961 [WARNING] warning
2019-02-17 03:28:19,961 [ERROR] error
2019-02-17 03:28:19,962 [CRITICAL] critical
2019-02-17 03:28:19 INFO coloredlogs_installed
2019-02-17 03:28:19 INFO info2
2019-02-17 03:28:19 WARNING warning2
2019-02-17 03:28:19 ERROR error2
2019-02-17 03:28:19 CRITICAL critical2

As you can see that the DEBUG debug2 output is missing after coloredlogs_installed

The similar issue could be verified if we run my script with click decorated --quiet option.

I am using Python 3.7, and coloredlogs 10.0. Thanks.

feature request: additional log level for 'success'

I might implement this and send a PR but I want to make sure the PR would be welcome first...

It would be nice to have another loglevel, success, which would perhaps tweak the text and color of the output to bold and bright green so someone using our program has a very clear indication than an operation has succeeded.

problems installing coloredlogs 6.0

I'm running into problems with getting coloredlgos 6.0 installed:

  • i) easy_install refuses to install coloredlogs 6.0 because it tries to work with files outside the sandbox:
$ easy_install --version
setuptools 29.0.1 from /Users/kehoste/.pypkgs/lib/python2.7/site-packages/setuptools-29.0.1-py2.7.egg (Python 2.7)

$ easy_install -U --prefix ~/.pypkgs coloredlogs
Searching for coloredlogs
Reading https://pypi.python.org/simple/coloredlogs/
Downloading https://pypi.python.org/packages/fe/c1/5a1106e70b74ce51130ecace0ad52e6035f3876b973333a6f149a711c660/coloredlogs-6.0.tar.gz#md5=713e08247c3fede29c2717433c38ba71
Best match: coloredlogs 6.0
Processing coloredlogs-6.0.tar.gz
Writing /var/folders/xl/p7lmsxcs0bsg5_zv9y9lzk5c0000gn/T/easy_install-Zn0ret/coloredlogs-6.0/setup.cfg
Running coloredlogs-6.0/setup.py -q bdist_egg --dist-dir /var/folders/xl/p7lmsxcs0bsg5_zv9y9lzk5c0000gn/T/easy_install-Zn0ret/coloredlogs-6.0/egg-dist-tmp-le3AKN
error: Setup script exited with error: SandboxViolation: mkdir('/private/var/folders/xl/p7lmsxcs0bsg5_zv9y9lzk5c0000gn/Library', 511) {}

The package setup script has attempted to modify files on your system
that are not within the EasyInstall build area, and has been aborted.

This package cannot be safely installed by EasyInstall, and may not
support alternate installation locations even if you run its setup
script by hand.  Please inform the package's author and the EasyInstall
maintainers to find out if a fix or workaround is available.
  • ii) When setuptools installs coloredlogs 6.0 as a dependency for my tool when running the tests with python setup.py test (since coloredlogs is listed in tests_require), for some reason Python start consuming a lot of memory (I saw it go up to 30GB) before it makes my system swap. I'm seeing this on macOS Sierra 10.12.3.

I'm not sure if ii) is related to i), maybe it's a weird side-effect?

Autocall coloredlogs.install based on an environment variable

It is possible to detect whether an environment variable (say, COLOREDLOGS_AUTOUSE) is set whenever Python starts, and, if it is, automatically import coloredlogs and install it.
See https://github.com/ionelmc/python-hunter/blob/master/setup.py and http://python-hunter.readthedocs.io/en/latest/introduction.html#via-environment-variable for an example.
Basically the idea would be to provide a coloredlogs.pth file in .../site-packages/ with the contents (approximately)

import os; __import__("coloredlogs").install() if os.environ.get("COLOREDLOGS_AUTOUSE") else None

and rely on the fact that Python will execute any line starting with import in a pth file in the site-packages directory.

The advantage would be to make the use of coloredlogs completely transparent for the author of the code, and directly switchable by the end user.

coloredlog's streamhandler should re-fetch sys.stderr every time

logging's "lastResortHandler" (the default handler) refetches the stderr attribute of the sys module every time just before writing to it (https://github.com/python/cpython/blob/master/Lib/logging/__init__.py#L1077), thus allowing patching of sys.stderr (e.g., via contextlib.redirect_stderr). It would be nice if coloredlog's handler did the same (likewise to support patching of sys.stderr).

A possible API would be to default the "stream" kwarg to coloredlogs.install to None (instead of the current sys.stderr), which would have the meaning "sys.stderr, but refetched before each write".

Consider not setting level on the colored handler

Hi,

happy new user of coloredlogs for its out of the box nice feature.

please consider this use case:

In [1]: import coloredlogs

In [2]: import logging

In [3]: logger = logging.getLogger()

In [4]: coloredlogs.install()

In [5]: logger.setLevel(logging.DEBUG)

In [6]: logger.debug('foo')

In [7]: 

I find it a bit counter intuitive. Naively I'd have expected to see my "foo" debug call.

All would be good if coloredlogs wouldn't set the level on the actual handler but only on the root logger (or the explicitly passed one otherwise)..

wdyt ?

thx.

How to add logging filters to coloredlogs?

How to add filters to coloredlogs.install()?

Scenario:

I am loading logging configuration using logging.dictConfig as a yaml file. I have defined respective filters in the config file, the filters are not added to colored logs.

Usecase:

Stream INFO, WARN and DEBUG to stdout and ERROR and CRITICAL to stderr.

Code:

import logging
logger = logging.getLogger(__name__)
logger.info('INFO')
logger.error('ERROR')

Output:

# Actual Output:
2017-06-13 13:40:40 - INFO - __main__(117) - INFO
2017-06-13 13:40:40 - ERROR - __main__(118) - ERROR
2017-06-13 13:40:40,642 - ERROR <PID 89531:MainProcess> __main__.<module>(): ERROR

# Expected Output:
2017-06-13 13:40:40 - INFO - __main__(117) - INFO
2017-06-13 13:40:40,642 - ERROR <PID 89531:MainProcess> __main__.<module>(): ERROR

Logging Config: in init.py

import logging
import yaml
config = yaml.safe_load(f.read())
logging.config.dictConfig(config)
coloredlogs.install(fmt=config['formatters']['standard']['format'], stream=sys.stdout,
                                    level=logging.INFO)

YAML Config

version: 1
disable_existing_loggers: true


filters:
    info_filter:
        () : lib.InfoFilter        
    error_filter:
        () : lib.ErrorFilter

formatters:
    standard:
        format: "%(asctime)s - %(levelname)s - %(name)s(%(lineno)d) - %(message)s"    
    error:
        format: "%(asctime)s - %(levelname)s <PID %(process)d:%(processName)s> %(name)s.%(funcName)s(): %(message)s"

handlers:
    console:
        class: logging.StreamHandler
        level: DEBUG
        formatter: standard 
        filters: [info_filter]
        stream: ext://sys.stdout
        
    error_console:
        class: logging.StreamHandler
        level: ERROR
        formatter: error  
        filters: [error_filter]
        stream: ext://sys.stderr
        

    info_file_handler:
        class: logging.handlers.RotatingFileHandler
        level: INFO
        formatter: standard
        filename: /tmp/info.log
        maxBytes: 10485760 # 10MB
        backupCount: 20
        encoding: utf8

    error_file_handler:
        class: logging.handlers.RotatingFileHandler
        level: ERROR
        formatter: error
        filename: /tmp/errors.log
        maxBytes: 10485760 # 10MB
        backupCount: 20
        encoding: utf8

    debug_file_handler:
        class: logging.handlers.RotatingFileHandler
        level: DEBUG
        formatter: standard
        filename: /tmp/debug.log
        maxBytes: 10485760 # 10MB
        backupCount: 20
        encoding: utf8

    critical_file_handler:
        class: logging.handlers.RotatingFileHandler
        level: CRITICAL
        formatter: standard
        filename: /tmp/critical.log
        maxBytes: 10485760 # 10MB
        backupCount: 20
        encoding: utf8

    warn_file_handler:
        class: logging.handlers.RotatingFileHandler
        level: WARN
        formatter: standard
        filename: /tmp/warn.log
        maxBytes: 10485760 # 10MB
        backupCount: 20
        encoding: utf8

root:
    level: NOTSET
    handlers: [console, error_console]
    propogate: no

loggers:
    lib:
        level: DEBUG
        handlers: [info_file_handler, error_file_handler, critical_file_handler, debug_file_handler, 
                          warn_file_handler]
        propogate: no

Windows 10 ANSI support

Windows 10 supports ANSI by default.
But right now the use of Colorama on Windows is hardcoded.
terminal.terminal_supports_colors looks for the env var ANSICON maybe the same can be used for coloredlogs?

Read logging format

This module should output in same format as specified by logging.basicConfig.

Coloring causes misalignment

Using the following format string:

'%(asctime)s [%(levelname)-8s]: %(message)-160s [%(filename)s:%(funcName)s:%(lineno)d]'

You will get a different alignment on info than the other levels.
I imagine this is due to the invisible coloring characters, so would you be able to just color everything default if not colored to make it consistent?

AttributeError: 'module' object has no attribute 'install'

The following example from the documentation:

import coloredlogs, logging
coloredlogs.install()
logger = logging.getLogger()
logger.info("this is an informational message")

Gives this error in python 2.7.6 on Ubuntu 14.04:

Traceback (most recent call last):
  File "./coloredlogs.py", line 21, in <module>
    import coloredlogs, logging
  File "/home/confus/misc/test/coloredlogs.py", line 22, in <module>
    coloredlogs.install()
AttributeError: 'module' object has no attribute 'install'

Problem when use coloredlogs with other libraries.

When I use selenium+phantomjs and coloredlogs, I found all log will output to the console, include selenuim's log. I just want show my log. How can I close the other logs?

This is my code:

FIELD_STYLES = dict(
    asctime=dict(color='green'),
    hostname=dict(color='magenta'),
    levelname=dict(color='green', bold=coloredlogs.CAN_USE_BOLD_FONT),
    filename=dict(color='magenta'),
    name=dict(color='blue'),
    threadName=dict(color='green')
)

LEVEL_STYLES = dict(
    debug=dict(color='green'),
    info=dict(color='cyan'),
    verbose=dict(color='blue'),
    warning=dict(color='yellow'),
    error=dict(color='red'),
    critical=dict(color='red', bold=coloredlogs.CAN_USE_BOLD_FONT)
)
logger = logging.getLogger("ProjectName")

cf = ConfigParser.ConfigParser()
cf.read("config.ini")
if cf.has_option("ProjectName", "debug") and cf.get("ProjectName", "debug") == "On":
    level = "DEBUG"
else:
    level = "INFO"

coloredlogs.install(
    level=level,
    fmt="[%(levelname)s] [(%(threadName)s)] [%(asctime)s] [%(filename)s:%(lineno)d] %(message)s",
    datefmt="%H:%M:%S",
    level_styles=LEVEL_STYLES,
    field_styles=FIELD_STYLES,
)

And I write log like this:

logger.debug("debug information")

And the output like this:

[INFO] [(MainThread)] [00:06:46] [WebSpider.py:74] initial web spider phantomjs process pool...
[DEBUG] [(MainThread)] [00:06:51] [remote_connection.py:415] POST http://127.0.0.1:11225/wd/hub/session {"requiredCapabilities": {}, "desiredCapabilities": {"javascriptEnabled": true, "phantomjs.page.settings.resourceTimeout": 10, "phantomjs.page.settings.loadImages": false, "platform": "ANY", "browserName": "phantomjs", "version": ""}}
[DEBUG] [(MainThread)] [00:06:51] [remote_connection.py:510] Finished Request
[INFO] [(MainThread)] [00:06:51] [WebSpider.py:85] 25.00% finished.

The "remote_connection.py:510" isn't my log, maybe it create by selenium or phantomjs.

After read some docs, I found the coloredlogs.install() function has a param called logger, if it None, it will set to the root logger, so I pass my logger to it, like this below:

coloredlogs.install(
    level=level,
    logger=logger,
    fmt="[%(levelname)s] [(%(threadName)s)] [%(asctime)s] [%(filename)s:%(lineno)d] %(message)s",
    datefmt="%H:%M:%S",
    level_styles=LEVEL_STYLES,
    field_styles=FIELD_STYLES,
)

But this time, there is no log output to console, so I pass a stream to this function, "stream=sys.stdout", also no output.

Did I do something wrong?

Filter instead of logger

IIRC, a LogFilter can actually modify the LogRecord objects. Perhaps instead of (inflexibly) hard-coding the log format, you could just define a custom filter that wraps parts of the LogRecord with the proper unicode color codes?

Generate RFC 3339 timestamp

Is there anyway to generate RFC 3339 timestamp, for example,2014-04-28T15:44:45.758-07:00

When I pass to coloredlogs my own datefmt and enable milliseconds, it becomes 2014-04-28T15:44:45-07:00,758 (milliseconds at the end of time zone info)

Crash in emit() with the non ascii characters

'ascii' codec can't encode characters in position 63-66: ordinal not in range(128)

def emit(self, record):
    """
    Called by the logging module for each log record. Formats the log
    message and passes it onto logging.StreamHandler.emit().
    """
    # Colorize the log message text.
    severity = record.levelname
    message = str(record.msg)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.