百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

[编程基础] Python日志记录库logging总结

off999 2025-09-12 01:25 20 浏览 0 评论


Python日志记录教程展示了如何使用日志记录模块在Python中进行日志记录。

文章目录

  • 1 介绍
  • 1.1 背景
  • 1.2 Python日志记录模块
  • 1.3 根记录器
  • 2 Python logging模块使用教程
  • 2.1 Python logging模块简单使用
  • 2.2 Python有效日志记录级别
  • 2.3 Python有效日志记录级别
  • 2.4 Python记录处理程序
  • 2.5 Python记录格式化程序
  • 2.6 Python日志基本配置
  • 2.7 Python日志记录文件配置
  • 2.8 Python日志记录变量
  • 2.9 Python日志记录格式日期时间
  • 2.10 Python日志记录堆栈跟踪
  • 2.11 Python记录getLogger
  • 3 参考

1 介绍

1.1 背景

日志记录是将信息写入日志文件的过程。日志文件包含有关在操作系统,软件或通信中发生的各种事件的信息。完成记录是出于以下目的:

  • 信息收集
  • 故障排除
  • 产生统计资料
  • 审计
  • 剖析

记录不仅限于识别软件开发中的错误。它还可用于检测安全事件,监视策略违规,在出现问题时提供信息,查找应用程序瓶颈或生成使用情况数据。应记录的事件包括输入验证失败,身份验证和授权失败,应用程序错误,配置更改以及应用程序启动和关闭。
但是不应记录的事件包括应用程序源代码,会话标识值,访问令牌,敏感的个人数据,密码,数据库连接字符串,加密密钥,银行帐户和持卡人数据。
综上所述,进行日志记录的一些最佳做法:

  • 日志记录应该有意义。
  • 日志应包含上下文。
  • 日志记录应在不同级别进行结构化和完成。
  • 日志记录应该是平衡的;它不应该包含太少或太多的信息。
  • 记录消息应该是人类可以理解的,并且可以被机器解析。
  • 登录更复杂的应用程序应完成几个日志文件。
  • 日志应适应开发和生产。

1.2 Python日志记录模块

Python日志模块定义了一些函数和类,这些函数和类为应用程序和库实现了一个灵活的事件日志系统。
日志记录模块具有四个主要组件:记录器(loggers),处理程序(handlers),过滤器(filters)和格式化程序(formatters)。记录器公开了应用程序代码直接使用的接口。处理程序将日志记录(由记录器创建)发送到适当的目的地。筛选器提供了更细粒度的功能,用于确定要输出的日志记录。格式化程序在最终输出中指定日志记录的布局。
Python日志记录级别主要有以下六个:

  • CRITICAL 危急
  • ERROR 错误
  • WARNING 警告
  • INFO 信息
  • DEBUG 调试
  • NOTSET 无设置

要注意日志等级是从上到下依次降低的,即:NOTEST< DEBUG < INFO < WARNING < ERROR < CRITICAL,而日志的信息量是依次减少的;
如果日志记录级别设置为WARNING,所有的WARNING, ERROR以及CRITICAL消息被写入日志文件或控制台。如果它被设置为ERROR,只有ERROR和 CRITICAL消息被记录。

日志记录器具有有效等级的概念。如果未在记录器上显式设置级别,则将其父级别用作其有效级别。如果父级没有显式设置的级别,则检查其父级,依此类推-搜索所有祖先,直到找到显式设置的级别。使用getLogger()创建记录器时,级别设置为NOTSET。如果未使用set level()显式设置日志记录级别,则消息将传播到日志记录父级。在找到级别不是NOTSET的祖先或到达根记录器之前,将遍历日志记录器的祖先链。根记录器设置了默认警告级别。

1.3 根记录器

