如何使用Python logging在click CLI中输出日志?

14

我使用了'click'库编写了一个Python命令行界面。我想同时使用Python内置的logging模块来将日志记录到控制台,但是我一直无法将日志消息输出到控制台。我尝试了一个非常简单的方法:

logger = logging.getLogger(__name__)

@click.command()
def cli():
    logger.setLevel("INFO")
    logger.info("Does this work?")
    print("done.")

记录器的内容没有出现在我的控制台中。也许需要处理程序来明确地将日志消息发送到标准输出?

logger = logging.getLogger(__name__)

@click.command()
def cli():
    handler = logging.StreamHandler(sys.stdout)
    handler.setFormatter(logging.Formatter('%(asctime)s %(message)s'))
    handler.setLevel("INFO")
    logger.addHandler(handler)
    logger.info("Does this work?")
    print("done.")

不幸的是,这也行不通。

第三个选项-创建一个处理程序并设置处理程序和记录器的日志级别-可以工作:

logger = logging.getLogger(__name__)

@click.command()
def cli():
    logger.setLevel("INFO")
    handler = logging.StreamHandler(sys.stderr)
    handler.setFormatter(logging.Formatter('%(asctime)s %(message)s'))
    handler.setLevel("INFO")
    logger.addHandler(handler)
    logger.info("Does this work?")
    print("done.")

看起来:

  • 如果使用logging.getLogger创建记录器,我必须明确地为我的记录器创建处理程序。
  • 并且我必须在记录器和处理程序上都设置日志级别?

是这样吗?设置两次级别似乎有些愚蠢。有什么意义吗?

还是我仍然误解了正确的方法?

感谢您的帮助!

3个回答

9
我个人喜欢使用loguru库来处理日志,我认为它更加简单。
以下是我通常的代码示例:
import click
from loguru import logger


@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name', help='The person to greet.')
def hello(count, name):
    """Simple program that greets NAME for a total of COUNT times."""
    for x in range(count):
        logger.info(f"That's it, beautiful and simple logging! - Counter: {x}")
        click.echo('Hello %s!' % name)

if __name__ == '__main__':
    hello()

 python loguru-click-cli-test.py --count=3
Your name: Geraldo
2020-06-10 20:02:48.297 | INFO     | __main__:hello:11 - That's it, beautiful and simple logging! - Counter: 0
Hello Geraldo!
2020-06-10 20:02:48.297 | INFO     | __main__:hello:11 - That's it, beautiful and simple logging! - Counter: 1
Hello Geraldo!
2020-06-10 20:02:48.297 | INFO     | __main__:hello:11 - That's it, beautiful and simple logging! - Counter: 2
Hello Geraldo!

Loguru: https://github.com/Delgan/loguru


7

我必须手动设置

logging.basicConfig(level=logging.INFO)

示例

import click
import logging

logging.basicConfig(level=logging.INFO)

@click.command()
def cli():
    logging.info("it works")

提供

$ mycli
INFO:root:it works

1
使用logging.basicConfig(level=logging.INFO, format='%(message)s')可以获得不带有“INFO:root:”的输出。 - Noam Nol

1

我想在调用点击处理程序时获取日志(命令名称和参数)。最终我得到了这段代码:

from functools import wraps
import logging
import click

logger = logging.getLogger(__name__)

def click_log(fn):
    @wraps(fn)
    def wrapper(*args, **kwargs):
        context = click.get_current_context()
        logger.info(f"{context.command.name}(**{context.params})")
        return fn(*args, **kwargs)
    return wrapper

@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
              help='The person to greet.')
@click_log
def hello(count, name):
    """Simple program that greets NAME for a total of COUNT times."""
    for x in range(count):
        click.echo(f"Hello {name}!")  # you can use logger.info


def configure_logger():
    logging.basicConfig(level="DEBUG")

configure_logger()

if __name__ == '__main__':
    hello()


它会给你以下输出:
python test_click.py --count 3
Your name: ok
INFO:__main__:hello(**{'count': 3, 'name': 'ok'})
Hello ok!
Hello ok!
Hello ok!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接