一直以来我用print输出日志(简单、快),久了之后就演变成了自己实现了一个日志类,输出日志、格式化到文件、每日生成新的日志文件...等功能。但是想想还是使用正规的系统的日志库比较好,就找到了logging然后简单学习了一下,本文是我在学习logging过程中整理出来的一个非常简单的demo,供给要求不复杂的同学10分钟快速入门logging。


logging简介

logging是Python自带的日志库,import logging之后就可以直接使用。


log等级说明

日志级别大小性依次是:DEBUG<INFO<WARNING<ERROR<CRITICAL。
如果设定输出日志级别是WARNING,则WARNING及之后的ERROR、CRITICAL也会输出,级别更低的DEBUG和INFO则不会输出。

日志等级(level)描述
DEBUG最详细的日志信息,典型应用场景是 问题诊断
INFO信息详细程度仅次于DEBUG,通常只记录关键节点信息,用于确认一切都是按照我们预期的那样进行工作
WARNING当某些不期望的事情发生时记录的信息(如,磁盘可用空间较低),但是此时应用程序还是正常运行的
ERROR由于一个更严重的问题导致某些功能不能正常运行时记录的信息
CRITICAL当发生严重错误,导致应用程序不能继续运行时记录的信息

format格式字符串中的字段

字段/属性名称使用格式描述
asctime%(asctime)s日志事件发生的时间--人类可读时间,如:2003-07-08
created%(created)f日志事件发生的时间--时间戳,就是当时调用time.time()函数返回的值
relativeCreated%(relativeCreated)d日志事件发生的时间相对于logging模块加载时间的相对毫秒数(目前还不知道干嘛用的)
msecs%(msecs)d日志事件发生事件的毫秒部分
levelname%(levelname)s该日志记录的文字形式的日志级别('DEBUG',|'INFO',|'WARNING',|'ERROR',|'CRITICAL')
levelno%(levelno)s该日志记录的数字形式的日志级别(10,|20,|30,|40,|50)
name%(name)s所使用的日志器名称,默认是'root',因为默认使用的是rootLogger
message%(message)s日志记录的文本内容,通过 msg % args计算得到的
pathname%(pathname)s调用日志记录函数的源码文件的全路径
filename%(filename)spathname的文件名部分,包含文件后缀
module%(module)sfilename的名称部分,不包含后缀
lineno%(lineno)d调用日志记录函数的源代码所在的行号
funcName%(funcName)s调用日志记录函数的函数名
process%(process)d进程ID
processName%(processName)s进程名称,Python3.1新增
thread%(thread)d线程ID
threadName%(thread)s线程名称

使用

# -*- coding:utf-8 -*-
import os, logging
from logging import handlers

# 实例化一个格式化器。设置日志的格式以及时间格式,输出格式化说明请看本文上方的"format格式字符串中的字段"说明
formatter = logging.Formatter('%(asctime)s [%(filename)s:%(lineno)d]-%(levelname)s: %(message)s', datefmt="%Y-%m-%d %H:%M:%S")

logger = logging.getLogger()
logger.setLevel(logging.INFO)#设置日志级别

# 一、输出日志到屏幕上。
sh = logging.StreamHandler() # 实例化StreamHandler:不给StreamHandler传参数就是往屏幕上输出
sh.setFormatter(formatter) # 设置屏幕上显示的格式
logger.addHandler(sh) # 把对象加到logger里

# 二、输出日志到按时间滚动的文件。即可以设定每天凌晨0点(每隔多少小时就)生成一个新的日志文件,并往该日志文件写入日志,周而复始。
th = handlers.TimedRotatingFileHandler(filename='mylog.log', when='midnight', encoding='utf-8') # 如果需要每天凌晨0点生成新的日志文件,就将when设为'midnight',
th.setFormatter(formatter) # 设置文件里写入的格式
logger.addHandler(th)
# TimedRotatingFileHandlerc参数说明:
# 1. interval:时间间隔
# 2. backupCount:备份文件的个数,如果超过这个个数就会自动删除
# 3. when:间隔的时间单位,when的值有以下几种:S 秒、M 分、H 小时、D 天、W 每星期(interval==0时代表星期一)、midnight 每天凌晨

# 三、输出日志到文件,使用FileHandler,并设定该handler的级别为ERROR,至少要ERROR以上的日志级别才写入该文件
f_handler = logging.FileHandler(f"mylog_error.log", encoding='utf-8') # 设置输出的文件名和编码方式,如果不设置编码方式,则中文字符串就会是乱码
f_handler.setLevel(logging.ERROR)
f_handler.setFormatter(formatter)
logger.addHandler(f_handler)


# 输出日志
logger.debug('这是debug级别的日志')
logger.info('这是info级别的日志')
logger.error('这是error级别的日志')
logger.warning('这是warning级别的日志')
logger.critical('这是critical级别的日志')

Q.E.D.


做一个热爱生活的人