Python日志库logging总结(最全的版本)

2023-11-17

转自:https://cloud.tencent.com/developer/article/1354396

 

1、日志级别

Python 标准库 logging 用作记录日志,默认分为六种日志级别(括号为级别对应的数值),NOTSET(0)、DEBUG(10)、INFO(20)、WARNING(30)、ERROR(40)、CRITICAL(50)。我们自定义日志级别时注意不要和默认的日志级别数值相同,logging 执行时输出大于等于设置的日志级别的日志信息,如设置日志级别是 INFO,则 INFO、WARNING、ERROR、CRITICAL 级别的日志都会输出。

2、logging 流程

官方的 logging 模块工作流程图如下:

从下图中我们可以看出看到这几种 Python 类型,LoggerLogRecordFilterHandlerFormatter

类型说明:

Logger:日志,暴露函数给应用程序,基于日志记录器和过滤器级别决定哪些日志有效。

LogRecord :日志记录器,将日志传到相应的处理器处理。

Handler :处理器, 将(日志记录器产生的)日志记录发送至合适的目的地。

Filter :过滤器, 提供了更好的粒度控制,它可以决定输出哪些日志记录。

Formatter:格式化器, 指明了最终输出中日志记录的布局。

 

 

 

logging流程图.png

  1. 判断 Logger 对象对于设置的级别是否可用,如果可用,则往下执行,否则,流程结束。
  2. 创建 LogRecord 对象,如果注册到 Logger 对象中的 Filter 对象过滤后返回 False,则不记录日志,流程结束,否则,则向下执行。
  3. LogRecord 对象将 Handler 对象传入当前的 Logger 对象,(图中的子流程)如果 Handler 对象的日志级别大于设置的日志级别,再判断注册到 Handler 对象中的 Filter 对象过滤后是否返回 True 而放行输出日志信息,否则不放行,流程结束。
  4. 如果传入的 Handler 大于 Logger 中设置的级别,也即 Handler 有效,则往下执行,否则,流程结束。
  5. 判断这个 Logger 对象是否还有父 Logger 对象,如果没有(代表当前 Logger 对象是最顶层的 Logger 对象 root Logger),流程结束。否则将 Logger 对象设置为它的父 Logger 对象,重复上面的 3、4 两步,输出父类 Logger 对象中的日志输出,直到是 root Logger 为止。

3、日志输出格式

日志的输出格式可以认为设置,默认格式为下图所示。

默认日志输出格式.png

4、基本使用

logging 使用非常简单,使用 basicConfig() 方法就能满足基本的使用需要,如果方法没有传入参数,会根据默认的配置创建Logger 对象,默认的日志级别被设置为 WARNING,默认的日志输出格式如上图,该函数可选的参数如下表所示。

参数名称

参数描述

filename

日志输出到文件的文件名

filemode

文件模式,r[+]、w[+]、a[+]

format

日志输出的格式

datefat

日志附带日期时间的格式

style

格式占位符,默认为 "%" 和 “{}”

level

设置日志输出级别

stream

定义输出流,用来初始化 StreamHandler 对象,不能 filename 参数一起使用,否则会ValueError 异常

handles

定义处理器,用来创建 Handler 对象,不能和 filename 、stream 参数一起使用,否则也会抛出 ValueError 异常

 

示例代码如下:

import logging

logging.basicConfig()
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

传入常用的参数,示例代码如下(这里日志格式占位符中的变量放到后面介绍):

import logging

logging.basicConfig(filename="test.log", filemode="w", format="%(asctime)s %(name)s:%(levelname)s:%(message)s", datefmt="%d-%M-%Y %H:%M:%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')

生成的日志文件 test.log ,内容如下:

13-10-18 21:10:32 root:DEBUG:This is a debug message
13-10-18 21:10:32 root:INFO:This is an info message
13-10-18 21:10:32 root:WARNING:This is a warning message
13-10-18 21:10:32 root:ERROR:This is an error message
13-10-18 21:10:32 root:CRITICAL:This is a critical message

但是当发生异常时,直接使用无参数的 debug()、info()、warning()、error()、critical() 方法并不能记录异常信息,需要设置 exc_info 参数为 True 才可以,或者使用 exception() 方法,还可以使用 log() 方法,但还要设置日志级别和 exc_info 参数。

import logging

logging.basicConfig(filename="test.log", filemode="w", format="%(asctime)s %(name)s:%(levelname)s:%(message)s", datefmt="%d-%M-%Y %H:%M:%S", level=logging.DEBUG)
a = 5
b = 0
try:
    c = a / b
except Exception as e:
    # 下面三种方式三选一,推荐使用第一种
    logging.exception("Exception occurred")
    logging.error("Exception occurred", exc_info=True)
    logging.log(level=logging.DEBUG, msg="Exception occurred", exc_info=True)

5、自定义 Logger

上面的基本使用可以让我们快速上手 logging 模块,但一般并不能满足实际使用,我们还需要自定义 Logger。

一个系统只有一个 Logger 对象,并且该对象不能被直接实例化,没错,这里用到了单例模式,获取 Logger 对象的方法为 getLogger

注意:这里的单例模式并不是说只有一个 Logger 对象,而是指整个系统只有一个根 Logger 对象,Logger 对象在执行 info()、error() 等方法时实际上调用都是根 Logger 对象对应的 info()、error() 等方法。

我们可以创造多个 Logger 对象,但是真正输出日志的是根 Logger 对象。每个 Logger 对象都可以设置一个名字,如果设置logger = logging.getLogger(__name__),__name__ 是 Python 中的一个特殊内置变量,他代表当前模块的名称(默认为 __main__)。则 Logger 对象的 name 为建议使用使用以点号作为分隔符的命名空间等级制度。

Logger 对象可以设置多个 Handler 对象和 Filter 对象,Handler 对象又可以设置 Formatter 对象。Formatter 对象用来设置具体的输出格式,常用变量格式如下表所示,所有参数见 Python(3.7)官方文档

变量

格式

变量描述

asctime

%(asctime)s

将日志的时间构造成可读的形式,默认情况下是精确到毫秒,如 2018-10-13 23:24:57,832,可以额外指定 datefmt 参数来指定该变量的格式

name

%(name)

日志对象的名称

filename

%(filename)s

不包含路径的文件名

pathname

%(pathname)s

包含路径的文件名

funcName

%(funcName)s

日志记录所在的函数名

levelname

%(levelname)s

日志的级别名称

message

%(message)s

具体的日志信息

lineno

%(lineno)d

日志记录所在的行号

pathname

%(pathname)s

完整路径

process

%(process)d

当前进程ID

processName

%(processName)s

当前进程名称

thread

%(thread)d

当前线程ID

threadName

%threadName)s

当前线程名称

Logger 对象和 Handler 对象都可以设置级别,而默认 Logger 对象级别为 30 ,也即 WARNING,默认 Handler 对象级别为 0,也即 NOTSET。logging 模块这样设计是为了更好的灵活性,比如有时候我们既想在控制台中输出DEBUG 级别的日志,又想在文件中输出WARNING级别的日志。可以只设置一个最低级别的 Logger 对象,两个不同级别的 Handler 对象,示例代码如下:

import logging
import logging.handlers

logger = logging.getLogger("logger")

handler1 = logging.StreamHandler()
handler2 = logging.FileHandler(filename="test.log")

logger.setLevel(logging.DEBUG)
handler1.setLevel(logging.WARNING)
handler2.setLevel(logging.DEBUG)

formatter = logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s")
handler1.setFormatter(formatter)
handler2.setFormatter(formatter)

logger.addHandler(handler1)
logger.addHandler(handler2)

# 分别为 10、30、30
# print(handler1.level)
# print(handler2.level)
# print(logger.level)

logger.debug('This is a customer debug message')
logger.info('This is an customer info message')
logger.warning('This is a customer warning message')
logger.error('This is an customer error message')
logger.critical('This is a customer critical message')

控制台输出结果为:

2018-10-13 23:24:57,832 logger WARNING This is a customer warning message
2018-10-13 23:24:57,832 logger ERROR This is an customer error message
2018-10-13 23:24:57,832 logger CRITICAL This is a customer critical message

文件中输出内容为:

2018-10-13 23:44:59,817 logger DEBUG This is a customer debug message
2018-10-13 23:44:59,817 logger INFO This is an customer info message
2018-10-13 23:44:59,817 logger WARNING This is a customer warning message
2018-10-13 23:44:59,817 logger ERROR This is an customer error message
2018-10-13 23:44:59,817 logger CRITICAL This is a customer critical message

创建了自定义的 Logger 对象,就不要在用 logging 中的日志输出方法了,这些方法使用的是默认配置的 Logger 对象,否则会输出的日志信息会重复。

import logging
import logging.handlers

logger = logging.getLogger("logger")
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.debug('This is a customer debug message')
logging.info('This is an customer info message')
logger.warning('This is a customer warning message')
logger.error('This is an customer error message')
logger.critical('This is a customer critical message')

