详解 python logging日志模块

目录
  • 1.日志简介
  • 2.日志级别
  • 3.修改日志级别
  • 4.日志记录到文件
  • 5.指定日志格式
  • 6.记录器(logger)
  • 7.处理器(Handler)
  • 8.处理器操作
  • 9.格式器(formatter)
  • 10.logging.basicConfig
  • 11.日志配置

转自微信公众号: Python之禅

1.日志简介

说到日志,无论是写框架代码还是业务代码,都离不开日志的记录,他能给我们定位问题带来极大的帮助。

记录日志最简单的方法就是在你想要记录的地方加上一句 print , 我相信无论是新手还是老鸟都经常这么干。在简单的代码中或者小型项目中这么干一点问题都没有。但是在一些稍大一点的项目,有时候定位一个问题,需要查看历史日志定位问题,用print就不合时宜了。

print 打印出来的日志没有时间,不知道日志记录的位置,也没有可读的日志格式, 还不能把日志输出到指定文件。。。。除非这些你都全部自己重复造一遍轮子。

最佳的做法是使用内置的logging模块, 因为 logging 模块给开发者提供了非常丰富的功能。

比如上图就是用标准库logging模块记录生成的日志,有日志的具体时间、日志发生的模块、有日志级别和日志的具体内容等等

怎么用呢,来看个例子:

导入logging模块,然后直接使用logging提供的日志消息记录方法就可以。

2.日志级别

日志级别分为以下5个级别

日志级别 使用场景
DEBUG debug级别用来记录详细的信息,方便定位问题进行调试,在生产环境我们一般不开启DEBUG
INFO 用来记录关键代码点的信息,以便代码是否按照我们预期的执行,生产环境通常会设置INFO级别
WARNING 记录某些不预期发生的情况,如磁盘不足
ERROR 由于一个更严重的问题导致某些功能不能正常运行时记录的信息
CRITICAL 当发生严重错误,导致应用程序不能继续运行时记录的信息

日志级别重要程度逐次提高,python提供了5个对应级别的方法。默认情况下日志的级别是WARGING, 低于WARING的日志信息都不会输出。

从上面代码中可以看到loging.warging以后的日志内容都打印在标准输出流,也就是命令行窗口,但是logging.debug和info记录的日志不会打印出来。

3.修改日志级别

如何让debug级别的信息也输出?

当然是修改默认的日志级别,在开始记录日志前可以使用logging.basicConfig方法来设定日志级别

import logging
logging.basicConfig( level=logging.DEBUG)
logging.debug("this is debug")
logging.info("this is info")
logging.error("this is error")

设置为debug级别后,所有的日志信息都会输出

DEBUG:root:this is debug
INFO:root:this is info
ERROR:root:this is error

4.日志记录到文件

前面的日志默认会把日志输出到标准输出流,就是只在命令行窗口输出,程序重启后历史日志没地方找,所以把日志内容永久记录是一个很常见的需求。同样通过配置函数logging.basicConfig可以指定日志输出到什么地方

import logging
logging.basicConfig(filename="test.log", level=logging.INFO)
logging.debug("this is debug")
logging.info("this is info")
logging.error("this is error")

这里我指定日志输出到文件test.log中,日志级别指定为了 INFO,最后文件中记录的内容如下:

INFO:root:this is info
ERROR:root:this is error

每次重新运行时,日志会以追加的方式在后面, 如果每次运行前要覆盖之前的日志,则需指定 filemode='w', 这个和 open 函数写数据到文件用的参数是一样的。

5.指定日志格式

默认输出的格式包含3部分,日志级别,日志记录器的名字,以及日志内容,中间用“:”连接。如果我们想改变日志格式,例如想加入日期时间、显示日志器名字,我们是可以指定format参数来设置日志的格式

import logging
logging.basicConfig(format='%(asctime)s %(levelname)s %(name)s %(message)s')
logging.error("this is error")

