Python-学习之路-14 Log 日志

log

logging模块

  • logging模块提供模块级别的函数记录日志
  • 包括四大组件

日志相关概念

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

log的作用

  • 通过记录和分析日志可以了解一个系统或软件程序运行情况是否正常,也可以在应用程序出现故障时快速定位问题。
  • 日志信息
    1. time
    2. 地点
    3. level
    4. 内容
  • 成熟的第三方日志
    • log4j
    • lg4php
    • logging

logging模块

  • 日志级别可自定义
  • 初始化或者写日志的时候需要指定日志级别
  • 只有级别等于或高于WARNING的时候日志才能被记录
  • 使用方式
    • 直接使用 logging()
    • loging四大组件直接定制

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进行一次性配置
  • logging.basicConfig(** kwargs)
    • 只在第一次调用的时候起作用
    • 不配做logger则使用默认值
      • 输出:sys.stderr
      • 级别:WARNING
      • 格式:level:log_name:content
# log案例
import logging
# 方法1
logging.debug("this is a debug log")
logging.info("this is a info log")
logging.warning("this is a warning log")
logging.error("this is a error log")
logging.critical("this is a critical log")

#方法2
logging.log(logging.DEBUG,"this is a debug log")
logging.log(logging.INFO,"this is a INFO log")
logging.log(logging.WARNING,"this is a WARNING log")
logging.log(logging.ERROR,"this is a ERROR log")
logging.log(logging.CRITICAL,"this is a CRITICAL log")

WARNING:root:this is a warning log
ERROR:root:this is a error log
CRITICAL:root:this is a critical log
WARNING:root:this is a WARNING log
ERROR:root:this is a ERROR log
CRITICAL:root:this is a CRITICAL log
# log案例2

import logging

#配置log的format
LOG_FORMAT = "%(asctime)s   %(levelname)s    %(message)s"
# 将日志打印级别调整至debug 并且将日志保存在log.log文件中
logging.basicConfig(filename="testlog.log",level=logging.DEBUG,format=LOG_FORMAT)
# 方法1
logging.debug("this is a debug log")
logging.info("this is a info log")
logging.warning("this is a warning log")
logging.error("this is a error log")
logging.critical("this is a critical log")

WARNING:root:this is a warning log
ERROR:root:this is a error log
CRITICAL:root:this is a critical log

logging format

asctime     %(asctime)s     日志事件发生的时间--人类可读时间,如:2003-07-08 16:49:45,896
created     %(created)f     日志事件发生的时间--时间戳,就是当时调用time.time()函数返回的值
relativeCreated     %(relativeCreated)d     日志事件发生的时间相对于logging模块加载时间的相对毫秒数(目前还不知道干嘛用的)
msecs   %(msecs)d   日志事件发生事件的毫秒部分
levelname   %(levelname)s   该日志记录的文字形式的日志级别('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')
levelno     %(levelno)s     该日志记录的数字形式的日志级别(10, 20, 30, 40, 50)
name    %(name)s    所使用的日志器名称,默认是'root',因为默认使用的是 rootLogger
message     %(message)s     日志记录的文本内容,通过 msg % args计算得到的
pathname    %(pathname)s    调用日志记录函数的源码文件的全路径
filename    %(filename)s    pathname的文件名部分,包含文件后缀
module  %(module)s  filename的名称部分,不包含后缀
lineno  %(lineno)d  调用日志记录函数的源代码所在的行号
funcName    %(funcName)s    调用日志记录函数的函数名
process     %(process)d     进程ID
processName     %(processName)s     进程名称,Python 3.1新增
thread  %(thread)d  线程ID
threadName  %(thread)s  线程名称

四大组件

  • 日志器(Logger):产生日志的一个接口
  • 处理器(Handler):把产生的日志发送到相应的目的地
  • 过滤器(Filter):更精细的控制日志输出
  • 格式器(Formatter):对输出信息进行格式化