所有记录器都是根记录器的后代。每个记录器将日志消息传递到其父级。使用该getLogger(name) 方法创建新的记录器。调用不带名称的函数(getLogger())将返回root记录器。根记录器始终具有显式级别集,WARNING 默认情况下为该级别。
根记录器位于层次结构的顶部,并且始终存在,即使未配置。通常,程序或库不应直接针对根日志记录器进行日志记录。相反,应该为程序配置一个特定的记录器。根日志可以用来轻松地打开和关闭所有库中的所有日志。

2 Python logging模块使用教程

python logging模块通常可以直接调用,无需安装

2.1 Python logging模块简单使用

该logging模块具有简单的方法,无需任何配置即可立即使用。这可以用于简单的日志记录。以下示例调用该logging模块的五个方法。消息将写入控制台。请注意,使用了根记录器,并且只写入了三则消息。这是因为默认情况下,仅写入具有级别警告和更高级别的消息。

import logging

logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')
WARNING:root:This is a warning message
ERROR:root:This is an error message
CRITICAL:root:This is a critical message

2.2 Python有效日志记录级别

日志记录级别是用set level()设置的。它将此记录器的阈值设置为lvl。将忽略严重程度低于lvl的日志消息。在下面示例中,我们将日志记录级别更改为DEBUG。

getLogger()返回具有指定名称的记录器。如果name为None,则返回根记录器。名称可以是定义日志层次结构的点分隔字符串;例如“a”、“a.b”或“a.b.c”。

import logging

# getLogger()返回具有指定名称的记录器。如果name为None,则返回根记录器。
logger = logging.getLogger('dev')
# 设置debug级别
logger.setLevel(logging.DEBUG)

logger.debug('This is a debug message')
logger.info('This is an info message')
logger.warning('This is a warning message')
logger.error('This is an error message')
logger.critical('This is a critical message')
DEBUG:dev:This is a debug message
INFO:dev:This is an info message
WARNING:dev:This is a warning message
ERROR:dev:This is an error message
CRITICAL:dev:This is a critical message

2.3 Python有效日志记录级别

有效日志记录级别是显式设置的级别或由日志记录父级确定的级别。每一个日志级别都有与之对应的一个阈值,如果日志级别对应的阈值小于设定值,就不会显示出来。各级别阈值为:

  • CRITICAL = 50
  • ERROR = 40
  • WARNING = 30
  • INFO = 20
  • DEBUG = 10
  • NOTSET = 0

以下示例中,我们检查了两个记录器的有效记录级别。

import logging


main_logger = logging.getLogger('main')
# 设定级别
main_logger.setLevel(logging.ERROR)

# 未设置dev_logger的级别;然后使用其父级的级别。
dev_logger = logging.getLogger()

print(main_logger.getEffectiveLevel())
print(dev_logger.getEffectiveLevel())
40
30

2.4 Python记录处理程序

处理程序是一个对象,负责将适当的日志消息(基于日志消息的严重性)分派到处理程序的指定目标。处理程序像级别一样设定。如果记录器没有处理程序集,则其父记录器将搜索处理程序。

以下示例为记录器创建了两个处理程序:文件处理程序和控制台处理程序。

import logging

logger = logging.getLogger('dev')
logger.setLevel(logging.INFO)

# 文件处理
# FileHandler将日志记录发送到test.log 文件。
fileHandler = logging.FileHandler('test.log')
fileHandler.setLevel(logging.INFO)

# 控制台处理
# StreamHandler将日志记录发送到流。如果未指定控制流,r则使用sys.stder。
consoleHandler = logging.StreamHandler()
consoleHandler.setLevel(logging.INFO)

# 将处理程序添加到记录器addHandler()。
logger.addHandler(fileHandler)
logger.addHandler(consoleHandler)

# 打印数据,并且保存数据
logger.info('information message')
information message
INFO:dev:information message

注意上面的程序在添加到记录器必须移除处理程序(这是这个大坑),不然会重复输出,因为会把当前logger和其父节点所有数据输出,如下所示:

import logging

logger = logging.getLogger('dev')
logger.setLevel(logging.INFO)

# 文件处理
# FileHandler将日志记录发送到test.log 文件。
fileHandler = logging.FileHandler('test.log')
fileHandler.setLevel(logging.INFO)

