python日志记录
To start, logging is a way of tracking events in a program when it runs and is in execution. Python logging module defines functions and classes that provide a flexible event logging system for python applications.
首先,日志记录是一种在程序运行和执行时跟踪其事件的方法。 Python日志记录模块定义了为python应用程序提供灵活的事件日志记录系统的函数和类 。
Logging information while events happen is a handy task which helps to see the pattern in which our program executes, what data it acted upon and what results it returned and all this is done without affecting the actual state of the program.
在事件发生时记录信息是一项方便的任务,它有助于查看程序的执行模式,所作用的数据以及返回的结果,并且所有这些操作都不会影响程序的实际状态。
Note that the logs are only for developers (usually) and they can be visualized using many tools. Let’s look into different aspects of python logging module now.
请注意,这些日志通常仅适用于开发人员,并且可以使用许多工具进行可视化。 现在让我们研究python日志记录模块的不同方面。
Each log message is assigned a level of severity. Broadly speaking, there are following python logging levels:
每个日志消息都分配有一个严重性级别。 概括地说,有以下python日志记录级别:
More or less they are very similar to java log4j logging framework.
它们或多或少与Java log4j日志记录框架非常相似。
Let’s look at different ways we can use python logging module to log messages.
让我们看看可以使用python日志记录模块记录消息的不同方式。
The simplest form of logging occurs in form of only String messages. Let’s quickly look at an example code snippet:
最简单的日志记录形式只有字符串消息形式。 让我们快速看一下示例代码片段:
import logging
logging.warning("Warning log.")
logging.info("Info log.")
The output will be:
输出将是:
Do you wonder why only the warning level log appeared in the console? This is because the default level of logging is WARNING
.
您是否想知道为什么只有警告级别日志出现在控制台中? 这是因为默认的日志记录级别是WARNING
。
Console logging is quite clear but what if we want to search through the logs after a day or a week? Won’t it be better if the logs were just collected at a single place where we can run simple text operations? Actually, we can log our messages to a file instead of a console.
控制台日志记录非常清楚,但是如果我们想在一天或一周后搜索日志,该怎么办? 如果仅将日志收集在一个我们可以运行简单文本操作的地方会更好吗? 实际上,我们可以将消息记录到文件而不是控制台中。
Let’s modify our script to do the necessary configuration:
让我们修改脚本以进行必要的配置:
import logging
# Configure file
logging.basicConfig(filename = 'my_logs.log', level = logging.DEBUG)
logging.warning("Warning log.")
logging.info("Info log.")
logging.debug("Debug log.")
When we run this script, we will not get back any output as all the logging is done in the file which is made by the script itself. Its content looks like:
当我们运行该脚本时,由于所有日志记录都在脚本本身创建的文件中完成,因此我们将不会获得任何输出。 其内容如下:
WARNING:root:Warning log.
INFO:root:Info log.
DEBUG:root:Debug log.
As we also used the log level as Debug, all the levels of logs are present in the file.
由于我们还将日志级别用作“调试”,因此所有级别的日志都存在于文件中。
In our last example, we wrote a simple script to log messages in a file. Now, go on and run the same script again and again. You’ll notice that the file is appended with messages and new logs are added to last content. This is the default behavior of the logging module.
在最后一个示例中,我们编写了一个简单的脚本将消息记录在文件中。 现在,继续并一次又一次地运行相同的脚本。 您会注意到该文件附加了消息,并且新日志已添加到最后一个内容。 这是日志记录模块的默认行为。
To modify this so that the messages are included as a fresh file, make slight changes in the configuration as:
要对此进行修改,以使消息作为新文件包含在内,请对配置进行一些小的更改,如下所示:
import logging
# Configure file
logging.basicConfig(filename = 'my_logs.log', filemode='w', level = logging.DEBUG)
logging.warning("Warning log.")
logging.info("Info log.")
logging.debug("Debug log.")
We just added a new attribute as filemode
. Now, run the script multiple times:
我们刚刚添加了一个新属性作为filemode
。 现在,多次运行脚本:
The content of the log file now looks like:
现在,日志文件的内容如下所示:
WARNING:root:Warning log.
INFO:root:Info log.
DEBUG:root:Debug log.
So, the messages are present as only fresh messages.
因此,消息仅作为新消息出现。
Of course, the format of current logs is, strange! We will try to clean our messages and put some formatting. Fortunately, it is just a matter of a single line configuration. Let’s quickly look at python logging format example:
当然,当前日志的格式很奇怪! 我们将尝试清除消息并放入一些格式。 幸运的是,这只是单线配置的问题。 让我们快速看一下python日志记录格式示例:
import logging
# Configure file
logging.basicConfig(filename='my_logs.log', filemode='w',
format='%(levelname)s: %(message)s', level=logging.DEBUG)
logging.warning("Warning log.")
logging.info("Info log.")
logging.debug("Debug log.")
Now in this case, the content of the log file looks like:
现在,在这种情况下,日志文件的内容如下所示:
WARNING: Warning log.
INFO: Info log.
DEBUG: Debug log.
Much cleaner, right?
清洁得多吧?
The log messages would make a lot of sense in real scenarios when we know when did an event actually occurred! We will try to provide date and timestamp to our messages. Again, it is just a matter of a single line configuration. Let’s quickly look at an example code snippet:
当我们知道事件实际发生的时间时,在实际情况下,日志消息会很有用! 我们将尝试为我们的消息提供日期和时间戳。 同样,这只是单线配置的问题。 让我们快速看一下示例代码片段:
import logging
# Configure file
logging.basicConfig(filename='my_logs.log', filemode='w',
format='%(levelname)s -> %(asctime)s: %(message)s', level=logging.DEBUG)
logging.warning("Warning log.")
logging.info("Info log.")
logging.debug("Debug log.")
We only added a single attribute as asctime
. Now in this case, the content of the log file looks like:
我们只添加了一个属性asctime
。 现在,在这种情况下,日志文件的内容如下所示:
WARNING -> 2017-12-09 12:56:25,069: Warning log.
INFO -> 2017-12-09 12:56:25,069: Info log.
DEBUG -> 2017-12-09 12:56:25,069: Debug log.
Making much more sense now.
现在变得更加有意义。
Now, we were making a direct use of logging module. Why not just get an object and use it to log messages. Let’s quickly look at an example code snippet:
现在,我们直接使用了日志记录模块。 为什么不只是获取一个对象并使用它来记录消息。 让我们快速看一下示例代码片段:
import logging
# Configure file
logging.basicConfig(filename='my_logs.log', filemode='w',
format='%(levelname)s -> %(asctime)s: %(message)s', level=logging.DEBUG)
logger = logging.getLogger(__name__)
logger.info("Using custom logger.")
shubham = {'name': 'Shubham', 'roll': 123}
logger.debug("Shubham: %s", shubham)
We only added a call to getLogger
. Now in this case, the content of the log file looks like:
我们只添加了对getLogger
的调用。 现在,在这种情况下,日志文件的内容如下所示:
INFO -> 2017-12-09 13:14:50,276: Using custom logger.
DEBUG -> 2017-12-09 13:14:50,276: Shubham: {'name': 'Shubham', 'roll': 123}
Clearly, we can log variables values as well. This will help including much more information in log messages about current state of the program.
显然,我们也可以记录变量值。 这将有助于在日志消息中包含有关程序当前状态的更多信息。
Now, it is a tedious process to provide same logging information in multiple files. What we can do is, we can centralise our configuration into a single place so that whenever we need to make any change, it is needed at a single place only.
现在,在多个文件中提供相同的日志记录信息是一个繁琐的过程。 我们可以做的是,我们可以将配置集中到一个地方,这样,无论何时需要进行任何更改,都只需在一个地方进行。
We can do this by creating a config file as shown:
我们可以通过创建一个配置文件来做到这一点,如下所示:
[loggers]
keys=root,JournalDev
[handlers]
keys=fileHandler, consoleHandler
[formatters]
keys=myFormatter
[logger_root]
level=CRITICAL
handlers=consoleHandler
[logger_JournalDev]
level=INFO
handlers=fileHandler
qualname=JournalDev
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=myFormatter
args=(sys.stdout,)
[handler_fileHandler]
class=FileHandler
formatter=myFormatter
args=("external_file.log",)
[formatter_myFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=
This way, we configured root and a JournalDev logger, provided a logger to both of these along with Handlers and a format. Now, we can make use of this logger file in our script:
这样,我们配置了root和JournalDev记录器,为这两个记录器以及Handlers和格式提供了记录器。 现在,我们可以在脚本中使用此记录器文件:
import logging
import logging.config
logging.config.fileConfig('logging.conf')
logger = logging.getLogger("JournalDev")
logger.info("Custom logging started.")
logger.info("Complete!")
As we configured two loggers in the file, we will see this output on the console as well:
当我们在文件中配置了两个记录器时,我们还将在控制台上看到以下输出:
These logs will be present in a file named external_file.log
as well:
这些日志也将出现在名为external_file.log
的文件中:
2017-12-09 13:52:49,889 - JournalDev - INFO - Custom logging started.
2017-12-09 13:52:49,889 - JournalDev - INFO - Complete!
This way, we can keep the logging configuration completely separate.
这样,我们可以使日志记录配置完全独立。
In this lesson, we learned about various functions provided by python logging module and saw how they work.
在本课程中,我们学习了python日志记录模块提供的各种功能,并了解了它们如何工作。
Reference: API Doc
参考: API文档
翻译自: https://www.journaldev.com/17431/python-logging
python日志记录