• Python日志模块01


    一、logging模块

    日志的作用可以简单总结为以下3点:
    1、程序调试
    2、了解软件程序运行情况,是否正常
    3、软件程序运行故障分析与问题定位

    1、日志的等级

    不同的应用程序所定义的日志等级可能会有所差别,分的详细点的会包含以下几个等级:

    级别 何时使用
    DEBUG 详细信息,典型地调试问题时会感兴趣。 详细的debug信息。
    INFO 证明事情按预期工作。 关键事件。
    WARNING 表明发生了一些意外,或者不久的将来会发生问题(如‘磁盘满了’)。软件还是在正常工作。
    ERROR 由于更严重的问题,软件已不能执行一些功能了。 一般错误消息。
    CRITICAL 严重错误,表明软件已不能继续运行了。
    NOTICE 不是错误,但是可能需要处理。普通但是重要的事件。
    ALERT 需要立即修复,例如系统数据库损坏。
    EMERGENCY 紧急情况,系统不可用(例如系统崩溃),一般会通知所有用户。

    2、日志字段信息与日志格式

    一条日志信息对应的是一个事件的发生,而一个事件通常需要包括以下几个内容:
    事件发生时间、事件发生位置、事件的严重程度–日志级别、事件内容

    上面这些都是一条日志记录中可能包含的字段信息,当然还可以包括一些其他信息,如进程ID、进程名称、线程ID、线程名称等。日志格式就是用来定义一条日志记录中包含那些字段的,且日志格式通常都是可以自定义的。

    3、logging模块的日志级别

    日志等级(level) 描述
    DEBUG 最详细的日志信息,典型应用场景是 问题诊断
    INFO 信息详细程度仅次于DEBUG,通常只记录关键节点信息,用于确认一切都是按照我们预期的那样进行工作
    WARNING 当某些不期望的事情发生时记录的信息(如,磁盘可用空间较低),但是此时应用程序还是正常运行的
    ERROR 由于一个更严重的问题导致某些功能不能正常运行时记录的信息
    CRITICAL 当发生严重错误,导致应用程序不能继续运行时记录的信息

    4、logging模块定义的模块级别的常用函数

    函数 说明
    logging.debug(msg, *args, **kwargs) 创建一条严重级别为DEBUG的日志记录
    logging.info(msg, *args, **kwargs) 创建一条严重级别为INFO的日志记录
    logging.warning(msg, *args, **kwargs) 创建一条严重级别为WARNING的日志记录
    logging.error(msg, *args, **kwargs) 创建一条严重级别为ERROR的日志记录
    logging.critical(msg, *args, **kwargs) 创建一条严重级别为CRITICAL的日志记录
    logging.log(level, *args, **kwargs) 创建一条严重级别为level的日志记录
    logging.basicConfig(**kwargs) 对root logger进行一次性配置

    5、logging.basicConfig()函数包含参数说明

    参数名称 描述
    filename 指定日志输出目标文件的文件名(可以写文件名也可以写文件的完整的绝对路径,写文件名日志放执行文件目录下,写完整路径按照完整路径生成日志文件),指定该设置项后日志信心就不会被输出到控制台了
    filemode 指定日志文件的打开模式,默认为’a’。需要注意的是,该选项要在filename指定时才有效
    format 指定日志格式字符串,即指定日志输出时所包含的字段信息以及它们的顺序。logging模块定义的格式字段下面会列出。
    datefmt 指定日期/时间格式。需要注意的是,该选项要在format中包含时间字段%(asctime)s时才有效
    level 指定日志器的日志级别
    stream 指定日志输出目标stream,如sys.stdout、sys.stderr以及网络stream。需要说明的是,stream和filename不能同时提供,否则会引发 ValueError异常
    style Python 3.2中新添加的配置项。指定format格式字符串的风格,可取值为’%’、’{‘和’$’,默认为’%’
    handlers Python 3.3中新添加的配置项。该选项如果被指定,它应该是一个创建了多个Handler的可迭代对象,这些handler将会被添加到root logger。需要说明的是:filename、stream和handlers这三个配置项只能有一个存在,不能同时出现2个或3个,否则会引发ValueError异常。

    6、logging模块中定义好的可以用于format格式字符串说明

    字段/属性名称 使用格式 描述
    asctime %(asctime)s 将日志的时间构造成可读的形式,默认情况下是‘2016-02-08 12:00:00,123’精确到毫秒
    name %(name)s 所使用的日志器名称,默认是’root’,因为默认使用的是 rootLogger
    filename %(filename)s 调用日志输出函数的模块的文件名; pathname的文件名部分,包含文件后缀
    funcName %(funcName)s 由哪个function发出的log, 调用日志输出函数的函数名
    levelname %(levelname)s 日志的最终等级(被filter修改后的)
    message %(message)s 日志信息, 日志记录的文本内容
    lineno %(lineno)d 当前日志的行号, 调用日志输出函数的语句所在的代码行
    levelno %(levelno)s 该日志记录的数字形式的日志级别(10, 20, 30, 40, 50)
    pathname %(pathname)s 完整路径 ,调用日志输出函数的模块的完整路径名,可能没有
    process %(process)s 当前进程, 进程ID。可能没有
    processName %(processName)s 进程名称,Python 3.1新增
    thread %(thread)s 当前线程, 线程ID。可能没有
    threadName %(thread)s 线程名称
    module %(module)s 调用日志输出函数的模块名, filename的名称部分,不包含后缀即不包含文件后缀的文件名
    created %(created)f 当前时间,用UNIX标准的表示时间的浮点数表示; 日志事件发生的时间–时间戳,就是当时调用time.time()函数返回的值
    relativeCreated %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数; 日志事件发生的时间相对于logging模块加载时间的相对毫秒数
    msecs %(msecs)d 日志事件发生事件的毫秒部分。logging.basicConfig()中用了参数datefmt,将会去掉asctime中产生的毫秒部分,可以用这个加上

    二、logging模块运用

    1、简单配置

    默认的日志格式为日志级别:Logger名称:用户输出消息

    import logging
    
    logging.debug("debug message")              #告警级别最低,只有在诊断问题时才有兴趣的详细信息。
    logging.info("info message")                #告警级别比debug要高,确认事情按预期进行。
    logging.warning("warning message")          #告警级别比info要高,该模式是默认的告警级别!预示着一些意想不到的事情发生,或在不久的将来出现一些问题(例如“磁盘空间低”)。该软件仍在正常工作。
    logging.error("error message")              #告警级别要比warning药膏,由于一个更严重的问题,该软件还不能执行某些功能。
    logging.critical("critical message")        #告警级别要比error还要高,严重错误,表明程序本身可能无法继续运行。
    
    
    #以上代码执行结果如下:
    WARNING:root:warning message
    ERROR:root:error message
    CRITICAL:root:critical message
    

    2、简单配置

    import logging
    logging.basicConfig(level=logging.DEBUG,
                        format="%(asctime)s %(name)s %(levelname)s %(message)s",
                        datefmt = '%Y-%m-%d  %H:%M:%S %a'    #注意月份和天数不要搞乱了,这里的格式化符与time模块相同
                        )
    logging.debug("msg1")
    logging.info("msg2")
    logging.warning("msg3")
    logging.error("msg4")
    logging.critical("msg5")
    
    
    #以上代码执行结果如下:
    2018-05-09  23:37:49 Wed root DEBUG msg1
    2018-05-09  23:37:49 Wed root INFO msg2
    2018-05-09  23:37:49 Wed root WARNING msg3
    2018-05-09  23:37:49 Wed root ERROR msg4
    2018-05-09  23:37:49 Wed root CRITICAL msg5
    

    2、升级版

    import logging
    LOG_FORMAT = "%(asctime)s %(name)s %(levelname)s %(pathname)s %(message)s "#配置输出日志格式
    DATE_FORMAT = '%Y-%m-%d  %H:%M:%S %a ' #配置输出时间的格式,注意月份和天数不要搞乱了
    logging.basicConfig(level=logging.DEBUG,
                        format=LOG_FORMAT,
                        datefmt = DATE_FORMAT ,
                        filename=r"d:	est.log" #有了filename参数就不会直接输出显示到控制台,而是直接写入文件
                        )
    logging.debug("msg1")
    logging.info("msg2")
    logging.warning("msg3")
    logging.error("msg4")
    logging.critical("msg5")
    
    
    #日志在d:目录下,日志具体内容
    2019-08-08  09:54:31 Thu  root DEBUG d:Log.py msg1 
    2019-08-08  09:54:31 Thu  root INFO d:Log.py msg2 
    2019-08-08  09:54:31 Thu  root WARNING d:Log.py msg3 
    2019-08-08  09:54:31 Thu  root ERROR d:Log.py msg4 
    2019-08-08  09:54:31 Thu  root CRITICAL d:Log.py msg5 
    

    3、日志流处理流程

    logging日志模块四大组件
    组件名称 对应类名 功能描述
    日志器 Logger 提供了应用程序可一直使用的接口
    处理器 Handler 将logger创建的日志记录发送到合适的目的输出
    过滤器 Filter 提供了更细粒度的控制工具来决定输出哪条日志记录,丢弃哪条日志记录
    格式器 Formatter 决定日志记录的最终输出格式
    最常用的配置方法如下:
    方法 描述
    Logger.setLevel() 设置日志器将会处理的日志消息的最低严重级别
    Logger.addHandler() 和 Logger.removeHandler() 为该logger对象添加 和 移除一个handler对象
    Logger.addFilter() 和 Logger.removeFilter() 为该logger对象添加 和 移除一个filter对象
    logger对象配置完成后,可以使用下面的方法来创建日志记录:
    方法 描述
    Logger.debug(), Logger.info(), Logger.warning(), Logger.error(), Logger.critical() 创建一个与它们的方法名对应等级的日志记录
    Logger.exception() 创建一个类似于Logger.error()的日志消息
    Logger.log() 需要获取一个明确的日志level参数来创建一个日志记录
    关于logger的层级结构与有效等级的说明:
    • logger的名称是一个以’.‘分割的层级结构,每个’.‘后面的logger都是’.'前面的logger的children,例如,有一个名称为 foo 的logger,其它名称分别为 foo.bar, foo.bar.baz 和 foo.bam都是 foo 的后代。
    • logger有一个"有效等级(effective level)"的概念。如果一个logger上没有被明确设置一个level,那么该logger就是使用它parent的level;如果它的parent也没有明确设置level则继续向上查找parent的parent的有效level,依次类推,直到找到个一个明确设置了level的祖先为止。需要说明的是,root logger总是会有一个明确的level设置(默认为 WARNING)。当决定是否去处理一个已发生的事件时,logger的有效等级将会被用来决定是否将该事件传递给该logger的handlers进行处理。
    • child loggers在完成对日志消息的处理后,默认会将日志消息传递给与它们的祖先loggers相关的handlers。因此,我们不必为一个应用程序中所使用的所有loggers定义和配置handlers,只需要为一个顶层的logger配置handlers,然后按照需要创建child loggers就可足够了。我们也可以通过将一个logger的propagate属性设置为False来关闭这种传递机制。
    Handler类:

    Handler对象的作用是(基于日志消息的level)将消息分发到handler指定的位置(文件、网络、邮件等)。Logger对象可以通过addHandler()方法为自己添加0个或者更多个handler对象。比如,一个应用程序可能想要实现以下几个日志需求:

    1)把所有日志都发送到一个日志文件中;

    2)把所有严重级别大于等于error的日志发送到stdout(标准输出);

    3)把所有严重级别为critical的日志发送到一个email邮件地址。这种场景就需要3个不同的handlers,每个handler复杂发送一个特定严重级别的日志到一个特定的位置。

    Handler.setLevel(lel):指定被处理的信息级别,低于lel级别的信息将被忽略
    Handler.setFormatter():给这个handler选择一个格式
    Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象

    需要说明的是,应用程序代码不应该直接实例化和使用Handler实例。因为Handler是一个基类,它只定义了素有handlers都应该有的接口,同时提供了一些子类可以直接使用或覆盖的默认行为。下面是一些常用的Handler:

    Handler 描述
    logging.StreamHandler 将日志消息发送到输出到Stream,如std.out, std.err或任何file-like对象。
    logging.FileHandler 将日志消息发送到磁盘文件,默认情况下文件大小会无限增长
    logging.handlers.RotatingFileHandler 将日志消息发送到磁盘文件,并支持日志文件按大小切割
    logging.hanlders.TimedRotatingFileHandler 将日志消息发送到磁盘文件,并支持日志文件按时间切割
    logging.handlers.HTTPHandler 将日志消息以GET或POST的方式发送给一个HTTP服务器
    logging.handlers.SMTPHandler 将日志消息发送给一个指定的email地址
    logging.NullHandler 该Handler实例会忽略error messages,通常被想使用logging的library开发者使用来避免’No handlers could be found for logger XXX’信息的出现。
    import logging
    def log():
        #创建logger,如果参数为空则返回root logger
        logger = logging.getLogger("nick")
        logger.setLevel(logging.DEBUG)  #设置logger日志等级
    
        #这里进行判断,如果logger.handlers列表为空,则添加,否则,直接去写日志
        if not logger.handlers:
            #创建handler
            fh = logging.FileHandler("test.log",encoding="utf-8")
            ch = logging.StreamHandler()
    
            #设置输出日志格式
            formatter = logging.Formatter(
                fmt="%(asctime)s %(name)s %(filename)s %(message)s",
                datefmt="%Y/%m/%d %X"
                )
    
            #为handler指定输出格式
            fh.setFormatter(formatter)
            ch.setFormatter(formatter)
    
            #为logger添加的日志处理器
            logger.addHandler(fh)
            logger.addHandler(ch)
    
        return logger #直接返回logger
    
    logger = log()
    logger.warning("泰拳警告")
    logger.info("提示")
    logger.error("错误")
    logger.debug("查错")
    

    4、按照时间自动截断并保存指定文件个数的案例

    import logging
    from logging import handlers
    
    logger = logging.getLogger(__name__)
    log_file = "timelog.log"
    #fh = handlers.RotatingFileHandler(filename=log_file,maxBytes=10,backupCount=3)
    fh = handlers.TimedRotatingFileHandler(filename=log_file,when="S",interval=5,backupCount=3) #filename定义将信息输入到指定的文件,
    # when指定单位是s(秒),interval是时间间隔的频率,单位是when所指定的哟(所以,你可以理解频率是5s);backupCount表示备份的文件个数,我这里是指定的3个文件。
    formatter = logging.Formatter('%(asctime)s %(module)s:%(lineno)d %(message)s')  #定义输出格式
    fh.setFormatter(formatter) #添加格式化输出
    logger.addHandler(fh)
    logger.warning("test1")
    logger.warning("test2")
    logger.warning("test3")
    logger.warning("test4")
    

    作者:oopp8
    链接:https://www.jianshu.com/p/e5595fd9f0e8
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 相关阅读:
    Atitit sql计划任务与查询优化器统计信息模块
    Atitit  数据库的事件机制触发器与定时任务attilax总结
    Atitit 图像处理知识点体系知识图谱 路线图attilax总结 v4 qcb.xlsx
    Atitit 图像处理 深刻理解梯度原理计算.v1 qc8
    Atiti 数据库系统原理 与数据库方面的书籍 attilax总结 v3 .docx
    Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析
    Atitit View事件分发机制
    Atitit 基于sql编程语言的oo面向对象大规模应用解决方案attilax总结
    Atitti 存储引擎支持的国内点与特性attilax总结
    Atitit 深入理解软件的本质 attilax总结 软件三原则"三次原则"是DRY原则和YAGNI原则的折
  • 原文地址:https://www.cnblogs.com/coding365/p/12872204.html
Copyright © 2020-2023  润新知