python 日志模块中的 log_level 参数不会影响性能吗?
Doesn't log_level parameter in python logging module affect performance?
我正在使用 API 从我的项目中获取一些服务。 API 调用花费的时间太长,所以我认为原因之一可能是我在项目和 IO reads/writes 中放置的 很多日志 需要时间。
我正在使用 logging。我的猜测是 LOG_LEVEL 丢弃优先级较低的日志,优先级较高的 API 调用应该在更短的时间内完成。但时间几乎相同(差异在 1/10 秒的范围内)。
关于 LOG_LEVEL 和我从 here 获得的性能的唯一参考是
The beauty of this is that if you set the log level to WARN, info and debug messages have next to no performance impact.
这里需要注意的几点
我没有将我的日志配置为流式传输到任何日志服务,例如 Kibana。
我已经检查了 this 种情况,我没有在日志消息中做任何预处理。
我已经完成了基本的 Logger 初始化,即
import logging
logger = logging.getLogger(__name__)
和未使用任何文件来写入日志,如下所示。 LOG_LEVEL 作为环境变量之一给出。
logging.basicConfig(filename="file_name.log")
考虑到所有其他事情都是最优的(如果所有事情都不是最优的,那么优先级越高的日志应该花费更少的时间),我是不是因为日志read/writes而猜测更多时间是错误的?如果不是,那么为什么使用高优先级 LOG_LEVEL 标志没有减少时间?
日志记录模块在哪个默认位置存储日志?
日志级别性能有什么区别?
设置日志级别会影响性能,但在大规模之前可能不会很明显。
设置级别时,您正在创建一种方法来阻止日志记录过程继续进行,并且在使用任何单个日志检查之前几乎不会发生任何事情。例如,CRITICAL
日志在 code:
中的样子
if self.isEnabledFor(CRITICAL):
self._log(CRITICAL, msg, args, **kwargs)
作为 _log
的一部分,记录器本身要做的不仅仅是此检查,因此通过设置日志级别可以节省时间。但是,它是相当优化的,所以在你启动记录器的时候,除非调用量的差异非常大,否则你可能不会注意到它。
如果您删除了对日志记录的任何引用而不仅仅是设置级别,您将获得更多的性能提升,因为根本不会进行该检查(这显然需要一些时间)。
日志默认存储在哪里?
默认情况下,不设置文件,StreamHandler
[source] is enabled and without specifying a specific stream, it will stream to sys.stderr
. When you set a file, it creates a FileHandler
which inherits from the same functions as StreamHandlers [source]。
如何优化?
对于您没有提出的问题,即 我如何加速记录? 我建议您查看 this,其中提供了一些建议。该建议的一部分是我在上面指出的,但告诉您明确检查您的日志级别,您甚至可以缓存该结果并检查缓存,这应该会进一步减少时间。
查看 以了解有关优化日志记录的更多信息。
最后,如果您想确定代码的速度问题,无论是否来自日志记录,您都需要使用分析器。 Python 中有内置分析功能,检查 here。
一个日志级别的性能并不比另一个更高,但是,如果为日志记录启用了一个级别,则记录器是嵌套的(在您的示例中,如果 __name__
中有点,例如 mypackage.core.logs
), Python你的版本运行即可。这是因为当您进行日志记录调用时会发生三件事:
记录器确定是否启用日志记录级别。
每次通话都会发生这种情况。在 3.7 之前的 Python 版本中,此调用未被缓存,嵌套记录器需要更长的时间来确定它们是否已启用。还有多久?在一些基准测试中,它是两倍的时间。也就是说,这在很大程度上依赖于日志嵌套,即使记录数百万条消息,这也只能节省几秒钟的系统时间。
记录器处理记录。
这就是概述的优化 in the documentation 发挥作用的地方。它们允许记录创建跳过一些步骤。
记录器将记录发送给处理程序。
这可能是默认值,StreamHandler, the FileHandler, the SysLogHandler, or any number of build-in or custom handlers. In your example, you are using the FileHandler 写入当前目录中的 file_name.log
。这可能适用于较小的应用程序,较大的应用程序将受益于使用外部记录器,如 syslog 或 systemd 日志。这样做的主要原因是因为它们在单独的进程中运行,并且针对处理大量日志进行了优化。
我正在使用 API 从我的项目中获取一些服务。 API 调用花费的时间太长,所以我认为原因之一可能是我在项目和 IO reads/writes 中放置的 很多日志 需要时间。
我正在使用 logging。我的猜测是 LOG_LEVEL 丢弃优先级较低的日志,优先级较高的 API 调用应该在更短的时间内完成。但时间几乎相同(差异在 1/10 秒的范围内)。
关于 LOG_LEVEL 和我从 here 获得的性能的唯一参考是
The beauty of this is that if you set the log level to WARN, info and debug messages have next to no performance impact.
这里需要注意的几点
我没有将我的日志配置为流式传输到任何日志服务,例如 Kibana。
我已经检查了 this 种情况,我没有在日志消息中做任何预处理。
我已经完成了基本的 Logger 初始化,即
import logging
logger = logging.getLogger(__name__)
和未使用任何文件来写入日志,如下所示。 LOG_LEVEL 作为环境变量之一给出。
logging.basicConfig(filename="file_name.log")
考虑到所有其他事情都是最优的(如果所有事情都不是最优的,那么优先级越高的日志应该花费更少的时间),我是不是因为日志read/writes而猜测更多时间是错误的?如果不是,那么为什么使用高优先级 LOG_LEVEL 标志没有减少时间?
日志记录模块在哪个默认位置存储日志?
日志级别性能有什么区别?
设置日志级别会影响性能,但在大规模之前可能不会很明显。
设置级别时,您正在创建一种方法来阻止日志记录过程继续进行,并且在使用任何单个日志检查之前几乎不会发生任何事情。例如,CRITICAL
日志在 code:
if self.isEnabledFor(CRITICAL):
self._log(CRITICAL, msg, args, **kwargs)
作为 _log
的一部分,记录器本身要做的不仅仅是此检查,因此通过设置日志级别可以节省时间。但是,它是相当优化的,所以在你启动记录器的时候,除非调用量的差异非常大,否则你可能不会注意到它。
如果您删除了对日志记录的任何引用而不仅仅是设置级别,您将获得更多的性能提升,因为根本不会进行该检查(这显然需要一些时间)。
日志默认存储在哪里?
默认情况下,不设置文件,StreamHandler
[source] is enabled and without specifying a specific stream, it will stream to sys.stderr
. When you set a file, it creates a FileHandler
which inherits from the same functions as StreamHandlers [source]。
如何优化?
对于您没有提出的问题,即 我如何加速记录? 我建议您查看 this,其中提供了一些建议。该建议的一部分是我在上面指出的,但告诉您明确检查您的日志级别,您甚至可以缓存该结果并检查缓存,这应该会进一步减少时间。
查看
最后,如果您想确定代码的速度问题,无论是否来自日志记录,您都需要使用分析器。 Python 中有内置分析功能,检查 here。
一个日志级别的性能并不比另一个更高,但是,如果为日志记录启用了一个级别,则记录器是嵌套的(在您的示例中,如果 __name__
中有点,例如 mypackage.core.logs
), Python你的版本运行即可。这是因为当您进行日志记录调用时会发生三件事:
记录器确定是否启用日志记录级别。
每次通话都会发生这种情况。在 3.7 之前的 Python 版本中,此调用未被缓存,嵌套记录器需要更长的时间来确定它们是否已启用。还有多久?在一些基准测试中,它是两倍的时间。也就是说,这在很大程度上依赖于日志嵌套,即使记录数百万条消息,这也只能节省几秒钟的系统时间。
记录器处理记录。
这就是概述的优化 in the documentation 发挥作用的地方。它们允许记录创建跳过一些步骤。
记录器将记录发送给处理程序。
这可能是默认值,StreamHandler, the FileHandler, the SysLogHandler, or any number of build-in or custom handlers. In your example, you are using the FileHandler 写入当前目录中的
file_name.log
。这可能适用于较小的应用程序,较大的应用程序将受益于使用外部记录器,如 syslog 或 systemd 日志。这样做的主要原因是因为它们在单独的进程中运行,并且针对处理大量日志进行了优化。