输出:

2021-12-15 07:44:16,547 ERROR root this is error

日志格式化输出提供了非常多的参数,除了时间、日志级别、日志消息内容、日志记录器的名字外,还可以指定线程名,进程名等等

到这里为止,日志模块的基本用法就这些了,也能满足大部分应用场景,更高级的方法接着往下看,可以帮助你更好的处理日志

6.记录器(logger)

前面介绍的日志记录,其实都是通过一个叫做日志记录器(Logger)的实例对象创建的,每个记录器都有一个名称,直接使用logging来记录日志时,系统会默认创建 名为 root 的记录器,这个记录器是根记录器。记录器支持层级结构,子记录器通常不需要单独设置日志级别以及Handler(后面会介绍),如果子记录器没有单独设置,则它的行为会委托给父级。

记录器名称可以是任意名称,不过最佳实践是直接用模块的名称当作记录器的名字。

命名如下:

logger = logging.getLogger(__name__)

默认情况下,记录器采用层级结构,上句点作为分隔符排列在命名空间的层次结构中。层次结构列表中位于下方的记录器是列表中较高位置的记录器的子级。例如,有个名叫 foo 的记录器,而名字是 foo.barfoo.bar.baz,和foo.bam 的记录器都是 foo 的子级。

├─foo
│  │  main.py
│  │  __init__.py
│  │  
│  ├─bam
│  │  │  __init__.py
│  │  │  
│  │          
│  ├─bar
│  │  │  __init__.py
│  │  │  
│  │  ├─baz
│  │  │  │  __init__.py
│  │  │  │

main.py:

import foo
from foo import bar
from foo import bam
from foo.bar import baz

if __name__ == '__main__':
    pass

foo.py

import logging

logging.basicConfig()
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

logger.info("this is foo")

这里我只设置foo这个记录器的级别为INFO

bar.py

import logging

logger = logging.getLogger(__name__)
logger.info("this is bar")

其它子模块都是像bar.py一样类似的代码,都没有设置日志级别,最后的输出结果是

INFO:foo:this is foo
INFO:foo.bar:this is bar
INFO:foo.bam:this is bam
INFO:foo.bar.baz:this is baz

这是因为 foo.bar 这个记录器没有设置日志级别,就会向上找到已经设置了日日志级别的祖先,这里刚好找到父记录器foo的级别为INFO,如果foo也没设置的话,就会找到根记录器root,root默认的级别为WARGING。

7.处理器(Handler)

记录器负责日志的记录,但是日志最终记录在哪里记录器并不关心,而是交给了另一个家伙--处理器(Handler)去处理。

例如一个Flask项目,你可能会将INFO级别的日志记录到文件,将ERROR级别的日志记录到标准输出,将某些关键日志(例如有订单或者严重错误)发送到某个邮件地址通知老板。这时候你的记录器添加多个不同的处理器来处理不同的消息日志,以此根据消息的重要性发送的特定的位置。

Python内置了很多实用的处理器,常用的有:

  • 1、StreamHandler 标准流处理器,将消息发送到标准输出流、错误流
  • 2、FileHandler 文件处理器,将消息发送到文件
  • 3、RotatingFileHandler  文件处理器,文件达到指定大小后,启用新文件存储日志
  • 4、TimedRotatingFileHandler 文件处理器,日志以特定的时间间隔轮换日志文件

8.处理器操作

Handler 提供了4个方法给开发者使用,细心的你可以发现了,logger可以设置level,Handler也可以设置Level。通过setLevel可以将记录器记录的不同级别的消息发送到不同的地方去。

import logging
from logging import StreamHandler
from logging import FileHandler

logger = logging.getLogger(__name__)

# 设置为DEBUG级别
logger.setLevel(logging.DEBUG)

# 标准流处理器,设置的级别为WARAING
stream_handler = StreamHandler()
stream_handler.setLevel(logging.WARNING)
logger.addHandler(stream_handler)