# 控制台处理
# StreamHandler将日志记录发送到流。如果未指定控制流,r则使用sys.stder。
consoleHandler = logging.StreamHandler()
consoleHandler.setLevel(logging.INFO)

# 将处理程序添加到记录器addHandler()。
logger.addHandler(fileHandler)
logger.addHandler(consoleHandler)

# 打印数据,并且保存数据
logger.info('information message')
information message
information message
INFO:dev:information message

解决办法在记录日志之后通过removeHandler移除处理函数


import logging

logger = logging.getLogger('dev')
logger.setLevel(logging.INFO)

# 文件处理
# FileHandler将日志记录发送到test.log 文件。
fileHandler = logging.FileHandler('test.log')
fileHandler.setLevel(logging.INFO)

# 控制台处理
# StreamHandler将日志记录发送到流。如果未指定控制流,r则使用sys.stder。
consoleHandler = logging.StreamHandler()
consoleHandler.setLevel(logging.INFO)

# 将处理程序添加到记录器addHandler()。
logger.addHandler(fileHandler)
logger.addHandler(consoleHandler)

# 打印数据,并且保存数据
logger.info('information message')

# 移除处理函数
logger.removeHandler(fileHandler)
logger.removeHandler(consoleHandler)

# 关闭处理函数
# 不然文件无法删除
# 返回输出只有三个information message输出
fileHandler.close();
consoleHandler.close();
information message
information message
information message
INFO:dev:information message

2.5 Python记录格式化程序

格式化程序是配置日志记录的最终顺序、结构和内容的对象。除了消息字符串之外,日志记录还包括日期和时间、日志名称和日志级别的严重性。下面示例创建一个控制台记录器,并向其处理程序添加格式化程序。

import logging

logger = logging.getLogger('devs')
logger.setLevel(logging.INFO)

consoleHandler = logging.StreamHandler()
consoleHandler.setLevel(logging.INFO)

logger.addHandler(consoleHandler)

# 创建格式化程序。它包括日期时间,记录器名称,记录级别名称和记录消息。
formatter = logging.Formatter('%(asctime)s  %(name)s  %(levelname)s: %(message)s')
consoleHandler.setFormatter(formatter)

logger.info('information message')

logger.removeHandler(consoleHandler)
consoleHandler.close;
2020-06-23 22:57:06,591  devs  INFO: information message
INFO:devs:information message

2.6 Python日志基本配置

basicConfig()配置根记录器。它通过使用默认格式化程序创建流处理程序来完成日志系统的基本配置。如果没有为根记录器定义处理程序,则debug()、info()、warning()、error()和critical()将自动调用basicConfig()。

以下示例使用basicConfig来配置根记录器。

import logging

# filename保存日志,format格式化输出,level设定消息等级
# 运行该程序后,我们在test.log文件中写入了五条消息 。
logging.basicConfig(filename='test.log', format='%(filename)s: %(message)s',
                    level=logging.DEBUG)

logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')
WARNING:root:This is a warning message
ERROR:root:This is an error message
CRITICAL:root:This is a critical message

2.7 Python日志记录文件配置

fileConfig()从configparser格式文件读取日志配置。本文在log.conf定义了一个记录器,处理程序和格式化。

log.conf文件内容如下:

[loggers]
keys=root,dev

[handlers]
keys=consoleHandler

[formatters]
keys=extend,simple

[logger_root]
level=INFO
handlers=consoleHandler

[logger_dev]
level=INFO
handlers=consoleHandler
qualname=dev
propagate=0

[handler_consoleHandler]
class=StreamHandler
level=INFO
formatter=extend
args=(sys.stdout,)

[formatter_extend]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s

[formatter_simple]
format=%(asctime)s - %(message)s

以下示例从log.conf中读取日志记录配置文件。

import logging
import logging.config

logging.config.fileConfig(fname='log.conf')

