• 软件:1914
  • 资讯:52339|
  • 收录网站:100606|

IT精英团

Python中日志模块的使用

Python中日志模块的使用

浏览次数:
评论次数:
编辑: 泽洋
信息来源: 51CTO博客
更新日期: 2021-11-16 18:12:38
摘要

Python中日志模块的使用,前言程序和脚本往往是无人值守运行的,一旦发生问题,就需要我们去追溯当时的情况来定位问题的原因。这便需要我们在程序和脚本中引入日志的功能。相比于print信息,使用logging日志有以下优点可以记录输出日志的时间、文件、函数以及代码行,甚至线程名和线程号可以分等级记录日志(调试级、信息级、

  • 资讯详情

前言

程序和脚本通常无人值守运行。一旦出现问题,我们就需要追溯当时的情况来定位问题的原因。

这就要求我们在程序和脚本中引入日志功能。

与打印信息相比,使用日志具有以下优点

您可以记录输出日志的时间、文件、函数和代码行,甚至线程名和线程号

日志可以记录在不同的级别(调试级别、信息级别、警告级别、错误级别和严重错误级别)

它可以实时输出到屏幕或文件中

基本使用

Python使用自己的日志模块来输出日志。日志模块的主要组件是一个日志记录器,如下图所示。

基本用途如下

导入日志记录

Logging.debug(“调试级别日志”)

Logging.info('信息级别日志')

log . warning('警告级别日志')#或log . warning('警告级别日志')

Logging.error(“错误级别日志”)

log . critical('严重错误级别的日志')

尝试:

1/0

ex:除外

log . exception(ex)#错误级别日志,显示多行回溯信息

运行结果如下

警告:root:警告级别日志

错误:根:错误级别日志

严重错误级别的日志

错误:根:零分割

追溯(最近一次通话最后一次):

模块中第9行文件' ipython-input-5-9be264a94d56 '

1/0

零除法错误:除以零

发现仅显示警告、错误和严重日志,因为日志记录中默认日志记录程序的级别是日志记录。警告,这意味着默认情况下只显示警告级别以上的日志。

修改日志等级

我们可以使用logging.basicConfig来修改root logger的设置。

导入日志记录

日志记录。基本配置(级别=日志记录。调试)#配置全局根日志记录

Logging.debug(“调试级别日志”)

Logging.info('信息级别日志')

日志记录。警告(“警告级别日志”)

Logging.error(“错误级别日志”)

log . critical('严重错误级别的日志')

再次运行,发现所有日志都可以输出。

级别日志级别支持

日志记录。未设置NOTSET:输出各级日志

日志记录。调试级别,所有级别的输出日志

日志记录。INFO:信息级别,输出包含信息级别以上的日志

日志记录。警告:警告级别,输出包含警告级别的日志

日志记录。错误:错误级别,输出包含高于错误级别的日志。

日志记录。严重错误:严重错误级别,仅输出严重错误日志

日志级别之间的关系是关键错误警告信息调试信息集

修改日志格式

日志的默认格式是警告:root:警告级别日志,即级别:日志名:输出消息。我们也可以在logging.basicConfig中使用format参数来修改它的输出格式。

导入日志记录

logging . basic config(level

l=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') logging.debug('调试级别的日志') logging.info('信息基本的日志') logging.warning('警告级别的日志') logging.error('错误级别的日志') logging.critical('严重错误级别的日志')

运行输出如下:

2020-11-04 10:11:49,238 - DEBUG - 调试级别的日志
2020-11-04 10:11:49,238 - INFO - 信息基本的日志
2020-11-04 10:11:49,238 - WARNING - 警告级别的日志
2020-11-04 10:11:49,238 - ERROR - 错误级别的日志
2020-11-04 10:11:49,238 - CRITICAL - 严重错误级别的日志

format中使用%(变量名)s这样的具名占位符,来输出不同的信息,其他的字符则原样显示。
支持的变量如下:

  • %(levelno)s: 打印日志级别的数值
  • %(levelname)s: 打印日志级别名称
  • %(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]
  • %(filename)s: 打印当前执行程序名
  • %(funcName)s: 打印日志的当前函数
  • %(lineno)d: 打印日志的当前行号(因为是数字,所以使用%d)
  • %(asctime)s: 打印日志的时间
  • %(thread)d: 打印线程ID
  • %(threadName)s: 打印线程名称
  • %(process)d: 打印进程ID
  • %(message)s: 打印日志信息

对于日期,我们可以使用datefmt来修改,比如,将上例中的logging.basicConfig修改为

...
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s - %(levelname)s - %(message)s',
                    datefmt='%Y年%m月%d日 %H:%M:%S')
...

输出形式如下:

2020年11月04日 10:19:04 - DEBUG - 调试级别的日志
2020年11月04日 10:19:04 - INFO - 信息基本的日志
2020年11月04日 10:19:04 - WARNING - 警告级别的日志
2020年11月04日 10:19:04 - ERROR - 错误级别的日志
2020年11月04日 10:19:04 - CRITICAL - 严重错误级别的日志

输出到文件

日志是默认输出的屏幕的,也可以通过logging.basicConfig中的filename将日志输出到文件。

import logging
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s - %(levelname)s - %(message)s',
                    datefmt='%Y年%m月%d日 %H:%M:%S',
                    filename='run.log',
                    filemode='a'
                    )