输出结果如下(可以看到日志信息被输出了两遍):

2018-10-13 22:21:35,873 logger WARNING This is a customer warning message
WARNING:logger:This is a customer warning message
2018-10-13 22:21:35,873 logger ERROR This is an customer error message
ERROR:logger:This is an customer error message
2018-10-13 22:21:35,873 logger CRITICAL This is a customer critical message
CRITICAL:logger:This is a customer critical message

说明:在引入有日志输出的 python 文件时,如 import test.py,在满足大于当前设置的日志级别后就会输出导入文件中的日志。

6、Logger 配置

通过上面的例子,我们知道创建一个 Logger 对象所需的配置了,上面直接硬编码在程序中配置对象,配置还可以从字典类型的对象和配置文件获取。打开 logging.config Python 文件,可以看到其中的配置解析转换函数。

从字典中获取配置信息:

import logging.config

config = {
    'version': 1,
    'formatters': {
        'simple': {
            'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        },
        # 其他的 formatter
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'level': 'DEBUG',
            'formatter': 'simple'
        },
        'file': {
            'class': 'logging.FileHandler',
            'filename': 'logging.log',
            'level': 'DEBUG',
            'formatter': 'simple'
        },
        # 其他的 handler
    },
    'loggers':{
        'StreamLogger': {
            'handlers': ['console'],
            'level': 'DEBUG',
        },
        'FileLogger': {
            # 既有 console Handler,还有 file Handler
            'handlers': ['console', 'file'],
            'level': 'DEBUG',
        },
        # 其他的 Logger
    }
}

logging.config.dictConfig(config)
StreamLogger = logging.getLogger("StreamLogger")
FileLogger = logging.getLogger("FileLogger")
# 省略日志输出

从配置文件中获取配置信息:

常见的配置文件有 ini 格式、yaml 格式、JSON 格式,或者从网络中获取都是可以的,只要有相应的文件解析器解析配置即可,下面只展示了 ini 格式和 yaml 格式的配置。

test.ini 文件

[loggers]
keys=root,sampleLogger

[handlers]
keys=consoleHandler

[formatters]
keys=sampleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[logger_sampleLogger]
level=DEBUG
handlers=consoleHandler
qualname=sampleLogger
propagate=0

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=sampleFormatter
args=(sys.stdout,)

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

testinit.py 文件

import logging.config

logging.config.fileConfig(fname='test.ini', disable_existing_loggers=False)
logger = logging.getLogger("sampleLogger")
# 省略日志输出

test.yaml 文件

version: 1
formatters:
  simple:
    format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:
  console:
    class: logging.StreamHandler
    level: DEBUG
    formatter: simple
  
loggers:
  simpleExample:
    level: DEBUG
    handlers: [console]
    propagate: no
root:
  level: DEBUG
  handlers: [console]

testyaml.py 文件

import logging.config
# 需要安装 pyymal 库
import yaml

with open('test.yaml', 'r') as f:
    config = yaml.safe_load(f.read())
    logging.config.dictConfig(config)

logger = logging.getLogger("sampleLogger")
# 省略日志输出

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python日志库logging总结(最全的版本) 的相关文章

