简单示例
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
# 日志级别(低到高): DEBUG 《 INFO 《 WARNING 《 ERROR 《 CRITICAL
# 如:logging.DEBUG
#
# basicConfig()函数:
# 1)传入logging.DEBUG作为level关键字参数,这将显示所有日志级别的消息(DEBUG 是最低的级别),
# 就像这样: logging.basicConfig(level=logging.DEBUG) ;将 basicConfig() 的 level 参数设置
# 为 logging.ERROR,这将只显示 ERROR 和 CRITICAL 消息,跳过 DEBUG、INFO 和 WARNING 消息。
# 2)将日志记录到文件,向basic Config() 函数接受 filename 关键字参数,就像这样:
# logging.basicConfig(
# filename='myProgramLog.txt',
# level=logging.DEBUG,
# format=' %(asctime)s - %(levelname)s - %(message)s'
# ) , 日志信息将被保存到 myProgramLog.txt 文件中。
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
# 计算一个数的阶乘
def factorial(n):
logging.debug('Start of factorial(%s%%)' % (n))
total = 1
for i in range(1, n + 1):
total *= i
logging.debug('i is ' + str(i) + ', total is ' + str(total))
logging.debug('End of factorial(%s%%)' % (n))
return total
logging.debug('Start of program')
print(factorial(5))
# 只要加入一次 logging.disable(logging.CRITICAL)调用,就可以禁止日志
# 要向 logging.disable() 传入一个日志级别,它就会禁止该级别和更低级别的所有日志消息
logging.disable(logging.CRITICAL)
logging.debug('End of program')
# 运行结果:
# 120
# 2017-10-11 11:38:56,075 - DEBUG - Start of program
# 2017-10-11 11:38:56,075 - DEBUG - Start of factorial(5%)
# 2017-10-11 11:38:56,075 - DEBUG - i is 1, total is 1
# 2017-10-11 11:38:56,075 - DEBUG - i is 2, total is 2
# 2017-10-11 11:38:56,075 - DEBUG - i is 3, total is 6
# 2017-10-11 11:38:56,075 - DEBUG - i is 4, total is 24
# 2017-10-11 11:38:56,075 - DEBUG - i is 5, total is 120
# 2017-10-11 11:38:56,075 - DEBUG - End of factorial(5%)
# 2017-10-11 11:38:56,075 - DEBUG - End of program
Python中的日志级别
默认日志级别是WARNING, logging模块只会输出指定level以上的log。
日志级别顺序:NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL;如果把looger的级别设置为INFO, 那么小于INFO级别的日志都不输出, 大于等于INFO级别的日志都输出。
logging模块
logging模块提供不同的日志级别,并可以采用不同的方式记录日志,比如文件,HTTP GET/POST,SMTP,Socket等,甚至可以自己实现具体的日志记录方式。
模块主要提供 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的构造方法需要两个参数:消息的格式字符串和日期字符串,这两个参数都是可选的。
logging.basicConfig()函数
basicConfig() 方法用于为日志系统做基本配置,有下面的参数:
filename :指定log日志输出到某个文件,而不是输出到sys.stderr中;
filemode:指定打开文件的模式,默认模式为a;a代表在文件中追加日志,w是删除原有文件,创建新文件;
format :设置日志字符串的输出格式;
level :将根记录器级别设置为指定的级别;
datefmt: 使用指定的日期/时间格式;
stream:指定日志输出到那里,如果有filename参数,忽略改参数。
模块级的效用函数。基本上将所有内容委托给根日志记录器。
logging.Logger
获取logger对象
logger = logging.getLogger(name)
不指定name返回root对象;
多次使用相同的name调用getLogger方法返回同一个logger对象;
使用__name__属性作为name
logging.Handler
handler对象负责发送相关的信息到指定目的地。
Handler.setLevel(lel):指定被处理的信息级别,低于lel级别的信息将被忽略
Handler.setFormatter():给这个handler选择一个格式
Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象
logging.Formatter
示例:
formatter = logging.Formatter(’%(asctime)s - %(levelname)s - %(message)s’)
Formatter的格式及说明:
格式 | 说明 |
---|---|
%(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 | 用户输出的消息 |
%(msecs)d | 创建时间的毫秒部分 |
logging.Filter
设置过滤器:
LOG=logging.getLogger(”chat.gui.statistic”)
console = logging.StreamHandler()
console.setLevel(logging.INFO)
formatter = logging.Formatter(’%(asctime)s %(levelname)s %(message)s’)
console.setFormatter(formatter)
filter=logging.Filter(”chat.gui”)
console.addFilter(filter)
LOG.addHandler(console)
名为“A.B”的过滤器只让名字带有 “A.B”前缀的Logger输出信息。
可以添加多个过滤器,只要有一个过滤器拒绝,日志信息就不会被输出。
在Logger中也可以添加过滤器。
每个Logger可以附加多个Handler。
使用logger控制台打印示例
import logging
# logger 的等级为 INFO
logging.basicConfig(level=logging.INFO)
# 创建logger对象
logger = logging.getLogger(__name__)
logger.info('Start reading database')
# read database here
records = {'john': 55, 'tom': 66}
logger.debug('Records: %s', records)
logger.info('Updating records ...')
# update records here
records = {'john': 44, 'tom': 55}
logger.info('Finish updating records')
输出结果:
INFO:__main__:Start reading database
INFO:__main__:Updating records ...
INFO:__main__:Finish updating records
修改(level=logging.INFO)为(level=logging.DEBUG),结果显示为:
INFO:__main__:Start reading database
DEBUG:__main__:Records: {'john': 55, 'tom': 66}
INFO:__main__:Updating records ...
INFO:__main__:Finish updating records
使用logger输出log到文件示例
import logging
import logging.handlers
LOG_FILE = 'tst.log'
# 实例化handler
handler = logging.handlers.RotatingFileHandler(LOG_FILE, maxBytes = 1024*1024, backupCount = 5)
fmt = '%(asctime)s - %(filename)s:%(lineno)s - %(name)s - %(message)s'
# 实例化formatter
formatter = logging.Formatter(fmt)
# 为handler添加formatter
handler.setFormatter(formatter)
# 获取名为tst的logger
logger = logging.getLogger('tst')
# 为logger添加handler
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
logger.info('first info message')
logger.debug('first debug message')