logger = logging.getLogger('dev')
logger.info('This is an information message')
2020-06-23 22:57:06,617 - dev - INFO - This is an information message

2.8 Python日志记录变量

通过使用字符串格式记录动态数据。以下示例将自定义数据写入日志消息。

import logging

root = logging.getLogger()
root.setLevel(logging.INFO)

log_format = '%(asctime)s %(filename)s: %(message)s'
logging.basicConfig(filename="test.log", format=log_format)

# incident happens
# 将自定义数据写入日志消息。
error_message = 'authentication failed'

root.error(f'error: {error_message}')
2020-06-23 22:57:06,624 - root - ERROR - error: authentication failed

2.9 Python日志记录格式日期时间

日期时间包含在带有asctime日志记录的日志消息中。使用datefmt配置选项,我们可以格式化datetime字符串。以下示格式化日志消息的日期时间。

import logging

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)



log_format = '%(asctime)s %(filename)s: %(message)s'
logging.basicConfig(filename="test.log", format=log_format,
                    datefmt='%Y-%m-%d %H:%M:%S')

logger.info("information message")
2020-06-23 22:57:06,631 - root - INFO - information message

2.10 Python日志记录堆栈跟踪

堆栈跟踪是调用函数的堆栈,这些函数一直运行到引发异常时为止。堆栈跟踪包含在exc_info选项中。
以下示例中,我们记录了尝试访问不存在的列表索引时引发的异常。

import logging

log_format = '%(asctime)s %(filename)s: %(message)s'
logging.basicConfig(filename="test.log", format=log_format)

vals = [1, 2]

try:
    print(vals[4])

except Exception as e:
    # 通过将exc_info设置为True,堆栈跟踪将包含在日志中。
    logging.error("exception occurred", exc_info=True)
2020-06-23 22:57:06,638 - root - ERROR - exception occurred
Traceback (most recent call last):
  File "<ipython-input-12-ef7fe4bd5d82>", line 9, in <module>
    print(vals[4])
IndexError: list index out of range

2.11 Python记录getLogger

在getLogger()返回具有指定名称的记录器。如果未指定名称,则返回根记录器。通常的做法是将模块名称放在其中。

使用给定名称对此函数的所有调用都返回相同的记录器实例。这意味着记录器实例不需要在应用程序的不同部分之间传递(这一点很坑)。

以下示例使用getLogger()创建一个新的记录器。它有一个文件处理程序和一个格式化程序

import logging
import sys

main = logging.getLogger('main')
main.setLevel(logging.DEBUG)

# 消息将被写入 my.log文件
handler = logging.FileHandler('my.log')

format = logging.Formatter('%(asctime)s  %(name)s %(levelname)s: %(message)s')
handler.setFormatter(format)

main.addHandler(handler)

main.info('info message')
main.critical('critical message')
main.debug('debug message')
main.warning('warning message')
main.error('error message')

# 清除数据
main.removeHandler(handler)
handler.close();

my.log中内容如下:

2020-06-23 22:54:41,265  main    INFO: info message
2020-06-23 22:54:41,265  main    CRITICAL: critical message
2020-06-23 22:54:41,265  main    DEBUG: debug message
2020-06-23 22:54:41,265  main    WARNING: warning message
2020-06-23 22:54:41,265  main    ERROR: error message

3 参考

http://zetcode.com/python/logging/


相关推荐

笔记本windows8系统下载(笔记本电脑系统win8)

在电脑上面就可以下载,打开浏览器搜索windous8系统会出现一些下拉选择,选择第一条或者选择有官网字样的,就直接有下载按钮,然后点击下载就可以了win8可以支持现在可以见到的所有Photosho...

win 11(win 11 25h2)

 Windows11是由微软公司(Microsoft)开发的操作系统,应用于计算机和平板电脑等设备。于2021年6月24日发布,2021年10月5日发行。Windows11提供了许多创新...

手机视频恢复软件免费版下载

