Python logging模块的基本使用、进阶使用详解

这篇具有很好参考价值的文章主要介绍了Python logging模块的基本使用、进阶使用详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

python3中,内置了logging模块,用于进行日志相关的处理。
这篇文章将总结logging模块的基本用法及进阶用法

一、基本使用

1. 日志级别及对应函数

logging模块默认定义了6个日志级别:

import logging
print(logging._nameToLevel)
# {'CRITICAL': 50, 'FATAL': 50, 'ERROR': 40, 'WARN': 30, 'WARNING': 30, 'INFO': 20, 'DEBUG': 10, 'NOTSET': 0}
print(logging._levelToName)
# {50: 'CRITICAL', 40: 'ERROR', 30: 'WARNING', 20: 'INFO', 10: 'DEBUG', 0: 'NOTSET'}

日志优先级:CRIRICAL>ERROR>WARNING>INFO>DEBUG
当日志级别设置为某个级别时,则低于该级别的日志将不输出。如日志级别设置为INFO,则DEBUG级别的日志将不输出。

级别名称 级别数值 函数 使用场景
NOTSET 0 (确切来说它不算是日志级别)
创建一个 logger 时,设置级别为 NOTSET (当 logger 是根 logger 时,将处理所有消息;当 logger 是非根 logger 时,所有消息会委派给父级)
DEBUG 10 logging.debug(msg, *args, **kwargs) 通常在开发调试阶段使用,用来定位问题或显示程序运行细节
INFO 20 logging.info(msg, *args, **kwargs) 通常用来输出一般信息,或确认程序能正常工作
WARNING/WARN 30 logging.warning(msg, *args, **kwargs)
logging.warn(msg, *args, **kwargs)
用来输出一些警告信息,但通常这些警告信息不影响程序正常运行
ERROR 40 logging.error(msg, *args, **kwargs) 用来输出程序的报错信息,表明程序的某些功能已不可用
CRITICAL/FATAL 50 logging.critical(msg, *args, **kwargs)
logging.fatal(msg, *args, **kwargs)
用来输出严重的错误信息,表明程序已不能继续执行

示例:

import logging

# 根日志器默认日志级别为WARNING,这里将其重置,以保证debug、info级别的日志也能输出
logging.basicConfig(level=logging.NOTSET)

logging.debug("This is a %s message.",logging.getLevelName(logging.DEBUG))
logging.info("This is an %s message.",logging.getLevelName(logging.INFO))
logging.warn("This is a %s message.",logging.getLevelName(logging.WARN))
logging.warning("This is a %s message.",logging.getLevelName(logging.WARNING))
logging.error("This is an %s message.",logging.getLevelName(logging.ERROR))
logging.critical("This is a %s message.",logging.getLevelName(logging.CRITICAL))
logging.fatal("This is a %s message.",logging.getLevelName(logging.FATAL))

logging.log(logging.INFO,"This ia a message from logging.log().")

输出:

DEBUG:root:This is a DEBUG message.
INFO:root:This is an INFO message.
E:/Chen/python3/ExciseA/test.py:14: DeprecationWarning: The 'warn' function is deprecated, use 'warning' instead
  logging.warn("This is a %s message.",logging.getLevelName(logging.WARN))
WARNING:root:This is a WARNING message.
WARNING:root:This is a WARNING message.
ERROR:root:This is an ERROR message.
CRITICAL:root:This is a CRITICAL message.
CRITICAL:root:This is a CRITICAL message.
INFO:root:This ia a message from logging.log().

解释:

  • 输出中第3行提示logging.warn() 已遗弃,但这里为了兼容,仍可用(我这里用的是python 3.7.7版本);
  • WARNWARNING等效,CRITICALFATAL等效,通常用CRITICAL;
  • logging.log(level, msg, *args, **kwargs) 其中,level参数指定输出日志级别。

2. logging.basicConfig(**kwargs)

该函数可以对根日志记录器进行配置

支持以下关键字参数:

参数 描述
filename 使用指定的文件名创建FileHandler,该参数缺省则使用StreamHandler
filemode 指定何种方式打开filename指定的文件,默认为a追加模式
format 指定处理器使用的格式字符串,根日志器的默认格式字符串为:%(levelname)s:%(name)s:%(message)s
datefmt 使用指定的日期/时间格式来替换%(asctime)s的默认格式'%Y-%m-%d %H:%M:%S,uuu',其中 uuu 部分是毫秒值,其他字母根据与 time.strftime() 所接受的格式相同
style 3.2 新增参数。如果指定了 format,将为格式字符串使用此风格。 '%', '{''$' 分别对应于 printf 风格, str.format()string.Template。 默认为 '%'
level 设置根日志器的级别,根记录器默认的日志级别为:logging.WARNING
stream 使用指定的流初始化StreamHandler,该流可以是open(filename, mode)创建的,也可以是sys.stdoutsys.stderr等,需要注意StreamHandler不会关闭open(filename, mode)创建的流
stream不能与filename/filemode同时出现
handlers 3.3 新增参数。如果指定了,这应该是一个已经创建的处理程序的可迭代对象,它将被添加到根处理程序中。列表中任何未分配格式化器的处理程序将被分配在此函数中创建的格式化器。
handlers不能与filename/filemode同时出现
handlers不能与stream同时出现

格式化字符串支持的参数:

参数名称 %-style {-style $-style 描述
name %(name)s {name} ${name} 当前日志器名称,根日志器名称为root
levelno %(levelno)s {levelno} ${levelno} 日志级别的数字值
{'CRITICAL': 50, 'ERROR': 40, 'WARNING': 30, 'INFO': 20, 'DEBUG': 10}
levelname %(levelname)s {levelname} ${levelname} 日志级别的文字值
{50: 'CRITICAL', 40: 'ERROR', 30: 'WARNING', 20: 'INFO', 10: 'DEBUG'}
pathname %(pathname)s {pathname} ${pathname} 发生日志记录调用的源文件完整路径名
filename %(filename)s {filename} ${filename} pathname的文件名部分(不含路径)
module %(module)s {module} ${module} filename的文件名部分(不含后缀),如:test.py文件,moduletest
lineno %(lineno)d {lineno:d} ${lineno:d} 发生日志调用处所在的行号
funcName %(funcName)s {funcName} ${funcName} 发生日志调用处,所在的函数名
created %(created)f {created:f} ${created:f} 创建日志的时间戳(time.time()的值)
asctime %(asctime)s {asctime} ${asctime} 日志生成的时间,默认形式为%Y-%m-%d %H:%M:%S,uuu,其中uuu是毫秒部分,如2023-08-17 10:01:05,112
msecs %(msecs)d {msecs:d} ${msecs:d} 日志生成时间的毫秒部分
thread %(thread)d {thread:d} ${thread:d} 线程ID(如果可用)
process %(process)d {process:d} ${process:d} 进程ID(如果可用)
message %(message)s {message} ${message} 记录日志的消息

示例1:

import logging

logging.basicConfig(
    level=logging.NOTSET,
    format='%(asctime)s - %(levelname)s - %(name)s - %(message)s'
)

logging.info(logging.BASIC_FORMAT)
2023-08-17 10:06:29,276 - INFO - root - %(levelname)s:%(name)s:%(message)s
# asctime 默认时间字符串格式为:%Y-%m-%d %H:%M:%S,%3d
# 根日志记录器默认的日志格式为:%(levelname)s:%(name)s:%(message)s

示例2:

import logging

logging.basicConfig(
    level=logging.NOTSET,
    format='%(asctime)s - %(levelname)s - %(name)s - %(message)s',
    datefmt="%a, %d %b %Y %H:%M:%S %z"
)

logging.info(logging.PercentStyle.asctime_format)
Thu, 17 Aug 2023 09:08:26 +0800 - INFO - root - %(asctime)s
# datefmt 指定 asctime 的格式字符串,其他字母根据与 [time.strftime()](https://docs.python.org/zh-cn/3.7/library/time.html#time.strftime) 所接受的格式相同
# format 默认使用的是 %-style 格式化形式

示例3:

import logging

logging.basicConfig(
    level=logging.NOTSET,
    format='{asctime}.{msecs:.0f} - {levelname} - {name} - {message}',
    datefmt="%a, %d %b %Y %H:%M:%S",
    style="{"
)

logging.info(logging.StrFormatStyle.asctime_format)
Thu, 17 Aug 2023 10:12:32.093 - INFO - root - {asctime}
# style 参数指定 format 格式字符串所使用的格式方式为 StrFormatStyle,即 {var} 形式
# {msecs:03.0f} 中,: 后面跟的字符串是对 msecs 进行格式控制的,如 03.0f 是指保留msecs的整数部分,且整数部分保留3位,不足3位在前面补零。详情参考:https://docs.python.org/zh-cn/3.7/library/stdtypes.html#str.format

示例4:

import logging

logging.basicConfig(
    level=logging.NOTSET,
    format='${asctime}.$msecs - ${levelname} - ${name} - ${message}',
    datefmt="%a, %d %b %Y %H:%M:%S",
    style="$"
)

logging.info(logging.StringTemplateStyle.asctime_format)
Thu, 17 Aug 2023 10:20:04.149.18017387390137 - INFO - root - ${asctime}
# style 参数指定 format 格式字符串所使用的格式方式为 StringTemplateStyle,即 ${var} 形式
# 其中,花括号可以省略,如示例中的 $msecs
# 但使用$这种方式,无法在 format 中控制变量的格式,例如,无法像示例3中那样控制 ${msecs} 仅输出3位整数值

示例5:

import logging

logging.basicConfig(
    level=logging.NOTSET,
    format='%(asctime)s - %(levelname)s - %(name)s - %(message)s',
    filename='./default.log'
)

logging.info("This is a INFO message.")
# 将日志输出到 default.log 文件中,如果没有文件则会自动创建一个 

二、进阶使用

日志库采用模块化方法,并提供几类组件:记录器、处理程序、过滤器和格式化程序

组件 实例化 功能描述
记录器 logging.getLogger() 暴露了应用程序代码直接使用的接口
处理程序 logging.FileHandler()
logging.StreamHandler()
logging.NullHandler()
将日志记录(由记录器创建)发送到适当的目标
过滤器 logging.Filter() 提供了更精细的附加功能,用于确定要输出的日志记录
格式化程序 logging.Formatter() 指定最终输出中日志记录的样式

示例1:

import logging

# 创建日志器
logger = logging.getLogger("test")
# 为日志器设置日志等级,如果这里不设置,将会使用其父级日志器的等日志等级
# 这里它的父日志器是root,root的默认日志级别是 logging.WARNING
logger.setLevel(logging.INFO)

# 创建文件处理程序
fh = logging.FileHandler(filename="./test.log",encoding="utf8")
# 创建流处理程序
sh = logging.StreamHandler()

# 为文件处理程序设置日志等级
fh.setLevel(logging.ERROR)
# 为流处理程序设置日志等级
sh.setLevel(logging.DEBUG)

# 创建格式化程序
ffmt = logging.Formatter(
    fmt = "%(asctime)s - %(levelname)s - %(name)s - %(filename)s:%(lineno)d - %(message)s",
    datefmt = "%Y/%m/%d %H:%M:%S"
)
# 创建格式化程序
sfmt = logging.Formatter(
    fmt = "%(asctime)s - %(levelname)s - %(name)s - %(filename)s:%(lineno)d - %(message)s",
)

# 将 ffmt 格式化程序应用到 fh 文件处理程序
fh.setFormatter(ffmt)
# 将 sfmt 格式化程序应用到 sh 流处理程序
sh.setFormatter(sfmt)

# 将文件处理程序应用到logger日志器
logger.addHandler(fh)
# 将流处理程序应用到logger日志器
logger.addHandler(sh)

# 记录日志信息
logger.debug("This is a DEBUG log.")
logger.info("This is an INFO log.")
logger.warning("This is a WARNING log.")
logger.error("This is an ERROR log.")
logger.critical("This is a CRITICAL log.")

控制台输出:

2023-08-17 12:57:37,238 - INFO - test - test.py:53 - This is an INFO log.
2023-08-17 12:57:37,238 - WARNING - test - test.py:54 - This is a WARNING log.
2023-08-17 12:57:37,238 - ERROR - test - test.py:55 - This is an ERROR log.
2023-08-17 12:57:37,238 - CRITICAL - test - test.py:56 - This is a CRITICAL log.

test.log 文件输出:

2023/08/17 12:57:37 - ERROR - test - test.py:55 - This is an ERROR log.
2023/08/17 12:57:37 - CRITICAL - test - test.py:56 - This is a CRITICAL log.

解释:

  • 使用sh.setLevel(logging.DEBUG)对流处理程序重新设置了日志级别,但是输出中并没有debug级别的日志信息。而使用fh.setLevel(logging.ERROR)对文件处理程序重新设置的日志级别,文件输出中过滤掉了ERROR以下级别的消息。因此说明了,为处理程序设置日志级别时,如果该级别低于日志器的日志级别时,则是无效设置。

示例2:

import logging

# 创建日志器 test
logger = logging.getLogger("test")
logger.setLevel(logging.INFO)

# 创建日志器 test.env1 ,表明 env1 上级日志器是 test
logger_env1 = logging.getLogger("test.env1")
# logger_env1.propagate = False

# 创建流处理程序
sh = logging.StreamHandler()

# 创建格式处理程序
sfmt = logging.Formatter(
    fmt = "%(asctime)s - %(levelname)8s - %(name)s - %(filename)s:%(lineno)d - %(message)s",
)

# 将格式处理程序应用到流处理程序
sh.setFormatter(sfmt)

# 将流处理程序应用到test日志器
logger.addHandler(sh)
# 将流处理程序应用到env1日志器
# logger_env1.addHandler(sh)

# 日志记录
logger_env1.debug("This is a DEBUG log.")
logger_env1.info("This is an INFO log.")
logger_env1.warning("This is a WARNING log.")
logger_env1.error("This is an ERROR log.")
logger_env1.critical("This is a CRITICAL log.")

控制台输出:

2023-08-17 13:23:55,499 -     INFO - test.env1 - test.py:44 - This is an INFO log.
2023-08-17 13:23:55,499 -  WARNING - test.env1 - test.py:45 - This is a WARNING log.
2023-08-17 13:23:55,499 -    ERROR - test.env1 - test.py:46 - This is an ERROR log.
2023-08-17 13:23:55,499 - CRITICAL - test.env1 - test.py:47 - This is a CRITICAL log.

解释:

  • getLogger() 返回对具有指定名称的记录器实例的引用,如果没有指定名称则返回root根记录器;

  • getLogger() 返回的记录器具有以.分隔的层次结构,在分层列表中较低的记录器是列表中较高的记录器的子项。例如,给定一个名为 foo 的记录器,名称为 foo.barfoo.bar.bazfoo.bam 的记录器都是 foo 子项

  • 子记录器将消息传播到与其上级记录器关联的处理程序。因此,不必为应用程序使用的所有记录器定义和配置处理程序。为顶级记录器配置处理程序并根据需要创建子记录器就足够了。

    上述示例证明了这点。示例中并没有为env1日志器添加处理程序,而是将处理器添加到了它上一级的test日志器,而日志记录直接使用的env1日志器,test日志器的设置对env1生效了。

    (你可以通过logger_env1.propagate = False,关闭这种传播关系,即env1不再使用上一级日志器的配置)

示例3:

import logging

# 创建日志器 test
logger = logging.getLogger("test")
logger.setLevel(logging.DEBUG)

# 创建日志器 test.env1 ,表明 env1 上级日志器是 test
logger_env1 = logging.getLogger("test.env1")

# 创建流处理程序
sh = logging.StreamHandler()

# 创建格式处理程序
sfmt = logging.Formatter(
    fmt = "%(asctime)s - %(levelname)8s - %(name)s - %(filename)s:%(lineno)d - %(message)s",
)

# 将格式处理程序应用到流处理程序
sh.setFormatter(sfmt)

# 创建Filter对象
class MyFilter(logging.Filter):
    def filter(self, record):
        if record.name == 'test':
            return record.levelno in (logging.WARNING,logging.INFO)
        if record.name == 'test.env1':
            return record.levelno == logging.ERROR
        return True

# 将过滤器应用到流处理程序
sh.addFilter(MyFilter())

# 将流处理程序应用到test日志器
logger.addHandler(sh)

logger.debug("This is a DEBUG log.")
logger.info("This is an INFO log.")
logger.warning("This is a WARNING log.")
logger.error("This is an ERROR log.")
logger.critical("This is a CRITICAL log.")

logger_env1.debug("This is a DEBUG log.")
logger_env1.info("This is an INFO log.")
logger_env1.warning("This is a WARNING log.")
logger_env1.error("This is an ERROR log.")
logger_env1.critical("This is a CRITICAL log.")

输出:

2023-08-17 14:28:19,674 -     INFO - test - test.py:51 - This is an INFO log.
2023-08-17 14:28:19,674 -  WARNING - test - test.py:52 - This is a WARNING log.
2023-08-17 14:28:19,674 -    ERROR - test.env1 - test.py:59 - This is an ERROR log.

解释:

  • 代码中使用sh.addFilter(MyFilter()),将自定义的MyFilter()过滤器应用到处理程序,该过滤器将对使用该处理程序的日志器生效;
  • test 日志器仅生成了 INFO、WARNING 级别的日志,其余日志被过滤器过滤掉了;
  • env1 日志器仅生成了 ERROR 级别的日志,其余日志被过滤器过滤掉了。

最后总结:
一条日志的输出需要经过以下几次过滤:

  • 日志器日志等级的过滤;
  • 日志器的过滤器过滤;
  • 处理器设置的日志等级的过滤;
  • 处理器设置的过滤器的过滤;


参考资料:

模块 logging — Python 的日志记录工具 — Python 3.7.13 文档

日志 HOWTO — Python 3.7.13 文档文章来源地址https://www.toymoban.com/news/detail-823557.html

到了这里,关于Python logging模块的基本使用、进阶使用详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Python从入门到进阶】22、urllib库基本使用

    接上篇《21、爬虫相关概念介绍》 上一篇我们介绍了爬虫的相关概念,本篇我们来介绍一下用Python实现爬虫的必备基础,urllib库的学习。 我们今后的学习可能需要用到很多python库(library),及引用其他已经编写好的程序代码模块,来提高我们的开发效率。 python库(library)是

    2024年02月07日
    浏览(38)
  • Python学习 -- logging模块

    logging 模块是 Python 中用于记录日志的标准库,它提供了丰富的功能,可以帮助开发者进行日志记录和管理。以下是关于logging模块的详细使用方式,包括日志级别、处理流程、Logger 类、Handler 类、Filter 类、Formatter 类以及模块中常用函数等内容。 1. 日志级别 ​ 2. 处理流程 ​

    2024年02月09日
    浏览(31)
  • Python的Logging模块

    日志是指记录系统或应用程序运行状态、事件和错误信息的文件或数据。在计算机系统中,日志通常用于故障排除、性能分析、安全审计等方面。日志可以记录各种信息,如系统启动和关闭时间、应用程序的运行状态、用户登录和操作记录、网络通信数据等。通过分析日志,

    2024年02月12日
    浏览(26)
  • 【100天精通python】Day23:正则表达式,基本语法与re模块详解示例

      目录  专栏导读  1 正则表达式概述 2 正则表达式语法 2.1 正则表达式语法元素

    2024年02月14日
    浏览(42)
  • Python的logging模块Demo

    Tip:默认情况下,logging模块不会自动地将日志存储到某个特定路径,除非你指定了该路径。你需要创建一个FileHandler,然后为其设置一个文件路径,这样日志就会被写入到该文件中。 以下是一个简单的例子,展示如何将日志信息写入到名为example.log的文件中:   在上述代码

    2024年02月07日
    浏览(33)
  • Python selenium驱动下载,模块安装以及基本使用

    视频版教程:一天掌握python爬虫【基础篇】 涵盖 requests、beautifulsoup、selenium 我们以谷歌浏览器为例讲解。首先我们要去下载谷歌浏览器驱动。 谷歌浏览器驱动下载地址:Chromium History Versions Download ↓ 查看谷歌浏览器版本 右上角三个点 - 帮助 - 关于 我们下载解压后的驱动,

    2024年02月06日
    浏览(40)
  • Python模块之logging和colorlog

    使用logging和colorlog实现日志记录可以方便地记录程序的运行情况,方便调试和分析问题。下面将详细说明如何使用logging和colorlog,并提供相应的代码示例。 首先需要安装colorlog模块。可以通过pip命令进行安装: logging模块是Python自带的日志记录模块。logging模块提供了非常灵活

    2024年02月10日
    浏览(58)
  • python接口自动化测试 - mock模块基本使用介绍

    py3已将mock集成到unittest库中 为的就是更好的进行单元测试 简单理解, 模拟接口返回参数 通俗易懂, 直接修改接口返回参数的值 官方文档:unittest.mock --- 模拟对象库 — Python 3.11.1 文档 解决依赖问题,达到解耦作用 当我们测试某个 目标接口(模块) 时,该接口 依赖其他接

    2024年02月02日
    浏览(65)
  • python 常用内置模块之 logging(日志输出)

    Python logging 模块定义了为应用程序和库实现灵活的事件日志记录的函数和类,可以方便第三方模块或者是应用使用。这个模块提供不同的日志级别,并可以采用不同的方式记录日志,比如文件,HTTP GET/POST,SMTP,Socket 等,甚至可以自定义实现具体的日志记录方式。 Logging 优点

    2024年02月05日
    浏览(45)
  • 【Python】进阶学习:pandas--read_excel()函数的基本使用

    【Python】进阶学习:pandas–read_excel()函数的基本使用 🌈 个人主页:高斯小哥 🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程👈 希望得到您的订阅和支持~ 💡 创作高质量博文(平均质量分92+),分享更多关于深度学习、

    2024年03月09日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包