logging.debug('调试级别的日志')
logging.info('信息基本的日志')
logging.warning('警告级别的日志')
logging.error('错误级别的日志')
logging.critical('严重错误级别的日志')

运行后,日志将不会输出到屏幕,转而输出到文件中,filemode支持'w'每次覆盖和'a'追加模式。

自定义handlers

如果想即输出到屏幕又输出到文件,我们可以在logging.basicConfig的handlers参数中添加两个不同的handler来实现,logging.StreamHander()可以用于输出到屏幕,logging.FileHandler()可以用于输出到文件。

import logging
cli_handler = logging.StreamHandler()  # 输出到屏幕的日志处理器
file_handler = logging.FileHandler(filename='run.log', mode='a', encoding='utf-8')  # 输出到文件的日志处理器
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s - %(levelname)s - %(message)s',
                    datefmt='%Y年%m月%d日 %H:%M:%S',
                    handlers=[cli_handler, file_handler]   # 添加两个日志处理器
                    )
logging.debug('调试级别的日志')
logging.info('信息基本的日志')
logging.warning('警告级别的日志')
logging.error('错误级别的日志')
logging.critical('严重错误级别的日志')

这样便可以即输出到屏幕又输出到文件了。

自定义Logger

使用logging.basicConfig是直接配置全局的root logger,会对项目中所有的模块及三方包产生影响。
为了不影响其他模块和三方包的日志输出,我们可以使用自定义Logger,即日志记录器,基本步骤为

  1. 使用logging.getLogger()新建一个logger对象,并配置期日志等级(总日志开关)
  2. 新建多个日志处理器,分别设置其格式和日志等级
  3. 将多个日志处理器添加到logger中
    代码如下
# 文件名: mylogger.py
import logging
def get_logger(name):
    logger = logging.getLogger(name)
    logger.setLevel(logging.DEBUG)   # 设置总日志等级
    format = logging.Formatter(fmt='%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y年%m月%d日 %H:%M:%S')  # 日志格式
    cli_handler = logging.StreamHandler()  # 输出到屏幕的日志处理器
    file_handler = logging.FileHandler(filename='run.log', mode='a', encoding='utf-8')  # 输出到文件的日志处理器
    cli_handler.setFormatter(format)  # 设置屏幕日志格式
    file_handler.setFormatter(format)  # 设置文件日志格式
    cli_handler.setLevel(logging.INFO)  # 设置屏幕日志等级, 可以大于日志记录器设置的总日志等级
    # file_hander.setLevel(logging.DEBUG)  # 不设置默认使用logger的等级
    logger.handlers.clear()  # 清空已有处理器, 避免继承了其他logger的已有处理器
    logger.addHandler(cli_handler)  # 将屏幕日志处理器添加到logger
    logger.addHandler(file_handler)  # 将文件日志处理器添加到logger
    return logger

使用方式为,导入本模块的get_logger方法,使用logger代替logging打印各种信息。

from mylogger import get_logger
logger = get_logger('mylogger')
logger.debug('调试级别的日志')
logger.info('信息基本的日志')
logger.warning('警告级别的日志')
logger.error('错误级别的日志')
logger.critical('严重错误级别的日志')

注意:由于logger具有子模块继承性,在项目中多个地方使用get_logger生成不同的logger对象时,有可能会继承其他logger的处理器。建议项目中使用同一个logger。或者对日志记录器使用单例模式。
在服务端项目中(如web项目),由于进程是长久运行,可以使用滚动日志处理器来分割日志文件。

标签: python
WinForm RichTextBox禁止换行
« 上一篇
返回列表
下一篇 »
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
你会是第一个来这里评论的人吗?
最近发布资讯
更多