很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误、警告等信息输出.
python的logging模块提供了标准的日志接口,可以通过它存储各种格式的日志.
logging的日志可以分为 debug(), info(), warning(), error() and critical() 5个级别
Level | When it’s used |
DEBUG | Detailed information, typically of interest only when diagnosing problems. |
INFO | Confirmation that things are working as expected. |
WARNING | An indication that something unexpected happened, or indicative of some problem in the near future (e.g. ‘disk space low’). The software is still working as expected. |
ERROR | Due to a more serious problem, the software has not been able to perform some function. |
CRITICAL | A serious error, indicating that the program itself may be unable to continue running. |
import logging
logging.warning("Warnning...")
logging.error("Error...")
logging.critical("Critical...")
logging.info("Info...")
logging.debug("Debug...")
执行结果:
WARNING:root:Warnning...
ERROR:root:Error...
CRITICAL:root:Critical...
为什么info和debug没有被打印呢?
这是由于logging模块的执行级别所决定的:debug=>info=>warning=>error=>critical
import logging
logging.basicConfig(filename="app.log",level=logging.INFO)
logging.warning('is when this event was logged.')
logging.warning("Warnning...")
logging.error("Error...")
logging.critical("Critical...")
logging.info("Info...")
logging.debug("Debug...")
执行结果会保存在app.log中
WARNING:root:is when this event was logged.
WARNING:root:Warnning...
ERROR:root:Error...
CRITICAL:root:Critical...
INFO:root:Info...
此时,发现Info的信息也会被记录,这是因为在basicConfig中,设置了level=logging.INFO
意思是把日志记录级别设置为INFO,级别为info或者高于info的均会被记录
log的日志格式:
%(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 | 用户输出的消息 |
具体如下:
import logging
logging.basicConfig(format='%(asctime)s %(lineno)d %(message)s ',datefmt='%m/%d/%Y %H:%M:%S')
logging.warning('log format...')
执行结果:
02/09/2017 14:38:07 16 log format...
在python中,logging模块记录日志还涉及4个主要类:
logger:提供了应用程序可以直接使用的接口
handler:将(logger模块创建的)日志记录发送到合适的目的输出
filter:提供了细度设备来决定输出哪条日志记录
formatter:决定日志记录的最终输出格式
logger:
每个程序在输出信息之前,都会要获得一个logger,logger通常对应的程序的模块名
Logger.setLevel(‘INFO'):指定最低的日志级别,低于‘INFO’的将被忽略
Logger.addFilter(filt):添加指定的filter
Logger.removeFilter(filt):删除指定的filter
Logger.addHandler(hdlr):增加指定的Handler
Logger.removeHandler(hdlr):删除指定的Handler
Logger.debug(msg):日志级别debug
Logger.info(msg):日志级别info
Logger.warning(msg):日志级别warning
Logger.error(msg):日志级别error
Logger.critical():日志级别critical
handler:
handler对象赋值发送相关的信息到指定的目的地。python的日志系统有多种Handler可以使用:
Logging.StreamHandler([strm])
使用这个Handler可以向类似于sys.stdout或者sys.stderr的任何文件对象(file object)输出信息
strm是一个文件对象,默认是sys.stderr
Logging.FileHandler(filename[,mode])
使用这个Handler用于向一个文件输出日志信息。不过FileHandler会帮你打开这个文件
filename:是文件名,必须指定一个文件名
mode:是文件的打开方式,默认是'a',追加到文件末尾
Logging.handlers.RotaingFileHandler( filename[, mode[, maxBytes[, backupCount]]])
类似于FileHandler,但是可以管理文件大小,当文件达到一定大小之后,会自动将当前日志文件改名,然后创建一个新的同名日志文件继续输出。
filename:是文件名,必须指定一个文件名
mode:是文件的打开方式,默认是'a',追加到文件末尾
maxBytes:用于指定日志文件的最大文件大小,如果maxBytes为0,意味着文件可以无限大
backupCount:用于指定保留的备份文件的个数
Logging.handlers.TimeRotatingFileHandler( filename [,when [,interval [,backupCount]]])
与RotaingFIleHandler类似,但是不是通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就自动创建新的日志文件,重命名时,附加的是当前时间。
filename:是文件名,必须指定一个文件名
when:是一个字符串。表示时间间隔的单位,不区分大小写。它有以下取值:
S 秒
M 分
H 小时
D 天
W 每星期(interval==0时代表星期一)
midnight 每天凌晨
interval:是时间间隔
backupCount:用于指定保留的备份文件的个数