随机推荐

  • Stable Diffusion web UI 安装教程

    Stable Diffusion web UI 安装教程 欢迎来到猫说AI wx搜索 猫说AI接入了最新版Chatgpt供大家免费使用 注意 这是ubuntu20 04安装步骤 conda创建python虚拟环境 conda create
  • pom报错,但不提示错误

    1 删除工作空间文件 workspace projects metadata plugins org eclipse m2e jdt 项目名称 container
  • Java获取指定日期的0点以及24点

    指定Date date 比如是 2022 12 09 12 34 28 获取这天的开始时间和结束时间 获得某天最大时间 2022 12 09 23 59 59 public static Date getEndOfDay Date date
  • 没有客户端执行mysql_重学MySQL:谈一谈MySQL架构

    作为一名Web后端程序员 需要经常与MySQL打交道 不过更多的时候还是停留在增删改查 CURD 的应用层面 然而随着负责项目的数据量增长和服务器硬件性能开始出现瓶颈 让我感觉有必要更加全面深入地学习与了解MySQL 以便更好地发挥MySQ
  •  使用jsp实现留言板功能

    使用jsp实现留言板功能 一 开发环境 本项目使用eclipse MySQL8 0进行开发 在开发的过程中使用了一个jar包 mysql connector java 8 0 16 jar 点我下载 二 项目结构 1 index jsp
  • 信息安全建设之开源安全产品

    对于中小企业来说 有很多免费且开源的路由器和防火墙解决方案 甚至可以作为企业的选择 这类产品中 很多都提供局域网服务 如VPN服务 热点网关和通过强制网络门户以共享无线网络 当我们在考虑安全解决方案的时候 最便于操作的肯定是商业产品 最经济
  • [整理][LaTex]小技巧之——首行缩进

    0 简介 在LaTex编辑时 有时会遇到这样一个有关于首行缩进的问题 在汉语环境的编辑下 习惯上每段会进行一个两个字的缩进 但是在默认编辑模式下 一个章节下的首段是没有首行缩进的 本文的目的主要是解决中文情况下首段缩进的情况 1 默认情况
  • Java入门 (超详细)JDK(1.8)下载与安装及环境变量的配置教程

    第一步 下载JDK 8 Oracle官网下载地址 https www oracle com java technologies javase javase8u211 later archive downloads html 进入官网JDK
  • 鸿蒙是一个怎么样的操作系统,真的是安卓套壳吗?

    从鸿蒙项目正式推出以来 就一直有各自声音 有看好的 认为鸿蒙的出现将会成为一个智能终端设备操作系统的框架和平台 促进万物互联产业的繁荣发展 也有的人在唱衰 觉得鸿蒙发展不起来 甚至认为鸿蒙只是安卓的换皮 套壳 那事实是怎么样的 鸿蒙与安卓之
  • 微信群发图文消息步骤说明

    前段时间学习微信接口开发 心得与大家分享 第一步 调用 上传下载多媒体接口 上传图片 接收微信服务器返回结果 解析获取返回的url的值 等待备用 第二步 调用 上传图文消息素材 接口 截图中红色方框标记的thumb media id的值替换
  • WireShark常用过滤规则

    一 地址过滤 对源地址及目的地址过滤 ip src 192 168 0 1 ip dst 192 168 0 1 对源地址或者目的地址过滤 ip addr 192 168 0 1 排除某个地址数据包过滤 ip addr 192 168 0
  • Linux中使用pip安装库时出现Aborted (core dumped)问题解决方案

    作者 陈玓玏 在Linux中安装上pip后 通过pip install安装python库时出现这个问题 root DZG0370 mnt c Windows System32 pip3 install pandas Downloading
  • Inno Setup 如何让生成的setup.exe文件有管理员权限

    首先 在 Setup 段 PrivilegesRequired admin 然后 找到INNO安装目录下的SetupLdr e32文件 将程序中的Manifest更改一下 用reshacker这类工具改 这样运行程序的时候 Windows
  • php use not allowed,PHP Curl - Received HTTP/0.9 when not allowed

    问题 I stumbled over a weird behavior when I try to send a post HTTP 2 0 request to apples push service http2ch curl init
  • 哈工大操作系统实验二:系统调用的实现

    实验链接 文章目录 前言 做实验前一定要先拍个快照 操作系统实验环境的搭建请看如下链接 Ubuntu系统 Linux0 11环境搭建 一 实验内容 二 基础知识 三 实验步骤 注 因为实验一已经修改过启动文件 但此次实验需要完整的启动文件
  • 小白如何做好项目管理?看这里

    作为项目管理新手 你刚被安排负责一个重要的新项目 这是你的第一个项目 是一个重大的挑战 以下这些方法可以帮你有个好的开始 成功管理你的第一个项目 一 学习和培养能力 能力发展首先要突破不知道没有能力 认识项目管理是一个职业方向 通过了解项目
  • MySql Community Downloads 社区版下载地址

    https dev mysql com downloads mysql
  • Servlet+JSP+JavaBean开发模式(MVC)介绍

    好伤心 写登陆注册之前看见一篇很好的博文 没有收藏 然后找不到了 前几天在知乎上看见一个问题 什么时候感觉最无力 前两天一直想回答 尝试过google到的所有solve case 结果bug依然在 今天想回答 明明遇见过 就是找不到那篇文的
  • 深度学习 卷积神经网络即插即用的小插件

    卷积神经网络即插即用的小插件 前言 卷积神经网络设计技巧 小插件 STN ASPP Non local SE CBAM DCN v1 v2 BlurPool RFB ASFF 代码实现 前言 本篇博客主要介绍卷积神经网络中的即插即用的模块
  • Python日志库logging总结(最全的版本)

    转自 https cloud tencent com developer article 1354396 1 日志级别 Python 标准库 logging 用作记录日志 默认分为六种日志级别 括号为级别对应的数值 NOTSET 0 DEB