Python logging 日志模块总结


本文转至 余子越的博客 ,文章 Python logging 日志模块总结,欢迎访问yuchaoshui.com 了解更多信息!

一、logging 模块四个概念

   logging模块包括logger,handler,filter,formatter这四个基本概念。

  • logger
    提供日志接口,供应用代码使用。logger最长用的操作有两类:配置和发送日志消息。可以通过logging.getLogger(name)获取logger对象,如果不指定name则返回root对象,多次使用相同的name调用getLogger方法返回同一个logger对象。

  • handler
    将日志记录(log record)发送到合适的目的地(destination),比如文件,socket等。一个logger对象可以通过addHandler方法添加0到多个handler,每个handler又可以定义不同日志级别,以实现日志分级过滤显示。

  • filter
    提供一种优雅的方式决定一个日志记录是否发送到handler。

  • formatter
    指定日志记录输出的具体格式。formatter的构造方法需要两个参数:消息的格式字符串和日期字符串,这两个参数都是可选的。

二、创建日志步骤详细说明

1. 创建logger

  • 创建logger
    logger是最终使用在代码中的实例。logging.getLogger() 用于获取logger实例,如果参数为空则返回root logger。如果参数相同则获取的是同一个实例,比如logging.getLogger("AppName1")logging.getLogger("AppName1") 在不同的地方执行获取到的是同一个实例。
logger = logging.getLogger()
logger1 = logging.getLogger("AppName1")
logger2 = logging.getLogger("AppName2")


  • 设置日志级别
    日志级别也可以用数字代替,分别对应为 {'DEBUG':10, 'INFO':20, 'WARNING':30, 'ERROR':40, 'CRITICAL':50} 。只有高于设置的日志级别才会被打印出来。
logger.setLevel(logging.DEBUG)
logger1.setLevel(logging.INFO)
logger2.setLevel(logging.WARNING)


2. 创建handler

  • 创建handler
    将日志记录发送到合适的目的地,比如文件、标准输出、标准错误。可以同时创建多个handler,将多个handler添加到同一个logger实例里面,这样这个logger就可以控制多个日志输出了(文件、控制台)。FileHandler 写入文件。StreamHandler 输入到控制台,可以是sys.stderr sys.stdout
file_handler = logging.FileHandler("app.log")
console_handler1 = logging.StreamHandler()
console_handler2 = logging.StreamHandler(sys.stderr)
console_handler3 = logging.StreamHandler(sys.stdout)


  • 创建日志格式
fmt = logging.Formatter(
    '%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)-8s %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S')

file_handler.setFormatter(fmt)
console_handler1.setFormatter(fmt)
console_handler2.setFormatter(fmt)
console_handler3.setFormatter(fmt)


3. 将handler加入logger

  将 handler 加入logger实例后上面的操作才会有效,且这几个handler是同时生效的。

logger.addHandler(file_handler)
logger.addHandler(console_handler1)
logger.addHandler(console_handler2)
logger.addHandler(console_handler3)


4. 在自己应用中使用logger

   在需要的地方记录日志

logger.debug('This is debug message')
logger.info('This is info message')
logger.warn('This is warning message')
logger.error('This is warning error')
logger.critical('This is critical error')


5. 一个完整的日志记录

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

import logging

logger = logging.getLogger("AppName")
logger.setLevel(logging.INFO)

fmt = logging.Formatter(
    '%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)-8s %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S')

file_handler = logging.FileHandler("app.log")
file_handler.setFormatter(fmt)

logger.addHandler(file_handler)

logger.debug('This is debug message')
logger.info('This is info message')
logger.warn('This is warning message')
logger.error('This is warning error')
logger.critical('This is critical error')


三、 format 可选参数列表

%(name)s  Logger的名字
%(levelno)s  数字形式的日志级别
%(levelname)s  文本形式的日志级别
%(pathname)s  调用日志输出函数的模块的完整路径名,可能没有
%(filename)s  调用日志输出函数的模块的文件名
%(module)s  调用日志输出函数的模块名
%(funcName)s  调用日志输出函数的函数名
%(lineno)d  调用日志输出函数的语句所在的代码行
%(created)f  当前时间,用UNIX标准的表示时间的浮 点数表示
%(relativeCreated)d  输出日志信息时的,自Logger创建以 来的毫秒数
%(asctime)s  字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(thread)d  线程ID。可能没有
%(threadName)s  线程名。可能没有
%(process)d  进程ID。可能没有
%(message)s  用户输出的消息

filename: 指定日志文件名
filemode: 和file函数意义相同,指定日志文件的打开模式,'w'或'a'
format: 指定输出的格式和内容,format可以输出很多有用信息
datefmt: 指定时间格式,同time.strftime()
level: 设置日志级别,默认为logging.WARNING
stream: 指定将日志的输出流,可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到sys.stderr,当stream和filename同时指定时,stream被忽略


四、根据文件大小切分日志

   RotatingFileHandler 的构造函数定义如下:

logging.handlers.RotatingFileHandler(self, filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=0)
  • maxBytes=1024*1024*50 表示 50M 大小。
  • mode='a'表示追加模式。
  • maxBytes 表示字节数。
  • backupCount 表示备份文件数。

  • 下面是一个根据文件大小来切分日志文件的例子

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

import time
import logging
import logging.handlers

logger = logging.getLogger("AppName")
logger.setLevel(logging.INFO)

fmt = logging.Formatter(
    '%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)-8s %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S')

file_handler = logging.handlers.RotatingFileHandler("app.log", mode="a", maxBytes=1000, backupCount=3)
file_handler.setFormatter(fmt)

logger.addHandler(file_handler)

while True:
    logger.info('This is info message!')
    time.sleep(0.5)


五、根据时间切分日志

  如果需要对日志文件根据时间进行切分,使用 TimedRotatingFileHandler, 它的构造函数定义如下:

logging.handlers.TimedRotatingFileHandler(self, filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False)
  • filename 是输出日志文件名的前缀,比如 myapp.log

  • when 是一个字符串的定义如下:

“S”: Seconds
“M”: Minutes
“H”: Hours
“D”: Days
“W”: Week day (0=Monday)
“midnight”: Roll over at midnight
  • interval 是指等待多少个单位when的时间后,Logger会自动重建文件,当然,这个文件的创建取决于filename+suffix,若这个文件跟之前的文件有重名,则会自动覆盖掉以前的文件。

  • backupCount 是保留日志个数。默认的0是不会自动删除掉日志。若设3,则在文件的创建过程中库会判断是否有超过这个3,若超过,则会从最先创建的开始删除。

  • 下面是一个根据时间来切分日志文件的例子。

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

import time
import logging
import logging.handlers

logger = logging.getLogger("AppName")
logger.setLevel(logging.INFO)

fmt = logging.Formatter(
    '%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)-8s %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S')

file_handler = logging.handlers.TimedRotatingFileHandler("app.log", when="M", interval=1, backupCount=10)
file_handler.suffix ="%Y-%m-%d_%H-%M"
file_handler.setFormatter(fmt)

logger.addHandler(file_handler)

while True:
    logger.info('This is info message!')
    time.sleep(0.5)


六、多进程写日志

多进程写日志、多进程写日志时的切分操作详情阅读 Python 日志模块应用


本文转至 余子越的博客 ,文章 Python logging 日志模块总结,欢迎访问yuchaoshui.com 了解更多信息!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值