Logger

  1. 向应用程序代码暴露几个方法,使应用程序可以在运行时记录日志消息;
  2. 基于日志严重等级(默认的过滤设施)或filter对象来决定要对哪些日志进行后续处理;
  3. 将日志消息传送给所有感兴趣的日志handlers。
  • 操作
    • Logger.setLevel() 设置日志器将会处理的日志消息的最低严重级别

    • Logger.addHandler() 和 Logger.removeHandler() 为该logger对象添加 和 移除一个handler对象

    • Logger.addFilter() 和 Logger.removeFilter() 为该logger对象添加 和 移除一个filter对象

    • Logger.debug(), Logger.info(), Logger.warning(), Logger.error(), Logger.critical() 创建一个与它们的方法名对应等级的日志记录

    • Logger.exception() 创建一个类似于Logger.error()的日志消息

    • Logger.log() 需要获取一个明确的日志level参数来创建一个日志记录

  • 如何得到一个logger对象
    • 通过Logger类的实例化方法创建一个Logger类的实例
    • logging.getLogger()方法

Handler

  • Handler对象的作用是(基于日志消息的level)将消息分发到handler指定的位置(文件、网络、邮件等)

  • 方法

    • Handler.setLevel() 设置handler将会处理的日志消息的最低严重级别
    • Handler.setFormatter() 为handler设置一个格式器对象
    • Handler.addFilter() 和 Handler.removeFilter() 为handler添加 和 删除一个过滤器对象
  • 需要说明的是,应用程序代码不应该直接实例化和使用Handler实例。因为Handler是一个基类,它只定义了素有handlers都应该有的接口,同时提供了一些子类可以直接使用或覆盖的默认行为。

    • 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'信息的出现。

Formatter

  • 直接实例化

  • 可以接触Format添加特殊内容

  • Formatter类的构造方法定义如下:

    logging.Formatter.__init__(fmt=None, datefmt=None, style='%')

  • 三个参数

    • fmt:指定消息格式化字符串,如果不指定该参数则默认使用message的原始值
    • datefmt:指定日期格式字符串,如果不指定该参数则默认使用"%Y-%m-%d %H:%M:%S"
    • style:Python 3.2新增的参数,可取值为 '%', '{'和 '$',如果不指定该参数则默认使用'%'

Filter

  • Filter可以被Handler和Logger用来做比level更细粒度的、更复杂的过滤功能。Filter是一个过滤器基类,它只允许某个logger层级下的日志事件通过过滤。
    filter(record)

使用logging四大组件记录日志

  1. 需求

    1. 要求将所有级别的所有日志都写入磁盘文件中
    2. all.log文件中记录所有的日志信息,日志格式为:日期和时间 - 日志级别 - 日志信息
    3. error.log文件中单独记录error及以上级别的日志信息,日志格式为:日期和时间 - 日志级别 - 文件名[:行号] - 日志信息
    4. 要求all.log在每天凌晨进行日志切割
  2. 分析

    1. 要记录所有级别的日志,因此日志器的有效level需要设置为最低级别--DEBUG;
    2. 日志需要被发送到两个不同的目的地,因此需要为日志器设置两个handler;另外,两个目的地都是磁盘文件,因此这两个handler都是与FileHandler相关的;
    3. all.log要求按照时间进行日志切割,因此他需要用logging.handlers.TimedRotatingFileHandler; 而error.log没有要求日志切割,因此可以使用FileHandler;
    4. 两个日志文件的格式不同,因此需要对这两个handler分别设置格式器;
import logging
import logging.handlers
import datetime

logger = logging.getLogger('mylogger')
logger.setLevel(logging.DEBUG)

rf_handler = logging.handlers.TimedRotatingFileHandler('all.log', when='midnight', interval=1, backupCount=7, atTime=datetime.time(0, 0, 0, 0))
rf_handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))

f_handler = logging.FileHandler('error.log')
f_handler.setLevel(logging.ERROR)
f_handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(filename)s[:%(lineno)d] - %(message)s"))

logger.addHandler(rf_handler)
logger.addHandler(f_handler)

logger.debug('debug message')
logger.info('info message')
logger.warning('warning message')
logger.error('error message')
logger.critical('critical message')
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容