Python 的Logging模块

今天来总结下python中保存log的方法
从Python2.3起Python的标准库加入了logging模块,logging模块给运行中的应用提供了一个标准的信息输出接口。典型的logging机制实现是把要输出的数据简单地写到一个txt文件中,写log文件的方式是一种常见的打log的方式,而logging模块提供的更多,它可以把输出信息输出到所有类文件的对象中去,包括TCP和UDP的sockets,email服务器,Unix的syslog系统,NT系列的事件log系统,内存的buffer和HTTP服务器,当然还有”真正的”文件中。
Logging库被设计成模块的方式,它提供了以下几个子模块:loggers,handlers,filters和formatters。

  1. Loggers把应用需要直接调用的接口暴露出来。
  2. Handlers把log记录发到相应的目的地。
  3. Filters决定哪些记录需要发给handler。
  4. Formatters定义了log记录的输出格式。

Loggers
Logger对象扮演了三重角色
首先,它提供给应用几个方法以便应用可以在运行时写log。
其次,Logger对象按照log信息的严重程度或者根据filter对象来决定如何处理log信息(默认的过滤功能)。
最后,logger还负责把log信息传送给相关的loghandlers。
Logger中最常使用的方法分成两部分中:configuration和message sending。

用于Configuration的方法:
setLevel(level)
addFilter(filter)
removeFilter(filter)
addHandler(handler)
removeHandler(handler)
setLevel()方法定义了一个logger处理的最低严重程度(比如说中/高/低三种,我定义为中,那么只有严重程度为中或者高的log才会被处理)。
Logging有如下级别: DEBUG,INFO,WARNING,ERROR,CRITICAL
DEBUG级别是内置的最低级别,CRITICAL是最高级别。
例如,如果严重级别设为INFO级,logger仅仅处理INFO,WARNING,ERROR和CRITICAL级的log,而DEBUG级别的则忽略掉。

根据logger对象的设置,以下的方法用来写log,方法定义如下:
debug(log_message, [*args[, **kwargs]])
info(log_message, [*args[, **kwargs]])
warning(log_message, [*args[, **kwargs]])
error(log_message, [*args[, **kwargs]])
critical(log_message, [*args[, **kwargs]])
exception(message[, *args])
log(log_level, log_message, [*args[, **kwargs]])
:log_message实际上是一个格式字符串,它可以包含诸如%s,%d,%f此类的替换符号。*args是实际要替换%s,%d,%f参数的列表。**kwargs关键字参数,logging只处理一个关键字exc_info,这个关键字决定是否对异常信息打log。
exception()和error()方法基本一样,不同之处是exception()多出一个stack trace用于转储,exception()方法只能从一个exception handler里面调用。
log()方法显式的带一个level参数,用这个可以得到比使用上面所列举的方法更为详细的log信息,这属于自定义log信息的范畴了。

Logging.getLogger([name])方法返回一个logger实例的引用,如果name参数给出则用这个参数的值作为名字,如果没有则用root做默认值。
名字是以点号分割的命名方式命名的(a.b.c)
对同一个名字的多个调用logging.getLogger()方法会返回同一个logger对象.
这种命名方式里后面的loggers是前面logger的子。例如有一个名字是foo的logger,那么诸如foo.bar,foo.bar.baz和foo.bam这样的logger都是foo这个logger的子,子loggers自动继承父loggers的log信息,正因如此,没有必要把一个应用的所有logger都配置一遍,只要把顶层的logger配置好了,然后子logger根据需要继承就行了。
例子:Log 类,用来记录log信息到文件中

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
import inspect
import traceback
class Log:
    ERROR = 'Error'
    WARNING = 'Warning'
    INFO = "Info"

    def __init__(self, logger_name, logfile):
        self.__logger_name = logger_name
        self.__logfile = logfile
        self.__get_logger()
        self.error_stack = []
        self.warning_stack = []

    def __get_logger(self):
        logger = logging.getLogger(self.__logger_name)
        logger.setLevel(logging.INFO)
        #create console handler
        ch = logging.StreamHandler()
        ch.setLevel(logging.INFO)
        #create file handle
        fh = logging.FileHandler(self.__logfile, 'a')
        fh.setLevel(logging.INFO)
        #create formatter       
        formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
        ch.setFormatter(formatter)
        fh.setFormatter(formatter)
        logger.addHandler(ch)
        logger.addHandler(fh)
        self.__logger = logger

    #如果 tag 是 Error,显示函数调用的堆栈信息
    #如果 tag 是 WARNIN, 显示函数的行号和调用方法信息。
    #如果 tag 是 INFO, 只显示message信息
    def info(self, tag, message=''):
        if tag == Log.ERROR:
            self.error_stack.append(message)
            frame = inspect.currentframe()
            stack_trace = traceback.format_stack(frame)
            self.__logger.info('[%s] %s' % (tag, message))
            self.__logger.info(''.join(stack_trace[:-1]))
        elif tag == Log.WARNING:
            self.warning_stack.append(message)
            frame = inspect.currentframe(1)
            callinfo = inspect.getframeinfo(frame)
            filename = callinfo[0]
            line_num = callinfo[1]
            function = callinfo[2]
            self.__logger.info('[%s] %s. File "%s", line %d, in %s'
                        % (tag, message, filename, line_num, function))
        else:
            self.__logger.info('[%s] %s' % (tag, message))

    def summary(self):
        self.__count(Log.WARNING, self.warning_stack)
        self.__count(Log.ERROR, self.error_stack)

    def __count(self, name, stack):
        num = len(stack)
        if num != 0:
            self.__logger.info("Total %d %s" % (num, name))
            for item in stack:
                self.__logger.info("[%s] %s" % (name, item))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值