`

python 日志详解

阅读更多

       软件开发中通过日志记录程序的运行情况是一个开发的好习惯,对于错误排查和系统运维都有很大帮助。Python标准库自带日志模块,已经足够强大,大部分情况下,python程序的日志功能直接调用标准库的日志模块即可。《The Hitchhiker’s Guide to Python》已对“日志”进行了详细阐述,python的官方文档也对日志做了说明,但Gevin依然感觉,通过这些英文资料,还不能让初学者在短时间迅速掌握python日志模块的使用,因此按照自己的思路,把相关内容做了如下整理,并附加一些Gevin认为文档中没有说明清楚的内容。

1. 基本用法

如果开发轻量级的应用,对日志的需求也比较简单,直接参考如下示例,在相关代码逻辑中加入日志功能即可:

#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import logging

logging.debug('debug message')
logging.info('info message')
logging.warn('warn message')
logging.error('error message')
logging.critical('critical message')

output:

WARNING:root:warn message
ERROR:root:error message
CRITICAL:root:critical message

默认情况下,logging模块将日志打印到屏幕上,日志级别为WARNING(即只有日志级别等于或高于WARNING的日志信息才会输出),日志格式为 warning level:instance name:warning message

1.1 将日志记录到文件中

将日志记录到文件中,只需在调用logging模块记录日志前,做个简单的配置即可:

#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import logging

# 配置日志文件和日志级别
logging.basicConfig(filename='logger.log', level=logging.INFO)

logging.debug('debug message')
logging.info('info message')
logging.warn('warn message')
logging.error('error message')
logging.critical('critical message')

本样例在记录日志前,通过logging.basicConfig做简单配置,将日志记录到日志文件logger.log中,也修改了默认的日志等级,高于或等于INFO级别的日志信息,都会记录到日志文件中。

2. 更加完善的日志功能

2.1 几个关键概念

如果要更加灵活的使用日志模块,首先要了解日志模块是怎样工作的。 LoggerHandlerFormatterFilter是日志模块的几个基本概念,日志模块的工作原理要从这四个基本概念说起。

  • Logger 即记录器,Logger提供了日志相关功能的调用接口。
  • Handler 即处理器,将(记录器产生的)日志记录发送至合适的目的地。
  • Filter 即过滤器,提供了更好的粒度控制,它可以决定输出哪些日志记录。
  • Formatter 即格式化器,指明了最终输出中日志记录的格式。

2.1.1 Logger

Logger 即“记录器”,Logger对象实例是日志记录功能的载体,如:

#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import logging

logger = logging.getLogger('simple_example')

logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

值得一提的是,Logger对象从不直接实例化,而是通过模块级的功能logging.getLogger(name)创建Logger实例。调用 logging.getLogger(name) 功能时,如果传入的name参数值相同,则总是返回同一个Logger对象实例的引用。

如果没有显式的进行创建,则默认创建一个root logger,并应用默认的日志级别(WARN)、默认的处理器Handler(StreamHandler,即将日志信息打印输出在标准输出上),和默认的格式化器Formatter(默认的格式即为第一个简单使用程序中输出的格式)。

Logger类包含的成员和方法可以查看官方文档

2.1.2 Handler

Handler 将日志信息发送到设置的位置,可以通过Logger对象的addHandler()方法为Logger对象添加0个或多个handler。一种日志的典型应用场景为,系统希望将所有的日志信息保存到log文件中,其中日志等级等于或高于ERROR的消息还要在屏幕标准输出上显示,日志等级为CRITICAL的还需要发送邮件通知;这种场景就需要3个独立的handler来实现需求,这三个handler分别与指定的日志等级或日志位置做响应

需要一提的是,为Logger配置的handler不能是Handler基类对象,而是Handler的子类对象,常用的Handler为StreamHandlerFileHandler, 和NullHandler,Handler的全部子类及详细介绍可以查看官方文档相应页面如果需要了解更多关于Handler的信息,直接查看官方文档即可。

2.1.3 Formatter

Formatter 用于设置日志输出的格式,与前两个基本概念不同的是,该类可以直接初始化对象,即 formatter=logging.Formatter(fmt=None, datefmt=None),创建formatter时,传入分别fmtdatefmt参数来修改日志格式和时间格式,默认的日志格式为%(asctime)s - %(levelname)s - %(message)s,默认的时间格式为%Y-%m-%d %H:%M:%S

2.1.4 Filter

Filter 可用于Logger对象或Handler对象,用于提供比日志等级更加复杂的日志过滤方式。默认的filter只允许在指定logger层级下的日志消息通过过滤。例如,如果把filter设置为filter=logging.Filter('A.B'),则logger ‘A.B’, ‘A.B.C’, ‘A.B.C.D’, ‘A.B.D’ 产生的日志信息可以通过过滤,但'A.BB', 'B.A.B'均不行。如果以空字符串初始化filter,则所有的日志消息都可以通过过滤。

Filter在日志功能配置中是非必须的,只在对日志消息过滤需求比较复杂时配置使用即可。

2.2 日志产生流程

日志产生的流程逻辑参考下图即可:

logging flow

2.3 日志模块的使用

日志模块使用的关键是“日志的配置”,日志配置好后,只要调用logger.INFO()logger.ERROR()等方法即可创建日志内容。

开发者可以通过三种方法配置日志模块:

  1. 在Python代码中显示创建loggers, handlers, formatters甚至filters,并调用这几个对象中的各个配置函数来完成日志配置
  2. 将配置信息写到配置文件中,然后读取配置文件信息来完成日志配置
  3. 将配置信息写到一个Dict中,然后读取这个配置字典来完成日志配置

2.3.1 通过代码配置并使用日志模块

通过代码配置日志模块简单方便,但如果需要修改配置时,需要改代码,因此不建议在大型项目中使用这种方法。

通过代码配置日志模块可以很好的理解日志模块的工作原理,用于学习,是一个很好的案例,因此Gevin也在下文中对此详细介绍。

1. 创建Logger

import logging

# create logger
logger = logging.getLogger('simple_example')

# Set default log level
logger.setLevel(logging.DEBUG)

2. 创建Handler


# create console handler and set level to warn

ch = logging.StreamHandler()
ch.setLevel(logging.WARN)

3. 创建Fomatter

# create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

4. 配置Logger

# add formatter to ch
ch.setFormatter(formatter)

# add ch to logger
# The final log level is the higher one between the default and the one in handler
logger.addHandler(ch)

5. 使用日志模块

logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

6. 完整的例子


#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import logging

# create logger
logger = logging.getLogger('simple_example')

# Set default log level
logger.setLevel(logging.DEBUG)


ch = logging.StreamHandler()
ch.setLevel(logging.WARN)

ch2 = logging.FileHandler('logging.log')
ch2.setLevel(logging.INFO)

# create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# add formatter to ch
ch.setFormatter(formatter)
ch2.setFormatter(formatter)

# add ch to logger
# The final log level is the higher one between the default and the one in handler
logger.addHandler(ch)
logger.addHandler(ch2)

# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

2.3.2 通过配置文件配置并使用日志模块

通过配置文件配置日志模块时,配置文件通常使用.ini格式,日志模块需要调用fileConfig,即logging.config.fileConfig('logging_config.ini'),然后logger的使用方法与上面相同:


#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import logging
import logging.config

logging.config.fileConfig('logging_config.ini')

# create logger
logger = logging.getLogger('root')

# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

其中,logging_config.ini文件内容如下:

[loggers]
keys=root,simpleExample

[handlers]
keys=consoleHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[logger_simpleExample]
level=INFO
handlers=consoleHandler
qualname=simpleExample
propagate=0

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

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

通过配置文件配置日志模块,逻辑与代码中配置一样,也是把loggerhandlerformatter定义好,然后组装到一起即可,无非ini配置和代码配置时的语法不通而已,开发者在基于ini文件配置日志模块时,只要参考上面例子做相应修改即可。

2.3.3 通过Dict对象配置并使用日志模块

基于Dict对象配置日志模块在python中应用广泛,很多Django或Flask项目都采用这种方式,但很多官方文档对这种方法介绍并不多,因此,本文提供一个使用样例,以后开发中参考该样例修改一下即可。


#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import logging
import logging.config

config = {
    'version': 1,
    'formatters': {
        'simple': {
            'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'level': 'DEBUG',
            'formatter': 'simple'
        },
        'file': {
            'class': 'logging.FileHandler',
            'filename': 'logging.log',
            'level': 'DEBUG',
            'formatter': 'simple'
        },
    },
    'loggers':{
        'root': {
            'handlers': ['console'],
            'level': 'DEBUG',
            # 'propagate': True,
        },
        'simple': {
            'handlers': ['console', 'file'],
            'level': 'WARN',
        }
    }
}

logging.config.dictConfig(config)


print 'logger:'
logger = logging.getLogger('root')

logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')


print 'logger2:'
logger2 = logging.getLogger('simple')

logger2.debug('debug message')
logger2.info('info message')
logger2.warn('warn message')
logger2.error('error message')
logger2.critical('critical message')


注:

日志的严重等级

Log Level如下,严重等级为NOTSETDEBUGINFOWARNINGERRORCRITICAL, 严重程度依次递增

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

修改日志消息的格式

日志的默认显示格式为:%(asctime)s - %(name)s - %(levelname)s - %(message)s,如果只想显示日志等级和日志信息,可以把格式改为:%(levelname)s:%(message)s,想了解全部Formatter中的可用变量,请查阅LogRecord attributes

日期时间的默认格式是ISO8601,修改日期时间格式请参考 time.strftime()

分享到:
评论

相关推荐

    Python中logger日志模块详解

    logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;相比print,具备如下优点: 可以通过设置不同的日志等级,在release版本中只输出重要信息,而...

    python日志输出----logging浅析与使用.pdf

    ### Python日志输出——Logging模块浅析与使用 #### 概述 日志记录是软件开发中的重要组成部分,它能够帮助开发者追踪程序运行时的状态、调试错误以及进行性能分析等。在Python中,`logging`模块是进行日志管理的...

    python日志输出----logging浅析与使用

    ### Python日志输出详解——深入理解logging模块 在Python编程中,日志系统扮演着至关重要的角色,尤其是在处理复杂项目时。它不仅帮助开发者追踪软件运行过程中的各种事件,还能在遇到问题时提供宝贵的线索。...

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

    python的logging模块提供了灵活的标准模块,使得任何Python程序都可以使用这个第三方模块来实现日志记录。python logging 官方文档 logging框架中主要由四个部分组成: Loggers: 可供程序直接调用的接口 Handlers:...

    树莓派python程序

    此外,为了实现更好的用户体验,你还可以添加日志记录、错误处理和用户界面等功能。 总之,这个项目展示了如何利用Python和树莓派的GPIO功能,结合红外避障传感器和超声波传感器,实现一个智能避障移动平台。这不仅...

    详解Python中logging日志模块在多进程环境下的使用

    在Python编程中,日志模块`logging`是一个强大的工具,用于记录程序运行过程中的各种信息。在多进程环境中,正确地使用`logging`模块尤为重要,因为它可以帮助开发者追踪和诊断分布式系统的问题。本文将深入探讨如何...

    Python日志logging模块功能与用法详解

    Python的logging模块是用于日志记录的标准库,其功能强大且灵活,适用于各种规模和类型的项目。logging模块提供了丰富的功能,包括定义不同的日志级别、处理日志输出、过滤不必要的日志信息以及自定义日志格式,使得...

    python logging模块书写日志以及日志分割详解

    ### Python Logging 模块书写日志以及日志分割详解 #### 概述 在软件开发过程中,合理地记录日志对于排查问题、监控系统状态至关重要。Python 的 `logging` 模块提供了强大的日志处理功能,它允许开发者自定义日志...

    Python日志syslog使用原理详解

    Python的日志模块提供了一个名为`syslog`的接口,用于将程序的日志信息发送到syslog服务。syslog是一种在多用户操作系统中广泛使用的日志系统,它可以将来自不同应用程序的日志消息集中管理。在Python中使用`syslog`...

    python logging日志模块的详解

    python logging日志模块的详解 日志级别 日志一共分成5个等级,从低到高分别是:DEBUG INFO WARNING ERROR CRITICAL。 DEBUG:详细的信息,通常只出现在诊断问题上 INFO:确认一切按预期运行 WARNING:一个迹象表明,...

    Python中内置的日志模块logging用法详解

    Python的logging模块提供了通用的日志系统,可以方便第三方模块或者是应用使用。这个模块提供不同的日志级别,并可以采用不同的方式记录日志,比如文件,HTTP GET/POST,SMTP,Socket等,甚至可以自己实现具体的日志...

    【pythonPHP】Python中函数详解共7页.pdf.zip

    【Python函数详解】 在Python编程语言中,函数是组织良好、可重用的代码块,它们执行特定任务并可能接收参数。本资料“【pythonPHP】Python中函数详解共7页.pdf”深入探讨了Python中的函数概念,这对于任何Python...

    对Python定时任务的启动和停止方法详解

    ### Python定时任务的启动与停止方法详解 在Python开发中,定时任务是非常常见的需求之一,尤其是在后台服务或自动化脚本中。Python社区提供了多种库来实现定时任务,其中较为流行的是`APScheduler`。本文将详细...

    【pythonPHP】Python中函数详解共7页.pdf

    【Python函数详解】 在Python编程语言中,函数是组织良好、可重用的代码块,它们执行特定任务并可能接收参数。Python中的函数是第一类对象,这意味着它们可以被赋值给变量、作为参数传递给其他函数,甚至作为其他...

    python中日志logging模块的性能及多进程详解

    对于普通的服务器硬盘(机械磁盘,非固态硬盘),Python日志的性能瓶颈是多少呢?今天我们就来测一下。下面话不多说,来一起看看详细的介绍: 测试代码如下: #! /usr/bin/env python #coding=utf-8 # ===========...

    python装饰器详解,python装饰器笔记心得.doc

    "Python装饰器详解" Python装饰器是程序开发中经常会用到的一个功能,用好了装饰器,开发效率如虎添翼。这也是Python面试中必问的问题。但对于好多初次接触这个知识的人来讲,这个功能有点绕,自学时直接绕过去了,...

    Python脚本使用详解 中文WORD版

    **Python脚本使用详解** Python是一种高级编程语言,以其简洁明了的语法和强大的功能而闻名。本文档将深入探讨Python脚本的各个方面,旨在帮助初学者和有经验的开发者更好地理解和利用Python进行各种任务。 1. **...

    详解Python自建logging模块

    此外,还展示了Python日志的默认日志级别,包括CRITICAL、ERROR、WARNING、INFO、DEBUG和NOTSET。 接着,文章阐述了logging模块中的日志级别机制。每个logger对象都有一个日志级别属性,其输出的日志信息将只会高于...

Global site tag (gtag.js) - Google Analytics