python记录日志
Logging is a very important functionality for a programmer. For both debugging and displaying run-time information, logging is equally useful. In this article, I will present why and how you could use the python’s logging module in your programs.
日志记录对于程序员来说是非常重要的功能。 对于调试和显示运行时信息,日志记录同样有用。 在本文中,我将介绍为什么以及如何在程序中使用python的日志记录模块。
为什么要记录而不打印() (Why Logging and not print())
There is a key difference between a print statement and logging output. Usually, print statements write to stdout (standard output) which is expected to be the useful information or the output of the program. However, logs are written into stderr (standard error). We can demonstrate this scenario as follows.
打印语句和日志输出之间有一个关键区别。 通常,打印语句将写入stdout (标准输出),该stdout应该是有用的信息或程序的输出。 但是,日志被写入stderr (标准错误)。 我们可以演示这种情况,如下所示。
import logginglogging.basicConfig(level=logging.INFO) #We'll talk about this soon!logging.warning('Something bad could happen!')
logging.info('You are running the program')
logging.error('Aw snap! Everything failed.')print("This is the program output")
Now if I run this program, I will see the following in the command line.
现在,如果我运行此程序,我将在命令行中看到以下内容。
$ python log_test.py
WARNING:root:Something bad could happen!
INFO:root:You are running the program
ERROR:root:Aw snap! Everything failed.
This is the program output
However, for the usual user, the information is too much. Though this is actually displayed all together in the command line the data is written into two separate streams. So a typical user should do the following.
但是,对于普通用户而言,信息太多了。 尽管实际上在命令行中一起显示了这些数据,但数据被写入两个单独的流中。 因此,典型用户应执行以下操作。
$ python log_test.py > program_output.txt
WARNING:root:Something bad could happen!
INFO:root:You are running the program
ERROR:root:Aw snap! Everything failed.$ cat program_output.txt
This is the program output
Here the useful program output is written to a file, by redirection >
. So we can see what's happening on the terminal and get the output conveniently on a file. Now let’s try to understand the log levels!
在这里,有用的程序输出通过重定向>
写入文件。 这样我们就可以查看终端上发生的情况,并在文件中方便地获取输出。 现在,让我们尝试了解日志级别!
日志记录和日志级别 (Logging and Log Levels)
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/5836657427ddf8fd70bb610f13b1f230.png)
Logging can happen for different reasons. These reasons are separated into levels of severity as following.
日志记录可能由于不同的原因而发生。 这些原因分为以下严重性级别。
DEBUG: Debug information for developers such as computed values, estimated parameters, URLs, API calls, etc.
DEBUG :开发人员的调试信息,例如计算值,估计参数,URL,API调用等。
INFO: Information, nothing serious.
INFO :信息,没什么大不了的。
WARNING: Warnings to users about inputs, parameters, etc.
警告 :警告用户有关输入,参数等的信息。
ERROR: Reports an error caused by something that the user did or occurred within the program.
错误 :报告由用户在程序中执行或执行的操作引起的错误。
CRITICAL: The highest priority log output. Used for critical concerns (Depends on the use-case).
严重 :最高优先级的日志输出。 用于关键问题(取决于用例)。
The most common types of logs are DEBUG, INFO, and ERROR. However, you can easily end up with scenarios where python throws warnings for version mismatches.
日志的最常见类型是DEBUG , INFO和ERROR 。 但是,您很容易遇到python引发版本不匹配警告的情况。
配置记录器和日志处理程序 (Configuring the Logger and Log Handlers)
The loggers can be configured under different parameters. The logger can be configured to follow a particular log level, a file name, file mode, and a format to print the log output.
记录器可以配置为不同的参数。 可以将记录器配置为遵循特定的日志级别,文件名,文件模式以及打印日志输出的格式。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/1cae8133ad585b9218502ac59cc751e0.png)
配置记录器参数 (Configuring the Logger Parameters)
The logger can be configured as follows.
记录器可以配置如下。
import logging
logging.basicConfig(filename='program.log', filemode='w', level=logging.DEBUG)
logging.warning('You are given a warning!')
The above setting asks the logger to output the log into a file named program.log
. The filemode=’w’
defines the nature of writing to file. For example, 'w'
open a new file overwriting whatever that was there. By default, this parameter is 'a'
which will open the log file in append mode. Sometimes it is useful to have a log history. The level parameter defines the lowest severity for logging. For example, if you set this to INFO, DEBUG logs will not be printed. You may have seen programs needs to be run inverbose=debug
mode to see some parameters. By default the level is INFO.
上面的设置要求记录器将日志输出到名为program.log
的文件中。 filemode='w'
定义写入文件的性质。 例如, 'w'
打开一个新文件,覆盖那里的所有文件。 默认情况下,此参数为'a'
,它将以附加模式打开日志文件。 有时,拥有日志历史记录会很有用。 level参数定义最低的日志记录严重性。 例如,如果将其设置为INFO ,则不会打印DEBUG日志。 您可能已经看到程序需要以verbose=debug
模式运行才能看到一些参数。 默认情况下,级别为INFO 。
创建一个日志处理程序 (Creating a Log Handler)
Although the above approach is straightforward for a simple application we need a comprehensive logging process for a production-ready software or a service. This is because it might be quite difficult to find for a particular ERROR log amidst millions of DEBUG logs. Furthermore, we need to use a single logger throughout the program and modules. This way we’ll correctly append the logs to the same file. For this, we can use handlers with different configurations for this task.
尽管上述方法对于简单的应用程序很简单,但是我们需要用于生产就绪型软件或服务的全面日志记录过程。 这是因为在数百万个DEBUG日志中很难找到特定的ERROR日志。 此外,我们需要在整个程序和模块中使用单个记录器。 这样,我们可以将日志正确附加到同一文件中。 为此,我们可以为此任务使用具有不同配置的处理程序。
import logginglogger = logging.getLogger("My Logger")
logger.setLevel(logging.DEBUG)console_handler = logging.StreamHandler()
file_handler = logging.FileHandler('file.log', mode='w')
console_handler.setLevel(logging.INFO)
file_handler.setLevel(logging.DEBUG)logger.addHandler(console_handler)
logger.addHandler(file_handler)
You can see that we first get a logger passing a name. This enables us to reuse the same logger everywhere else in the program. We set the global logging level to be DEBUG. This is the lowest log level, hence enables us to use any log level in other handlers.
您可以看到,我们首先得到了一个记录器,传递了一个名称。 这使我们能够在程序的其他任何地方重用相同的记录器。 我们将全局日志记录级别设置为DEBUG 。 这是最低的日志级别,因此使我们能够在其他处理程序中使用任何日志级别。
Next, we create two handlers for console and file writing. For each handler, we provide a log level. This can help reduce the overhead on console output and transfer them to the file handler. Makes it easy to deal with debugs later.
接下来,我们为控制台和文件写入创建两个处理程序。 对于每个处理程序,我们提供一个日志级别。 这可以帮助减少控制台输出的开销,并将其传输到文件处理程序。 使以后处理调试变得容易。
格式化日志输出 (Formatting the Log Output)
Logging is not merely print our own message. Sometimes we need to print other information such as time, log level, and process ids. For this task, we can use log formatting. Let’s see the following code.
记录不仅仅是打印我们自己的消息。 有时我们需要打印其他信息,例如时间,日志级别和进程ID。 对于此任务,我们可以使用日志格式。 让我们看下面的代码。
console_format = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
file_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')console_handler.setFormatter(console_format)
file_handler.setFormatter(file_format)
Before we add handlers to the logger we can format the log outputs as above. There are many more parameters that you can use for this. You can find them all here.
在将处理程序添加到记录器之前,我们可以如上所述格式化日志输出。 您可以使用更多参数。 您可以在这里找到所有它们。
重用代码 (A Code for Reuse)
The following is a code snippet for logging that I continue to use in many of my applications. Thought it might be useful for you as the reader.
以下是用于日志记录的代码片段,我将继续在许多应用程序中使用它们。 认为它对您作为读者可能有用。
import logging
logger = logging.getLogger('Program Name-Version')
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
consoleHeader = logging.StreamHandler()
consoleHeader.setFormatter(formatter)
consoleHeader.setLevel(logging.INFO)
fileHandler = logging.FileHandler(f"{output}/metabcc-lr.log")
fileHandler.setLevel(logging.DEBUG)
fileHandler.setFormatter(formatter)
logger.addHandler(fileHandler)
logger.addHandler(consoleHeader)
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/96e7f73599f7ef62aa077e2e202a8ffa.png)
多线程登录 (Loggin with Multithreading)
The logging module is made with thread safety in mind. Hence no special action is required when you’re logging from different threads except very few exceptions (out of the main scope of this article).
日志记录模块的设计考虑到线程安全性。 因此,当您从不同的线程进行日志记录时,除了很少的例外情况(不在本文的主要范围之内)时,不需要采取特殊的措施。
I hope this is a simple but useful article for many budding programmers and engineers. The following are a few more python tutorials that you might like having a look at. Happy reading. Cheers! :-)
我希望这对许多新兴的程序员和工程师来说都是简单而有用的文章。 以下是您可能想要看的其他一些python教程。 祝您阅读愉快。 干杯! :-)
翻译自: https://levelup.gitconnected.com/tutorial-on-python-logging-ac5f21e0a00
python记录日志