封装log方法
1 import logging 2 import os.path 3 import time 4 5 6 project_path = 'selenium_framework_demo_lianxi' #定义项目目录 7 8 class Logger(object): 9 def __init__(self, logger): 10 """ 11 指定保存日志的文件路径,日志级别,以及调用文件 12 将日志存入到指定的文件中 13 :param logger: 14 """ 15 16 # 创建一个logger 17 self.logger = logging.getLogger(logger) 18 self.logger.setLevel(logging.DEBUG) 19 20 # 返回当前时间 21 current_time = time.strftime('%Y%m%d%H%M', time.localtime(time.time())) 22 # 返回当前目录 23 current_path = os.path.dirname(os.path.abspath(project_path)) 24 # 指定分隔符对字符串进行切片 25 path1 = current_path.split(project_path) 26 path2 = [path1[0], project_path] 27 path3 = '' 28 # 在该路径下新建下级目录 29 new_name = path3.join(path2) + '/logs/' 30 # 返回当前时间的年月日作为目录名称 31 dir_time = time.strftime('%Y%m%d', time.localtime(time.time())) 32 # 判断该目录是否存在 33 isExists = os.path.exists(new_name + dir_time) 34 if not isExists: 35 os.makedirs(new_name + dir_time) 36 print(new_name + dir_time + "目录创建成功") 37 38 else: 39 # 如果目录存在则不创建,并提示目录已存在 40 print(new_name + "目录 %s 已存在" % dir_time) 41 42 try: 43 # 创建一个handler,用于写入日志文件 44 45 # 如果case组织结构式 /testsuit/featuremodel/xxx.py , 那么得到的相对路径的父路径就是项目根目录 46 log_name = new_name + dir_time + '/' + current_time + '.log' # 定义日志文件的路径以及名称 47 48 fh = logging.FileHandler(log_name) 49 fh.setLevel(logging.INFO) 50 51 # 再创建一个handle,用于输出到控制台 52 ch = logging.StreamHandler() 53 ch.setLevel(logging.INFO) 54 55 # 定义handle的输出格式 56 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 57 fh.setFormatter(formatter) 58 ch.setFormatter(formatter) 59 60 # 给logger添加handler 61 self.logger.addHandler(fh) 62 self.logger.addHandler(ch) 63 except Exception as e: 64 print("输出日志失败! %s" % e) 65 66 # 日志接口,用户只需调用这里的接口即可,这里只定位了INFO, WARNING, ERROR三个级别的日志,可根据需要定义更多接口 67 def info(cls, msg): 68 cls.log.info(msg) 69 return 70 71 def warning(cls, msg): 72 cls.log.warning(msg) 73 return 74 75 def error(cls, msg): 76 cls.log.error(msg) 77 return 78 79 # 定义一个函数,回调logger实例 80 def getlog(self): 81 return self.logger 82 83 # 用于调试 84 # if __name__ == '__main__': 85 # logger = Logger() 86 # logger.info('This is info') 87 # logger.warning('This is warning') 88 # logger.error('This is error')
这两天在网上搜索了一些关于Python怎么写入日志,刚开始根本不知道怎么入手,就开始了解先制定了一个目标,然后根据目标开始往下学习,最终演变成了上面的版本。
一、目标:
1.日志级别
2.指定保存文件路径
3.根据时间生成相应的日志目录及日志文件
4.调用日志文件
二、了解日志的一些基本信息:
1.日志级别:
•NOTSET:0(很少用,本文不作介绍)
•DEBUG:程序调试bug时使用
•INFO:程序正常运行时使用
•WARNING:程序未按预期运行时使用,但并不是错误,如:用户登录密码错误
•ERROR:程序出错误时使用,如:IO操作失败
•CRITICAL:特别严重的问题,导致程序不能再继续运行时使用,如:磁盘空间为空,一般很少使用
默认的是WARNING等级,当在WARNING或WARNING之上等级的才记录日志信息。
一般我们在Python中调用或生成日志都要使用logging模块,所以得先了解该模块。
日志等级从低到高的顺序是:NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL
注:日志信息只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING
2.logging日志等级和输出格式的设置,且日志信息保存到日志文件:
先了解logging的框架:
•Loggers: 可供程序直接调用的接口,app通过调用提供的api来记录日志
•Handlers: 决定将日志记录分配至正确的目的地
•Filters:对日志信息进行过滤,提供更细粒度的日志是否输出的判断
•Formatters: 制定最终记录打印的格式布局
注:level 表示设置的日志等级
format 表示日志的输出格式, 参数说明:
%(levelname)s: 打印日志级别名称
%(filename)s: 打印当前执行程序名
%(lineno)d: 打印日志的当前行号
%(asctime)s: 打印日志的时间
%(message)s: 打印日志信息
filename 表示文件名
filemode 表示文件模式,参数为‘w’表示每次的日志信息都覆盖掉之前的
datefnt 表示自定义时间格式
3.logging模块自带的三个handler:
StreamHandler
作用:将日志信息输出到sys.stdout, sys.stderr 或者类文件对象(更确切点,就是能够支持write()和flush()方法的对象)
logging.StreamHandler(stream=None)
说明:
1、只有一个参数stream
2、日志信息会输出到指定的stream中,如果stream为空则默认输出到sys.stderr
FileHandler:
作用:继承自StreamHandler,将日志信息输出到磁盘文件上。
logging.FileHandler(filename=None, mode='a', encoding=None, delay=False)
说明:
模式默认为append,delay为true时,文件直到emit方法被执行才会打开。默认情况下,日志文件可以无限增大。
NullHandler:
作用:空操作handler,没有参数。
三、开始动手编写调试程序
实际上面的代码可以根据实际需要进行删减。
注:上面是我个人的学习过程,参考了许多资料。