# 文件处理器,设置的级别为INFO
file_handler = FileHandler(filename="test.log")
file_handler.setLevel(logging.INFO)
logger.addHandler(file_handler)

logger.debug("this is debug")
logger.info("this is info")
logger.error("this is error")
logger.warning("this is warning")

运行后,在命令行窗口输出的日志内容是:

this is error
this is warning

输出在文件的日志内容是:

this is info
this is error
this is warning

尽管我们将logger的级别设置为了DEBUG,但是debug记录的消息并没有输出,因为我给两个Handler设置的级别都比DEBUG要高,所以这条消息被过滤掉了。

9.格式器(formatter)

格式器在文章的前面部分其实已经有所介绍,不过那是通过logging.basicConfig来指定的,其实格式器还可以以对象的形式来设置在Handler上。格式器可以指定日志的输出格式,要不要展示时间,时间格式什么,要不要展示日志的级别,要不要展示记录器的名字等等,都可以通过一个格式器对消息进行格式化输出。

import logging
from logging import StreamHandler

logger = logging.getLogger(__name__)

# 标准流处理器
stream_handler = StreamHandler()
stream_handler.setLevel(logging.WARNING)

# 创建一个格式器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# 作用在handler上
stream_handler.setFormatter(formatter)
# 添加处理器
logger.addHandler(stream_handler)

logger.info("this is info")
logger.error("this is error")
logger.warning("this is warning")

注意:格式器只能作用在处理器上,通过处理器的setFromatter方法设置格式器。而且一个Handler只能设置一个格式器。是一对一的关系。而 logger 与 handler 是一对多的关系,一个logger可以添加多个handler。handler 和 logger 都可以设置日志的等级。

10.logging.basicConfig

回到最开始的地方,logging.basicConfig() 方法为我们干了啥?现在你大概能猜出来了。来看python源码中是怎么说的

Do basic configuration for the logging system.

This function does nothing if the root logger already has handlers configured. It is a convenience method intended for use by simple scripts to do one-shot configuration of the logging package.

The default behaviour is to create a StreamHandler which writes to sys.stderr, set a formatter using the BASIC_FORMAT format string, and add the handler to the root logger.

A number of optional keyword arguments may be specified, which can alter the default behaviour.

  • 1、创建一个root记录器
  • 2、设置root的日志级别为warning
  • 3、为root记录器添加StreamHandler处理器
  • 4、为处理器设置一个简单格式器
logging.basicConfig()
logging.warning("hello")

这两行代码其实就等价于:

import sys
import logging
from logging import StreamHandler
from logging import Formatter

logger = logging.getLogger("root")
logger.setLevel(logging.WARNING)
handler = StreamHandler(sys.stderr)
logger.addHandler(handler)
formatter = Formatter(" %(levelname)s:%(name)s:%(message)s")
handler.setFormatter(formatter)
logger.warning("hello")

logging.basicConfig 方法做的事情是相当于给日志系统做一个最基本的配置,方便开发者快速接入使用。它必须在开始记录日志前调用。不过如果 root 记录器已经指定有其它处理器,这时候你再调用basciConfig,则该方式将失效,它什么都不做。

11.日志配置

日志的配置除了前面介绍的将配置直接写在代码中,还可以将配置信息单独放在配置文件中,实现配置与代码分离。

日志配置文件 logging.conf

[loggers]
keys=root

[handlers]
keys=consoleHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

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

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

加载配置文件

import logging
import logging.config

# 加载配置
logging.config.fileConfig('logging.conf')

# 创建 logger
logger = logging.getLogger()

# 应用代码
logger.debug("debug message")
logger.info("info message")
logger.warning("warning message")
logger.error("error message")

输出:

2021-12-23 00:02:07,019 - root - DEBUG - debug message
2021-12-23 00:02:07,019 - root - INFO - info message
2021-12-23 00:02:07,019 - root - WARNING - warning message
2021-12-23 00:02:07,019 - root - ERROR - error message

