日志模块
import logging
日志级别:
日志级别 | 日志函数 | 描述 |
DEBUG | logging.debug() | 最低级别。调试排查问题时才会关注 |
INFO | logging.info() | 一般事件信息 |
WARNING | logging.warning() | 提示信息,表示可能出现的问题,不会影响程序运行 |
ERROR | logging.error() | 记录错误信息,导致程序出错 |
CRITICAL | logging.critical() | 最高级别,致命的错误,导致程序停止工作 |
logging模块默认日志级别是warning,所以只有warning及以上的级别会打印出来
logging模块提供了两种记录日志的方式:
第一种方式是使用logging提供的模块级别的函数
logging.info('msg')
第二种方式是使用Logging日志系统的四大组件
logger.info('msg')
日志模式配置:
logging.basicConfig(level=logging.DEBUG,#控制台打印的日志级别
filename='new.log',
filemode='a',##模式,有w和a,w就是写模式,每次都会重新写日志,覆盖之前的日志#a是追加模式,默认如果不写的话,就是追加模式
format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'#日志格式)
filename设置日志保存路径
filemode设置日志保存模式
level 设置日志的级别
format 设置日志的格式
如果在logging.basicConfig()设置filename 和filemode,则只会保存log到文件,不会输出到控制台。
logging库采取了模块化的设计
四大组件:记录器、处理器、过滤器、格式化器
Logger 暴露了应用程序代码能直接使用的接口。
Handler将(记录器产生的)日志记录发送至合适的目的地。
Filter提供了更好的粒度控制,它可以决定输出哪些日志记录。
Formatter 指明了最终输出中日志记录的格式。
Logger:
Logger.setLevel()指定logger将会处理的最低的安全等级日志信息, debug是最低的内置安全等级,critical是最高的内建安全等级。例如,如果严重程度为INFO,记录器将只处理INFO,WARNING,ERROR和CRITICAL消息,DEBUG消息被忽略。
Logger.addHandler()和Logger.removeHandler()从记录器对象中添加和删除处理程序对象。处理器详见Handlers。
Logger.addFilter()和Logger.removeFilter()从记录器对象添加和删除过滤器对象
Handler:
1) logging.StreamHandler -> 控制台输出
2) logging.FileHandler -> 文件输出
3) logging.handlers.RotatingFileHandler -> 按照大小自动分割日志文件,一旦达到指定的大小重新生成文件
4) logging.handlers.TimedRotatingFileHandler -> 按照时间自动分割日志文件
5)logging.handlers.HTTPHandler ->将日志消息以GET或POST的方式发送给一个HTTP服务器
6)logging.handlers.SMTPHandler ->将日志消息发送给一个指定的email地址
Formatter:
Formatter对象设置日志信息最后的规则、结构和内容,默认的时间格式为%Y-%m-%d %H:%M:%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 | 用户输出的消息 |
四大组件之间的关系:
1)日志器(logger)需要通过处理器(handler)将日志信息输出到目标位置,如:文件、sys.stdout、网络等;
2)不同的处理器(handler)可以将日志输出到不同的位置;
3)日志器(logger)可以设置多个处理器(handler)将同一条日志记录输出到不同的位置;
4)每个处理器(handler)都可以设置自己的过滤器(filter)实现日志过滤,从而只保留感兴趣的日志;
5)每个处理器(handler)都可以设置自己的格式器(formatter)实现同一条日志以不同的格式输出到不同的地方。
简单点说就是:
日志器(logger)是入口,真正干活儿的是处理器(handler),处理器(handler)还可以通过过滤器(filter)和格式器(formatter)对要输出的日志内容做过滤和格式化等处理操作。
关于exc_info, stack_info, extra关键词参数的说明:
exc_info: 其值为布尔值,如果该参数的值设置为True,则会将异常异常信息添加到日志消息中。如果没有异常信息则添加None到日志信息中。
stack_info: 其值也为布尔值,默认值为False。如果该参数的值设置为True,栈信息将会被添加到日志信息中。
extra: 这是一个字典(dict)参数,它可以用来自定义日志格式中所包含的字段,但是它的key不能与logging模块定义的字段冲突。
例:
logging.basicConfig(format="%(asctime)s - %(levelname)s - %(user)s[%(ip)s] - %(message)s", datefmt="%m/%d/%Y %H:%M:%S %p")
logging.warning(“Some one delete the log file.”, exc_info=True, stack_info=True, extra={‘user’: ‘Tom’, ‘ip’:‘47.98.53.222’})
记录日志流程:
1)创建handler:hanlder = logging.FileHandler(filename='info_log',mode='a',encoding='utf-8')
2)设置格式format:fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s", datefmt='%Y-%m-%d %H:%M:%S')
handler.setFormatter(fmt)
3)创建logger:logger = logging.Logger(name='logger的name',level=logging.INFO)
4)将handler添加到logger
logger.addHandler(handler)
5)打印日志:logger.info("我是info日志")
示例:
import logging #输出到控制台 def exportConsole(): logging.basicConfig(format='%(asctime)s - %(module)s[line:%(lineno)d] - %(levelname)s: %(message)s', level=logging.DEBUG) logging.debug("这是debug log") logging.info("这是info log") logging.warning("这是warning log") logging.error("这是error log") logging.critical("这是critical log") #输出到文件 def exportFile(): info_handler = logging.FileHandler(filename='info.log',mode='a',encoding='utf-8') fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s", datefmt='%Y-%m-%d %H:%M:%S') info_handler.setFormatter(fmt) info_logger = logging.Logger(name='logger的name',level=logging.INFO) info_logger.addHandler(info_handler) info_logger.debug("这是debug log") info_logger.info("这是info log") info_logger.warning("这是warning log") info_logger.error("这是error log") info_logger.critical("这是critical log") #同时输出到文件&控制台 def exportConsoleFile(): console_handler = logging.StreamHandler() file_handler = logging.FileHandler(filename='file.log',mode='a',encoding='utf-8') format = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s", datefmt='%Y-%m-%d %H:%M:%S') console_handler.setFormatter(format) file_handler.setFormatter(format) logger = logging.Logger(name=__name__,level=logging.INFO) logger.addHandler(console_handler) logger.addHandler(file_handler) logger.debug("这是debug log") logger.info("这是info log") logger.warning("这是warning log") logger.error("这是error log") logger.critical("这是critical log") #按周期分割日志 def exportLogTime(): from logging.handlers import TimedRotatingFileHandler import datetime time = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d') time_handler = TimedRotatingFileHandler(filename=time+".log",when='D',interval=1,backupCount=3,encoding='utf-8',atTime=datetime.time(0, 0, 0, 0)) format = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s", datefmt='%Y-%m-%d %H:%M:%S') time_handler.setFormatter(format) logger = logging.Logger(name='test',level=logging.INFO) logger.addHandler(time_handler) logger.debug("这是debug log") logger.info("这是info log") logger.warning("这是warning log") logger.error("这是error log") logger.critical("这是critical log") #捕获异常 try: value = 2 / 0 except Exception: logger.error("亲,发生错误了哟!看这里->",exc_info=True) #按大小分割日志 def exportLogSize(): from logging.handlers import RotatingFileHandler logger = logging.getLogger('sizeLog') logger.setLevel(logging.DEBUG) handler = RotatingFileHandler(filename='size.log',mode='a', maxBytes=1024, backupCount=5, encoding='utf-8', delay=False) format = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s", datefmt='%Y-%m-%d %H:%M:%S') handler.setFormatter(format) logger.addHandler(handler) logger.debug("这是debug log") logger.info("这是info log") logger.warning("这是warning log") logger.error("这是error log") logger.critical("这是critical log")
参考:
https://blog.csdn.net/qq_43552842/article/details/83795457