手机视频删了怎么恢复  一、安卓手机视频恢复  1.打开电脑,移动鼠标,进入互盾安卓恢复大师官网,下载并安装该软件。手机连接至电脑。手机视频删了怎么恢复  2.打开运行互盾安卓恢复大师,在软件界面看到...

diy电脑装机教程(diy电脑组装步骤)

1,看价格。根据自己的预算价格,选择适合该价格的电脑。注意不要以过高的价格买到配置过低的电脑;2,看性能。根据自己需要的电脑性能,以合理的价格购买。注意不要以过高的价格买到配置过低的电脑。电脑的配置如...

u盘莫名其妙要格式化(u盘总是要格式化什么意思)

如果您在使用U盘时突然收到提示需要格式化的消息,这可能是由于以下原因之一引起的:U盘感染病毒:U盘中可能存在恶意病毒,这些病毒可能会导致U盘无法正常使用。当您尝试打开U盘时,系统会提示您进行格式化操作...

win7家庭版原版(win7家庭版价格)

你的win7旗舰版应该是个盗版软件,在你使用的过程中你可能触碰到了后台升级,升级完以后就变成了家庭版了,在你不知不觉中被改变的,厄这个软件属于盗版的,厄升级完以后没什么大区别,这个旗舰版家庭版在家里面...

win10自动更新失败怎么办(win10自动升级失败)

安装更新失败有许多原因。WindowsUpdate需要能够扫描您的计算机以了解需要哪些更新,并能够下载和安装这些更新。如果某个阶段遇到问题,则可能阻止某个更新安装到计算机中。有关错误或失败的详细信...

截图的几种方法(截图的几种方法有哪些)

 第一种截图方式:按printScreen键。按一下键盘上的printScreen键以后,整个屏幕会被截取下来,截图会默认保存在剪贴板中。第二种截图方式:使用微信截图。进入聊天界面,我们会发...

电脑装了两个系统怎么切换(电脑安装2个系统怎么更换启动)

1.点击运行打开电脑点击左下角的开始菜单栏选项,右击鼠标在序列栏中选择运行打开。2.输入msconfig接着在运行的输入框中输入msconfig点击确定即可打开系统配置。3.点击引导打开系统配置的页面...

linux系统哪个版本好用(最好linux系统版本)

个人比较推荐Debian这个发行版本。DebianGNU/Linux于1993年首次公布,至今已经有近30年历史了。当然其他版本比如openSUSE,Slackware,ArchLinux,Ubu...

win10激活在哪里查看(win10激活时间在哪里看)

在Windows10中,您可以通过以下方法查看激活状态:方法1:使用“设置”应用1.点击屏幕左下角的“开始”按钮,然后点击“设置”(齿轮图标)。2.在设置窗口中,点击“系统”图标。3.在“系统...

官方win10dll文件修复工具(官方win7dll文件修复工具)

当电脑丢失dll文件时,可以采用以下几种方法进行一键修复:从回收站还原:如果是不小心误删了一些计算机文件,导致电脑出现异常的情况时,首先就可以去回收站找回dll文件,如果文件还在,就可以通过还原操作来...

qq所有历史旧版本大全(qq历史版本一览表)

有2种方法。一种是:你是QQ会员。你可以把旧版打开,聊天记录上传。然后打开新的QQ,下载。第2种是:你在硬盘上装了QQ软件,然后你就点卸载(uninst),把原来的卸了。然后按原位置覆盖,装上06版。...

电脑显示器分辨率怎么调(显示分辨率无法调整)

1、以win7为例,首先右键点击桌面,在右键菜单中直接显示了屏幕分辨率的选项,用鼠标点击一下这个选项。2、在分辨率设置选项页面中,有一个分辨率的选项,点击一下这个选项,上面默认显示的数值是你现在的屏幕...

8系统(8系统点检控制包含什么)

WIndows8系统是微软目前最新的操作系统,Moto的图形界面设计,使很多已经习惯于早期windows系统的用户难以接受,Windows8是一个向平板和桌面系统妥协的产物,存在着相当多的利弊。...

取消回复欢迎 发表评论: