click-log icon indicating copy to clipboard operation
click-log copied to clipboard

Allow specifying custom formatter and log level in init decorator

Open tomers opened this issue 7 years ago • 6 comments

Hi, I wanted to add support for explicitly defining formatter and logging level during declaration of the logger in the @init decorator. I added unit-tests for this new feature. I wanted to update documentation (of http://click.pocoo.org/dev/api/) accordingly, but unfortunately it seems that the documentation code is not part of the GitHub project. I would appreciate if you could merge this code.

Thanks

tomers avatar Jun 26 '17 12:06 tomers

Inside your CLI function you can just use logger.getLogger('name') and modify it as you like! We should document this.

untitaker avatar Jun 27 '17 10:06 untitaker

# -*- coding: utf-8 -*-

import logging

import click
from click.testing import CliRunner

import click_log

import pytest


logging.basicConfig(level=logging.WARNING, format='CUSTOM_FORMATTER | %(levelname)s | %(message)s')
# Now the handler of the root logger has a custom formatter
test_logger = logging.getLogger(__name__)
# The formatter of test_logger is the root logger's formatter, which is the custom formatter


def test_level_with_formatter_inside(runner):
    """
    The following test fails, since @click_log.init() overwrites the custom format set by logging.basicConfig.
    There is no way to restore the original formatter which is overwritten by ColorFormatter
    """
    @click.command()
    @click_log.init()  # this decorator overwrites the root logger's formatter, replacing it with ColorFormatter
    def cli():
        # The formatter of test_logger is still the root logger's formatter, but now it is ColorFormatter.
        # The custom formatter defined above is now gone, and cannot be retrieved.
        # A workaround is to create a new formatter here with the same properties, but sometimes the basicConfig
        # is set by the application logic and we cannot reproduce it easily 
        test_logger.debug('hey')
        test_logger.info('yo')
        test_logger.warning('oh')
        test_logger.error('damn')

    result = runner.invoke(cli, catch_exceptions=False)
    assert not result.exception
    assert result.output == 'CUSTOM_FORMATTER | WARNING | oh\nCUSTOM_FORMATTER | ERROR | damn\n'

BTW I considered adding some overwrite_formatter boolean parameter (defaults to True) in the init decorator. What do you think should be the solution to this problem?

tomers avatar Jun 28 '17 07:06 tomers

I meant that you can do this within the function, but actually this doesn't cover all cases. I'll think about it.

untitaker avatar Jul 24 '17 18:07 untitaker

Any news? :-)

tomers avatar Sep 12 '17 07:09 tomers

Recently click_log.init vanished and click_log.basic_config can be called anytime you like. Therefore you can first call basic_config and then use your own code to modify the logger. Does that cover your usecase?

untitaker avatar Sep 25 '17 17:09 untitaker

Check out #10 for info on migration to the new API

untitaker avatar Sep 25 '17 18:09 untitaker