[英]How to output logs with python logging in a click cli?
I've written a python cli with the 'click' library.我用“click”库编写了一个 python cli。 I'd like to also use python's built-in
logging
module for logging to the console.我还想使用 python 的内置
logging
模块来记录到控制台。 But I've struggled getting the logging messages to the console.但是我一直在努力将日志消息发送到控制台。 I tried a very simple approach:
我尝试了一个非常简单的方法:
logger = logging.getLogger(__name__)
@click.command()
def cli():
logger.setLevel("INFO")
logger.info("Does this work?")
print("done.")
The logger content doesn't appear in my console.记录器内容没有出现在我的控制台中。 Maybe it needs a handler to explicitly send log messages to stdout?
也许它需要一个处理程序来显式地将日志消息发送到标准输出?
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.")
Unfortunately this also doesn't work.不幸的是,这也不起作用。
A third option--creating a handler and setting loglevels for the handler and the logger-- works:第三个选项——创建一个处理程序并为处理程序和记录器设置日志级别——有效:
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.")
It seems like:这好像是:
logging.getLogger
, I have to create a handler for my logger explicitly.logging.getLogger
创建一个记录器,我必须明确地为我的记录器创建一个处理程序。 Is that right?那正确吗? It seems silly to set the level twice.
设置两次级别似乎很愚蠢。 What's the point?
重点是什么?
Or am I still misunderstanding the right way to do this?还是我仍然误解了正确的方法?
Thanks for your help!谢谢你的帮助!
I had to manually set我不得不手动设置
logging.basicConfig(level=logging.INFO)
Example例子
import click
import logging
logging.basicConfig(level=logging.INFO)
@click.command()
def cli():
logging.info("it works")
gives给
$ mycli
INFO:root:it works
I personally like the loguru
library for handling logs.我个人喜欢处理日志的
loguru
库。 I think it's simpler.我认为它更简单。
Here's an example of how I usually do it:这是我通常如何做的一个例子:
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 Loguru: https://github.com/Delgan/loguru
I was looking to get logs when a click handler is called (command name and parameters).我希望在调用单击处理程序时获取日志(命令名和参数)。 I end up with this snippet:
我最终得到了这个片段:
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()
It gives you the following output:它为您提供以下 output:
python test_click.py --count 3
Your name: ok
INFO:__main__:hello(**{'count': 3, 'name': 'ok'})
Hello ok!
Hello ok!
Hello ok!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.