在python中,为什么要使用日志记录而不是print?

问题:在python中,为什么要使用日志记录而不是print?

对于复杂项目中的简单调试,是否有理由使用python记录器而不是print?那其他用例呢?是否每个都有一个公认的最佳用例(尤其是在您仅查找标准输出时)?

我一直都听说这是“最佳实践”,但我一直无法弄清原因。

For simple debugging in a complex project is there a reason to use the python logger instead of print? What about other use-cases? Is there an accepted best use-case for each (especially when you’re only looking for stdout)?

I’ve always heard that this is a “best practice” but I haven’t been able to figure out why.


回答 0

日志记录程序包具有许多有用的功能:

  • 易于查看从何处以及何时(即使是哪一行)进行记录调用。
  • 您可以同时登录文件,套接字,几乎所有内容。
  • 您可以根据严重性区分日志记录。

印刷没有这些。

另外,如果您的项目打算由其他python工具导入,则对于您的包来说,将内容打印到stdout是不好的做法,因为用户很可能不知道打印消息的来源。使用日志记录,包的用户可以选择是否要传播您工具中的日志记录消息。

The logging package has a lot of useful features:

  • Easy to see where and when (even what line no.) a logging call is being made from.
  • You can log to files, sockets, pretty much anything, all at the same time.
  • You can differentiate your logging based on severity.

Print doesn’t have any of these.

Also, if your project is meant to be imported by other python tools, it’s bad practice for your package to print things to stdout, since the user likely won’t know where the print messages are coming from. With logging, users of your package can choose whether or not they want to propogate logging messages from your tool or not.


回答 1

正确记录的最大优点之一是您可以对消息进行分类,然后根据需要将其打开或关闭。例如,为项目的某个部分打开调试级别的消息,而为其他部分调低调试级别的消息,这样可能会很有用,以免被信息过载所取代,并轻松地专注于您需要执行的任务记录。

另外,日志是可配置的。您可以轻松地对其进行过滤,将其发送到文件,对其进行格式化,添加时间戳以及在全球范围内可能需要的任何其他事项。打印报表不容易管理。

One of the biggest advantages of proper logging is that you can categorize messages and turn them on or off depending on what you need. For example, it might be useful to turn on debugging level messages for a certain part of the project, but tone it down for other parts, so as not to be taken over by information overload and to easily concentrate on the task for which you need logging.

Also, logs are configurable. You can easily filter them, send them to files, format them, add timestamps, and any other things you might need on a global basis. Print statements are not easily managed.


回答 2

打印语句将在线调试器的负面影响与诊断工具结合在一起,是两全其美的方式。您必须修改程序,但无法从中获得更多有用的代码

在线调试器使您可以检查正在运行的程序的状态。但是真正的调试器的好处是您不必修改源代码。调试会话之前或之后;您只需将程序加载到调试器中,告诉调试器您要查找的位置,便一切就绪。

对应用程序进行检测可能需要先进行一些工作,以某种方式修改源代码,但是生成的诊断输出可能具有大量详细信息,并且可以在非常特定的程度上打开或关闭。python日志记录模块不仅可以显示记录的消息,还可以显示调用该消息的文件和函数,是否有回溯,是否发出了消息的实际时间等等。比那更多的; 诊断仪器永远不需要拆除;当程序完成并投入生产时,它与添加之日一样有效和有用。但是它可以将其输出卡在一个日志文件中,在该文件中它不会惹恼任何人,或者可以将日志级别调低以将所有最紧急的消息拒之门外。

真正比在测试时使用ipython更加容易,并且可以预测调试器的需求或用途,并且熟悉其用于控制​​内置pdb调试器的命令。

当您发现自己认为打印语句可能比使用pdb容易(通常如此)时,您会发现使用记录器比使用并随后删除打印语句更容易使程序处于工作状态。 。

我将编辑器配置为突出显示打印语句为语法错误,并将记录语句突出为注释,因为这就是我如何看待它们。

Print statements are sort of the worst of both worlds, combining the negative aspects of an online debugger with diagnostic instrumentation. You have to modify the program but you don’t get more, useful code from it.

An online debugger allows you to inspect the state of a running program; But the nice thing about a real debugger is that you don’t have to modify the source; neither before nor after the debugging session; You just load the program into the debugger, tell the debugger where you want to look, and you’re all set.

Instrumenting the application might take some work up front, modifying the source code in some way, but the resulting diagnostic output can have enormous amounts of detail, and can be turned on or off to a very specific degree. The python logging module can show not just the message logged, but also the file and function that called it, a traceback if there was one, the actual time that the message was emitted, and so on. More than that; diagnostic instrumentation need never be removed; It’s just as valid and useful when the program is finished and in production as it was the day it was added; but it can have it’s output stuck in a log file where it’s not likely to annoy anyone, or the log level can be turned down to keep all but the most urgent messages out.

anticipating the need or use for a debugger is really no harder than using ipython while you’re testing, and becoming familiar with the commands it uses to control the built in pdb debugger.

When you find yourself thinking that a print statement might be easier than using pdb (as it often is), You’ll find that using a logger pulls your program in a much easier to work on state than if you use and later remove print statements.

I have my editor configured to highlight print statements as syntax errors, and logging statements as comments, since that’s about how I regard them.


回答 3

如果使用日志记录,则负责部署的人员可以配置记录器以将其与自定义信息一起发送到自定义位置。如果仅打印,则仅此而已。

If you use logging then the person responsible for deployment can configure the logger to send it to a custom location, with custom information. If you only print, then that’s all they get.


回答 4

日志记录实质上会创建一个具有其他元数据(时间戳,日志级别,行号,进程等)的可打印输出的可搜索纯文本数据库。

这是纯金,我可以在python脚本运行在日志文件上运行egrep 。我可以调整egrep模式搜索以准确选择我感兴趣的内容,而忽略其余内容。认知负担的减少和以后通过反复试验选择我的egrep模式的自由是我的主要好处。

tail -f mylogfile.log | egrep "key_word1|key_word2"

现在,抛出其他打印无法完成的很棒的事情(发送至套接字,设置调试级别,logrotate,添加元数据等),您有充分的理由偏爱于记录普通打印语句。

我倾向于使用打印语句,因为它既懒惰又容易,添加日志记录需要一些样板代码,嘿,我们有yasnippets(emacs)和ultisnips(vim)以及其他模板工具,所以为什么要放弃对普通打印语句的记录!

Logging essentially creates a searchable plain text database of print outputs with other meta data (timestamp, loglevel, line number, process etc.).

This is pure gold, I can run egrep over the log file after the python script has run. I can tune my egrep pattern search to pick exactly what I am interested in and ignore the rest. This reduction of cognitive load and freedom to pick my egrep pattern later on by trial and error is the key benefit for me.

tail -f mylogfile.log | egrep "key_word1|key_word2"

Now throw in other cool things that print can’t do (sending to socket, setting debug levels, logrotate, adding meta data etc.), you have every reason to prefer logging over plain print statements.

I tend to use print statements because it’s lazy and easy, adding logging needs some boiler plate code, hey we have yasnippets (emacs) and ultisnips (vim) and other templating tools, so why give up logging for plain print statements!?