Python 日志

文章介绍了如何在Python中实现日志功能,包括通过函数调用栈获取信息,改变print函数的输出颜色,以及使用logging库进行日志记录,特别讨论了自定义句柄和默认句柄的使用方法。
摘要由CSDN通过智能技术生成

欢迎访问我的博客首页


1. 通过函数调用栈实现


  traceback 库记录着 Python 的调用栈。使用 traceback,不仅可以输出日志位置,还可以输出函数调用栈。

import traceback, time, os

def selfLog(*logs, toFile=True):
    tracebackinfo = str(traceback.extract_stack()[-2])
    begin = tracebackinfo.index('file')
    end = tracebackinfo.rindex(' in')
    tracebackinfo = tracebackinfo[begin:end]
    times = time.strftime('%Y/%m/%d %H:%M:%S', time.localtime())
    if toFile:
        tracebackinfo = 'file ' + os.path.basename(tracebackinfo)
        handle = open('log.txt', 'a')
        handle.write('-- log: %s, %s\n' % (tracebackinfo, times))
        handle.write('    ')
        for log in logs[:-1]:
            handle.write('%s ' % log)
        handle.write('%s\n' % logs[-1])
        handle.close()
        return
    print('-- log: %s, %s' % (tracebackinfo, times))
    print('   ', end='')
    for log in logs[:-1]:
        print('%s' % log, end=' ')
    print(logs[-1])

  假如上面的代码在 selfLog.py 中,调用者代码:

from selfLog import selfLog
selfLog('abcd')
selfLog('abc', 'def')

  可以看出,我们可以像使用 print 语句一样使用 selfLog:输出单个对象、逗号隔开的多个对象、格式化输出对象。

2. 改变 print 函数输出字体的颜色


  python 可以指定 print 字体颜色,代码 selfLog.py:

import config
import time, traceback
from colorama import init

init(autoreset=True)

def getColor(rank):
    manner = 1
    foreground = 30  # [30, 37]
    background = 47  # [40, 47]
    foreground += rank % 8
    background -= rank % 8
    # color = '\033[%d;%d;%dm' % (manner, foreground, background)
    color = '\033[%d;%dm' % (manner, foreground)
    return color

def selfLog(rank, *logs):
    if rank < config.selfLogRank:
        return
    tracebackinfo = str(traceback.extract_stack()[-2])
    begin = tracebackinfo.index('file')
    end = tracebackinfo.rindex(' in')
    tracebackinfo = tracebackinfo[begin:end]
    times = time.strftime('%Y/%m/%d %H:%M:%S', time.localtime())
    print('-- %s, %s' % (tracebackinfo, times))
    color = getColor(rank)
    for log in logs:
        print('   %s%s' % (color, log), end=' ')
    print()

config.py:

selfLogRank = 0

main.py:

from selfLog import selfLog

if __name__ == '__main__':
    selfLog(1, 'Reading image...', 'info_1', 'info_2')
    selfLog(3, 'Failed to read image!', 'info_1')

  调用时第一个参数 rank 不小于 config.selfLogRank 才会输出。

3. 使用 logging


  logging 是 Python 的日志库,可以很方便地把日志输出到控制台或文件中。

  使用 logging 库,可以输出单个字符串、数字、变量等对象,但不能输出逗号隔开的多个对象。如果想输出多个对象,需要使用格式化输出。

3.1 自定义名称的句柄


  标准库 logging 有一个 logger,该 logger 有一个名称为 root 的默认句柄。句柄负责输出日志,可以通过 logger 添加句柄。

import time
import logging

def init_log():
    # 1.变量。
    date_fmt = '%Y/%m/%d %H:%M:%S'
    masg_fmt = '%(name)s %(pathname)s, line %(lineno)d, %(asctime)s %(levelname)-5.5s: %(message)s'
    path_log = time.strftime('%Y%m%d_%H%M%S', time.localtime()) + '.log'
    # 2.名称为 root 的默认日志。
    logging.basicConfig(filename='root_' + path_log, filemode='w', format=masg_fmt, datefmt=date_fmt,
                        level=logging.NOTSET)
    # 3.自定义名称的日志。
    logger = logging.getLogger('阿尔法公司')
    # 3.1 控制台。
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.WARNING)
    console_handler.setFormatter(fmt=logging.Formatter(fmt=masg_fmt, datefmt=date_fmt))
    logger.addHandler(console_handler)
    # 3.2 文件。
    file_handler = logging.FileHandler(filename=path_log, mode='a', encoding='utf-8')
    file_handler.setLevel(logging.ERROR)
    file_handler.setFormatter(fmt=logging.Formatter(fmt=masg_fmt, datefmt=date_fmt))
    logger.addHandler(file_handler)
    return logger

if __name__ == '__main__':
    logger = init_log()
    logging.info('logging 信息')
    logging.debug('logging 调试')
    logging.warning('logging 警告')
    logging.error('logging 错误')
    logging.critical('logging 严重错误')
    logger.info('logger 信息')
    logger.debug('logger 调试')
    logger.warning('logger 警告')
    logger.error('logger 错误')
    logger.critical('logger 严重错误')

  basicConfig 用于配置默认名为 root 的句柄。在这里配置文件名时日志将会被输出到文件,否则输出到控制台。无论使用 logging.info/debug/warning/error/critical 还是 logger.info/debug/warning/error/critical 输出,都会按 basicConfig 的配置输出到文件或控制台。

  上面使用 logger 添加的两个自定义句柄,分别把日志输出到控制台和文件。这两个句柄只能响应 logger.info/debug/warning/error/critical,不能响应 logging.info/debug/warning/error/critical。

3.2 使用默认句柄


  虽然自定义句柄可以指定名称,但我们必须获取 logger,才能使用它输出。在其它文件中使用 logger,必须先把它 import 进来。使用默认句柄时,只需在项目任意位置配置 logging,在其它文件只需 import logging 就能直接使用。

import time
import logging

def init_log():
    # 1.变量。
    date_fmt = '%Y/%m/%d %H:%M:%S'
    masg_fmt = '%(name)s %(pathname)s, line %(lineno)d, %(asctime)s %(levelname)-5.5s: %(message)s'
    path_log = time.strftime('%Y%m%d_%H%M%S', time.localtime()) + '.log'
    # 2.名称为 root 的默认日志。
    # logging.basicConfig(filename='root_' + path_log, filemode='w', format=masg_fmt, datefmt=date_fmt,
    #                     level=logging.NOTSET)
    # 3.自定义名称的日志。
    # logger = logging.getLogger('阿尔法公司')
    # 3.1 控制台。
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.WARNING)
    console_handler.setFormatter(fmt=logging.Formatter(fmt=masg_fmt, datefmt=date_fmt))
    logging.getLogger().addHandler(console_handler)
    # 3.2 文件。
    file_handler = logging.FileHandler(filename=path_log, mode='a', encoding='utf-8')
    file_handler.setLevel(logging.ERROR)
    file_handler.setFormatter(fmt=logging.Formatter(fmt=masg_fmt, datefmt=date_fmt))
    logging.getLogger().addHandler(file_handler)

if __name__ == '__main__':
    init_log()
    logging.info('logging 信息')
    logging.debug('logging 调试')
    logging.warning('logging 警告')
    logging.error('logging 错误')
    logging.critical('logging 严重错误')

4. 参考


  1. print 颜色
  2. logging 级别,博客园,2019。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值