python 日志打印

参考https://www.cnblogs.com/yangliheng/p/6058436.html

1:四个主要类,使用官方文档中的概括:

  logger 提供了应用程序可以直接使用的接口;

  handler 将(logger创建的)日志记录发送到合适的目的输出;

  filter 提供了细度设备来决定输出哪条日志记录;用处不太大

  formatter 决定日志记录的最终输出格式

2:模块级函数

  logging.getLogger([name]): #返回一个logger对象,如果没有指定名字将返回root logger,最常用

  logging.basicConfig(): #给logger对象的配置管理函数 ,不常用

  logging.debug()logging.info()logging.warning()logging.error()logging.critical(): #logger的日志级别

3:logging模块的api

1)logging.getLogger([name])

返回一个logger实例,如果没有指定name,返回root logger。只要name相同,返回的logger实例都是同一个而且只有一个,即name和logger实例是一一对

应的。这意味着,无需把logger实例在各个模块中传递。只要知道name,就能得到同一个logger实例

2)logger.setLevel(lvl)——设置logger的level,

level有以下几个级别:

NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL

不同日志级别对应的数字对照

级别 数值

CRITICAL 50

ERROR 40

WARNING 30

INFO 20

DEBUG 10

NOTSET 0

如果把logger的级别设置为INFO, 那么小于INFO级别的日志都不输出, 大于等于INFO级别的日志都输出。也就意味着同一个logger实例,如果多个地方调用,会

出现很多重复的日志

3)logger.addHandler(hd)—— logger雇佣handler来帮它处理日志

handler对象负责发送相关的信息到指定目的地。Python的日志系统有多种Handler可以使用。有些Handler可以把信息输出到控制台,有些Logger可以把信息输

出到文件,还有些 Handler可以把信息发送到网络上。如果觉得不够用,还可以编写自己的Handler。可以通过addHandler()方法添加多个多handler

handler主要有以下几种:

logging.StreamHandler: #日志输出到流即控制台,可以是sys.stderr、sys.stdout

logging.FileHandler: #日志输出到文件

logging.handlers.RotatingFileHandler #日志输出到文件,并按照设定的日志文件大小切割

logging.handlers.TimedRotatingFileHandler #日志输出到文件,并按设定的时间切割日志文件

logging.handlers.SocketHandler: #远程输出日志到TCP/IP sockets

logging.handlers.DatagramHandler: #远程输出日志到UDP sockets

logging.handlers.SMTPHandler: #远程输出日志到邮件地址

logging.handlers.SysLogHandler: #日志输出到syslog

logging.handlers.NTEventLogHandler: #远程输出日志到Windows NT/2000/XP的事件日志

logging.handlers.MemoryHandler: #日志输出到内存中的制定buffer

由于StreamHandler和FileHandler是常用的日志处理方式,所以直接包含在logging模块中,而其他方式则包含在logging.handlers模块中,

handle常见调用

Handler.setLevel(lel) #指定被处理的信息级别,低于lel级别的信息将被忽略

Handler.setFormatter() #给这个handler选择一个格式

Handler.addFilter(filt)、Handler.removeFilter(filt):#新增或删除一个filter对象

4:常用配制

关于logging.basicConfig函数的常用配置:

filename: 指定日志文件名

filemode: 和file函数意义相同,指定日志文件的打开模式,'w'或'a'

datefmt: 指定时间格式,同time.strftime()

level: 设置日志级别,默认为logging.WARNING,即warning及级别更高的日志才输出

stream: 指定将日志的输出流,可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到sys.stderr,当stream和filename同时指定时,stream被

忽略

format: 指定输出的格式和内容,format可以输出很多有用信息,如上例所示:

%(name)s 打印logger名,默认为root

%(levelno)s: 打印日志级别的数值

%(levelname)s: 打印日志级别名称

%(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]

%(filename)s: 打印当前执行程序名

%(funcName)s: 打印日志的当前函数

%(lineno)d: 打印日志的当前行号

%(asctime)s: 打印日志的时间

%(message)s: 打印日志信息

%(thread)d: 打印线程ID

%(threadName)s: 打印线程名称

%(process)d: 打印进程ID

#  项目目录
basedir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))#获取根目录路径

#  日志配置
logdir = os.path.join(basedir, 'log')
logpath =os.path.join(logdir, 'apiall.log')
error =os.path.join(logdir, 'apierror.log')
logger = logging.getLogger('apiteststudy')#logger:日志对象,logging模块中最基础的对象,
# 用logging.getLogger(name)方法进行初始化,name可以不填。通常logger的名字我们对应模块名,如聊天模块、数据库模块、验证模块等。
# 打印debug 以上全部信息
logger.setLevel(logging.DEBUG)#logger对象常用方法setLevel:设置日志等级,一旦设置了日志等级,则调用比等级低的日志记录函数则不会输出
datafmt = "%Y-%m-%d %H:%M:%S"
#定义日志输出格式formatter
fm = logging.Formatter(fmt='%(asctime)s %(name)-s %(module)-s[line:%(lineno)d] %(levelname)-s -- %(message)s',datefmt=datafmt)
# 创建一个handler,用于输出到控制台,一般不用
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
#再创建一个handler,用于写入日志文件,只输出debug级别以上的日志,并调用定义的输出格式
fh = logging.handlers.TimedRotatingFileHandler(logpath, when='D', interval=1, backupCount=5,atTime=datetime.time(0, 0, 0, 0),encoding='utf-8')

# interval是时间间隔,backupCount是备份文件的个数,如果超过这个个数,就会自动删除,when是间隔的时间单位,单位有以下几种:
# S 秒、 M 分 小时、D 天、W 每星期(interval==0时代表星期一)、midnight 每天凌晨
# fh = logging.FileHandler(logpath, encoding='utf-8')
# fh.setLevel(logging.DEBUG)
fh.setFormatter(fm)
ch.setFormatter(fm)
logger.addHandler(fh)  #打印到文件
logger.addHandler(ch)  #打印到控制台
logging.getLogger("requests").setLevel(logging.WARNING)
# # 打印错误信息
f_handler = logging.handlers.TimedRotatingFileHandler(error, when='S', interval=1, backupCount=5,atTime=datetime.time(0, 0, 0, 0),encoding='utf-8')
f_handler.setLevel(logging.ERROR)
datafmt = "%Y-%m-%d %H:%M:%S"
fm = logging.Formatter(fmt='%(asctime)s %(name)-s %(module)-s[line:%(lineno)d] %(levelname)-s -- %(message)s',datefmt=datafmt)
f_handler.setFormatter(fm)
logger.addHandler(f_handler)

if __name__ == "__main__":
    logger.info('this is test')
    print("根目录:{}".format(basedir))

5.调用

import logging

import logging.config

logging.config.fileConfig("logger.conf")

logger = logging.getLogger("example01")

logger.debug('This is debug message')

logger.info('This is info message')

logger.warning('This is warning message')

from config.config import logger
           if type(res)==dict:
                try:
                    response_status_code=res['code']
                except :
                    response_status_code = None
                if response_status_code in [0, 200]:
                    logger.info("接口正常:接口返回状态码==200|0")
                    # logger.info("响应内容:%s" % res.json())
                    logger.info("响应内容:%s" % res)
                    # result = res.json()["msg"]
                    # result=res.json()
                    result = res
                    # self.assertEqual(result, 'success', msg='断言msg是否等于success')
                    logger.info('实际结果:{0} 期望结果:{1}'.format(result, 'success'))  # 带关键字

                    # print('接口响应:{0}'.format(res.json()))
                    print('接口响应:{0}'.format(res))
                    print(('实际结果:{0} 期望结果:{1}'.format(result, 'success')))
                else:
                    logger.error("接口错误:接口失败返回状态码!=200")
            else:
                response_status_code=res.status_code#返回结果为HttpResponse对象时才可用.status_code

                if response_status_code in [0,200]:
                    logger.info("接口正常:接口返回状态码==200|0")
                    # logger.info("响应内容:%s" % res.text)
                    # result = res.json()["msg"]
                    result=res.text
                    # self.assertEqual(result, 'success', msg='断言msg是否等于success')
                    logger.info('实际结果:{0} 期望结果:{1}'.format(result, 'success'))  # 带关键字

                    # print('接口响应:{0}'.format(res.text))
                    print(('实际结果:{0} 期望结果:{1}'.format(result, 'success')))
                else:
                    logger.error("接口错误:接口失败返回状态码!=200")