到这里算是对logging的一次比较完整的介绍,当然,还有很多细节并没有涉及到,因此我给了几个链接供参考。

到此这篇关于详解 python logging日志模块的文章就介绍到这了,更多相关python logging日志模块内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python基础之logging模块知识总结

    前言 logging模块是Python内置的标准模块,主要用于输出脚本运行日志,可以设置输出日志的等级.日志保存路径等. 可以通过设置不同的日志等级,在 release 版本中只输出重要信息,而不显示大量的调试信息 logging 可以决定将信息输出位置和内容 logging 线程更安全 一.日志级别 级别排序:CRITICAL > ERROR > WARNING > INFO > DEBUG debug : 打印全部日志,详细信息,通常只出现在诊断问题 info : 打印info

  • Python的logging模块基本用法

    在服务器部署时,往往都是在后台运行.当程序发生特定的错误时,我希望能够在日志中查询.因此这里熟悉以下 logging 模块的用法. logging 模块定义了报告错误和状态信息的标准 API. logging 的组件 日志系统有 4 个相互交互的组件.我们需要使用 Logger 实例来向日志添加信息.触发日志会创建一个 LogRecord,用于内存中存储信息.Logger 可能有很多 Handler 对象,用于接收和处理日志记录.Handler 使用 Formatter 来输出日志记录. 向文件

  • Python logging简介详解

    目录 一.日志级别 1. 级别定义 2. 简单示例 3. 指定级别 二.基本概念 1. Logger 2. Handler 3. Formatter 三.示例 1. 日志输出至控制台 2. 日志输出至文件 四.默认Logger 总结 一.日志级别 1. 级别定义 ​ logging模块提供了5种日志级别,分别为:CRITICAL>ERROR>WARNING>INFO>DEBUG.这些级别具有不同的优先级,其中CRITICAL的优先级最高,而DEBUG的优先级最低.具体来说 debu

  • python自定义封装带颜色的logging模块

    python 自定义封装带颜色的logging模块 自己在搭建python接口自动化框架 分享一些内容过程中想自己封装一个logger方法 根据logging进行二次封装 代码如下 import logging import os import time import colorlog from logging.handlers import RotatingFileHandler # 创建文件目录 cur_path = os.path.dirname(os.path.realpath(__fi

  • 详解 python logging日志模块

    目录 1.日志简介 2.日志级别 3.修改日志级别 4.日志记录到文件 5.指定日志格式 6.记录器(logger) 7.处理器(Handler) 8.处理器操作 9.格式器(formatter) 10.logging.basicConfig 11.日志配置 转自微信公众号: Python之禅 1.日志简介 说到日志,无论是写框架代码还是业务代码,都离不开日志的记录,他能给我们定位问题带来极大的帮助. 记录日志最简单的方法就是在你想要记录的地方加上一句 print , 我相信无论是新手还是老鸟都

  • 详解 python logging日志模块

    目录 1.日志简介 2.日志级别 3.修改日志级别 4.日志记录到文件 5.指定日志格式 6.记录器(logger) 7.处理器(Handler) 8.处理器操作 9.格式器(formatter) 10.logging.basicConfig 11.日志配置 转自微信公众号: Python之禅 1.日志简介 说到日志,无论是写框架代码还是业务代码,都离不开日志的记录,他能给我们定位问题带来极大的帮助. 记录日志最简单的方法就是在你想要记录的地方加上一句 print , 我相信无论是新手还是老鸟都

  • 详解python logging日志传输

    1.生成日志并通过http传输出去(通过HTTPHandler方式): #生成并发送日志 import logging from logging.handlers import HTTPHandler import logging.config def save(): logger = logging.getLogger(__name__) # 生成一个log实例,如果括号为空则返回root logger hh = HTTPHandler(host='127.0.0.1:5000', url='

  • python logging日志模块的详解

    python logging日志模块的详解 日志级别 日志一共分成5个等级,从低到高分别是:DEBUG INFO WARNING ERROR CRITICAL. DEBUG:详细的信息,通常只出现在诊断问题上 INFO:确认一切按预期运行 WARNING:一个迹象表明,一些意想不到的事情发生了,或表明一些问题在不久的将来(例如.磁盘空间低").这个软件还能按预期工作. ERROR:更严重的问题,软件没能执行一些功能 CRITICAL:一个严重的错误,这表明程序本身可能无法继续运行 这5个等级,也

  • Python logging日志模块 配置文件方式

    在一些微服务或web服务中我们难免需要日志功能,用来记录一些用户的登录记录,操作记录,以及一些程序的崩溃定位,执行访问定位等等; Python内置 非常强大的日志模块 ==> logging 今天给大家分享一下以配置文件形式进行配置log日志 ; Centos6.7 Python3.6 logging0.5.1.2 logging模块有三个比较重要的功能组件: 1.loggers 配置文件可定义一些输出日志的appname 2.handler 过滤器,比如设置日志的分隔大小,输出位置,日志文件创

  • 详解Python中string模块除去Str还剩下什么

    string模块可以追溯到早期版本的Python. 以前在本模块中实现的许多功能已经转移到str物品. 这个string模块保留了几个有用的常量和类来处理str物品. 字符串-文本常量和模板 目的:包含用于处理文本的常量和类. 功能 功能capwords()将字符串中的所有单词大写. 字符串capwords.py import string s = 'The quick brown fox jumped over the lazy dog.' print(s) print(string.capw

  • 详解Python中Addict模块的使用方法

    目录 介绍 1.安装 2.用法 3.要牢记的事情 4.属性,如键.item等 5.默认值 6.转化为普通字典 7.计数 8.更新 9.Addict 是怎么来的 介绍 Addit 是一个Python模块,除了提供标准的字典语法外,Addit 生成的字典的值既可以使用属性来获取,也可以使用属性进行设置. 这意味着你不用再写这样的字典了: body = {     'query': {         'filtered': {             'query': {              

  • 详解Python中matplotlib模块的绘图方式

    目录 1.matplotlib之父简介 2.matplotlib图形结构 3.matplotlib两种画绘图方法 方法一:使用matplotlib.pyplot 方法二:面向对象方法 1.matplotlib之父简介 matplotlib之父John D. Hunter已经去世,他的一生辉煌而短暂,但是他开发的的该开源库还在继续着辉煌.国内介绍的资料太少了,查阅了一番整理如下: 1968 出身于美国的田纳西州代尔斯堡. 之后求学于普林斯顿大学. 2003年发布Matplotlib 0.1版,初衷

  • python logging日志模块以及多进程日志详解

    本篇文章主要对 python logging 的介绍加深理解.更主要是 讨论在多进程环境下如何使用logging 来输出日志, 如何安全地切分日志文件. 1. logging日志模块介绍 python的logging模块提供了灵活的标准模块,使得任何Python程序都可以使用这个第三方模块来实现日志记录.python logging 官方文档 logging框架中主要由四个部分组成: Loggers: 可供程序直接调用的接口 Handlers: 决定将日志记录分配至正确的目的地 Filters:

  • 详解python中asyncio模块

    一直对asyncio这个库比较感兴趣,毕竟这是官网也非常推荐的一个实现高并发的一个模块,python也是在python 3.4中引入了协程的概念.也通过这次整理更加深刻理解这个模块的使用 asyncio 是干什么的? 异步网络操作并发协程 python3.0时代,标准库里的异步网络模块:select(非常底层) python3.0时代,第三方异步网络库:Tornado python3.4时代,asyncio:支持TCP,子进程 现在的asyncio,有了很多的模块已经在支持:aiohttp,ai

随机推荐