使用python脚本日志功能

 假设要开发一个自动化脚本工具,工程结构如下,common这个package是框架功能的实现,scripts目录是我们编写的测试用例脚本(请忽略其他不相关的目录)。

  我们对日志功能的需求如下:

   1 为了便于日志的查看,每个脚本对应一个日志文件,日志文件以脚本的名字命名

   2 日志路径以及每个脚本保存的日志容量可以设置,比如设置为5mb,则超过后最老日志被自动覆盖

   3 日志功能要使用方便,减少与框架业务功能的耦合

  

  可见,os.getcwd()获取的是执行脚本的目录, sys.argv[0]是执行脚本的绝对路径名, __file__是被执行代码所在文件的绝对路径名。

  现在就清楚了,我们应该用sys.argv[0]来获取执行脚本的名字,由于获取到的是绝对路径,需要做一点处理:sys.argv[0].split(‘/’)[-1].split(‘.’)[0]

  2 日志容量问题,要实现超过容量后自动覆盖最老日志,采用logging中的rotatingfilehandler类即可,可以设置日志文件的大小,以及备份个数。

  那么日志路径和容量配置放在哪里呢?让用户直接修改rotatingfilehandler的参数显然不好,最好不要让用户修改框架文件,用户只需调用接口写自己的脚本即可。

  这里采用的方案是将配置信息写入一个文件,xml文件比较适合用来作为配置文件,用户通过修改xml文件来制定配置,日志模块从xml文件读取参数。

  这里为了方便将xml文件放入common下面,命名为config.xml,内容为:

e:\pythonlog
8
3

  读取xml文件内容,使用lxml库非常简单,后面再给出代码。

  

  3 日志功能要使用方便,减少与框架业务功能的耦合,最好就是对日志功能进行封装,只提供记录日志的接口即可。

  日志接口采用类方法的形式就可以满足上述要求,用户只需要通过类调用日志记录接口,随处调用,使用方便,并且无需定义类实例,与框架业务没有耦合。    

  有了上述分析,我们来实现日志模块。

  由于日志功能也是框架基础的一部分,我们将日志模块也放在common这个package中,在common下新建log.py文件,代码如下:

# coding: utf-8
from lxml import etree
import logging.handlers
import logging
import os
import sys
# 提供日志功能
class logger:
# 先读取xml文件中的配置数据
# 由于config.xml放置在与当前文件相同的目录下,因此通过 __file__ 来获取xml文件的目录,然后再拼接成绝对路径
# 这里利用了lxml库来解析xml
root = etree.parse(os.path.join(os.path.dirname(__file__), ‘config.xml’)).getroot()
# 读取日志文件保存路径
logpath = root.find(‘logpath’).text
# 读取日志文件容量,转换为字节
logsize = 1024*1024*int(root.find(‘logsize’).text)
# 读取日志文件保存个数
lognum = int(root.find(‘lognum’).text)
# 日志文件名:由用例脚本的名称,结合日志保存路径,得到日志文件的绝对路径
logname = os.path.join(logpath, sys.argv[0].split(‘/’)[-1].split(‘.’)[0])
# 初始化logger
log = logging.getlogger()
# 日志格式,可以根据需要设置
fmt = logging.formatter(‘[%(asctime)s][%(filename)s][line:%(lineno)d][%(levelname)s] %(message)s’, ‘%y-%m-%d %h:%m:%s’)
# 日志输出到文件,这里用到了上面获取的日志名称,大小,保存个数
handle1 = logging.handlers.rotatingfilehandler(logname, maxbytes=logsize, backupcount=lognum)
handle1.setformatter(fmt)
# 同时输出到屏幕,便于实施观察
handle2 = logging.streamhandler(stream=sys.stdout)
handle2.setformatter(fmt)
log.addhandler(handle1)
log.addhandler(handle2)
# 设置日志基本,这里设置为info,表示只有info级别及以上的会打印
log.setlevel(logging.info)
# 日志接口,用户只需调用这里的接口即可,这里只定位了info, warning, error三个级别的日志,可根据需要定义更多接口
@classmethod
def info(cls, msg):
cls.log.info(msg)
return
@classmethod
def warning(cls, msg):
cls.log.warning(msg)
return
@classmethod
def error(cls, msg):
cls.log.error(msg)
return

  来测试一下,在脚本script1和script2中分别编写下面代码:

from common.log import *
logger.info(‘this is info’)
logger.warning(‘this is warning’)
logger.error(‘this is error’)

  分别运行两个脚本,控制台输出为:

  

更多使用python脚本日志功能相关文章请关注php中文网!

Posted in 未分类

发表评论