logging模块的使用 2021-03-10

日志的级别:

  • DEBUG
  • INFO
  • WARNNING
  • ERROR
  • CRITICAL
作者代码可以见 代码

几个重要的概念

    1. Logger:记录器,是应用程序直接使用的借口
    1. Handler处理器,将(记录器)产生的日志记录发送往合适的借口
    1. Filter:过滤器,提供更好的输出控制,可以决定输出哪些日志记录
Logger

 Logger是一个树级的结构,使用debug,info等前一定要创建Logger实例,即创建一个记录器。如果没有显式的创建,默认创建一个root logger,并应用默认的日志级别(WARN),处理器Handler(StreamHandler,即讲日志信息打印输出在标准的输出上),和格式化器(默认的格式是第一个简单使用程序中输出的样式)。

#创建方法:
logger = logging.getLogger(logger_name)

 创建Logger实例后,可以使用如下的方法设置日志级别,增加处理器Handler。

  • logger.setLevel(logging.DEBUG)
  • logger.addHadnler(handler_name)
  • logger.removeHandler(handler_name)
Handler处理器

 Handler的处理器类型有很多种,常见有三个,Streamhandler,FileHandler,NullHandler
 创建StreamHandler后可以使用如下的方法设置日志级别(level),格式化器(Formatter),过滤器(Filter):

  • ch.setLevel(logging.WARN)
  • ch.setFormatter(formatter_name)
  • ch.addFilter(filter_name)
  • ch.removeFilter(filter_name)
#StreamHandler的创建方法:
sh = logging.StreamHandler(stream=None)
#FileHandler创建方法
fh = logging.FileHandler(filename,mode='a',encoding=None,delay=False)
#NullHandler创建方法
这玩意没什么用,由库开发者使用
Formatter格式化器

 使用Formatter对象设置日志信息的最后贵的,结构和内容,默认的时间格式位%Y-%m-%d%H:%M:%S

#创建方法:
formatter = logging.Formatter(fmt=None,datafmt=None)
其中fmt是消息的格式化串,datafmt是日志字符串,如果不指定fmt将会使用%(message)s' 如果不指明datefmt将使ISO8601的日期格式。
Filter过滤器

 Handler和Logger都可以使用Filter完成比级别完成更复杂的过滤,Filter基类仅允许指定Logger层次一下的事件,例如使用'A.B'初始化的Filter允许Logger ‘A.B’, ‘A.B.C’, ‘A.B.C.D’, ‘A.B.D’等记录的事件,logger‘A.BB’, ‘B.A.B’ 等就不行。 如果用空字符串来初始化,所有的事件都接受。

filter = logger.Filter(name=' ')

Logger Handler Filte Formatter几种关系,该关系可以使用如下图进行描述:

几种实例之间的关系

由上图可以知,Logger是一个树形的结构,Logger可以包括多个Handler和Filter,一个Handler可以有多个Formatter和Filter,并且日志级别将会继承。

Logging的工作流程

Logging的工作流程
    1. 由上图可以知道,如果使用者的代码中产生了日志提交,首先进行判断登记等级是否大于Logger实例的等价,如果小于,会抛弃这个日志,否则进入下一步.
    1. 创建日志,使用注册到Logger中的Filter进行过滤,轮流进行过滤,如果有一个把他过滤掉了,终止。否则等所有的过滤完成后进入下一步。
    1. 日子继续往下流
    • 日志流向所有注册在Logger中的Handlers,首先判断等级够不够,接着判断有没有过滤器,都不能拒绝日志的话,将会格式化输出(会产生额外的信息,比如在哪个文件那一行等)。
    1. 判断日志能够进行传播,如果可以并且有父类Logger,那么将会送入父类进行处理。

几种配置方式

#下面是一些模块级别的函数:
getLogger返回指定name的日志记录器,name=None时候返回层级结构总为根级别的记录器,如果指定了name,name一般是用a. a.b a.b.c.d,这些名称自定义
logging.getLogger(name=None)

logging.GetLoggerClass() 返回标准的Logger类
常见的logging.debug('')都是在根记录器中产生消息

logging.disable(level=logging.CRITICAL),以为重载的形式会作用在所有的Logger,一般用来限制全局
logging.addLevelName(level,levelName) 自己定义一个等级对应的名字,如30对应一个MyDebug
logging.basicConfig(**   kwags) 使用磨人的Formatte创建一个StreamHandler并加入根日志记录起,如果没有为跟记录器定已处理程序,那么debug()等会自动调用basicConfig。如果根日志记录器配置了处理程序,不执行任何操作。
#logging.shutdown

 上述提到的支持一下参数:

名字 功能
filename 指定日志输出目标文件的文件名,指定该设置项后日志信心就不会被输出到控制台了
filemode 指定日志文件的打开模式,默认为'a'。需要注意的是,该选项要在filename指定时才有效
format 指定日志格式字符串,即指定日志输出时所包含的字段信息以及它们的顺序。logging模块定义的格式字段下面会列出。
datafmt 指定日期/时间格式。需要注意的是,该选项要在format中包含时间字段%(asctime)s时才有效
level 指定日志器的日志级别
stream 可以指定日志输出目标stream,如sys.stdout、sys.stderr以及网络stream。需要说明的是,stream和filename不能同时提供,否则会引发 ValueError异常
handlers 该选项如果被指定,它应该是一个创建了多个Handler的可迭代对象,这些handler将会被添加到root logger。需要说明的是:filename、stream和handlers这三个配置项只能有一个存在,不能同时出现2个或3个,否则会引发ValueError异常。
encoding
errors
format参数中可能用到的格式化串:
  • %(name)s Logger的名字
  • %(levelno)s 数字形式的日志级别
  • %(levelname)s 文本形式的日志级别
  • %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
  • %(filename)s 调用日志输出函数的模块的文件名
  • %(module)s 调用日志输出函数的模块名
  • %(funcName)s 调用日志输出函数的函数名
  • %(lineno)d 调用日志输出函数的语句所在的代码行
  • %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
  • %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
  • %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
  • %(thread)d 线程ID。可能没有
  • %(threadName)s 线程名。可能没有
  • %(process)d 进程ID。可能没有
  • %(message)s用户输出的消息

一个例子

# -*- encoding:utf-8 -*-
import logging

# create logger
logger_name = "example"
logger = logging.getLogger(logger_name)
logger.setLevel(logging.DEBUG)

# create file handler
log_path = "./log.log"
fh = logging.FileHandler(log_path)
fh.setLevel(logging.WARN)

# create formatter
fmt = "%(asctime)-15s %(levelname)s %(filename)s %(lineno)d %(process)d %(message)s"
datefmt = "%a %d %b %Y %H:%M:%S"
formatter = logging.Formatter(fmt, datefmt)

# add handler and formatter to logger
fh.setFormatter(formatter)
logger.addHandler(fh)

# print log info
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')```

##### 文件配置
配置文件logging.conf如下:
```[loggers]
keys=root,example01

[logger_root]
level=DEBUG
handlers=hand01,hand02

[logger_example01]
handlers=hand01,hand02
qualname=example01
propagate=0

[handlers]
keys=hand01,hand02

[handler_hand01]
class=StreamHandler
level=INFO
formatter=form02
args=(sys.stderr,)

[handler_hand02]
class=FileHandler
level=DEBUG
formatter=form01
args=('log.log', 'a')

[formatters]
keys=form01,form02

[formatter_form01]
format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s```

使用程序logger.py如下:
```#!/usr/bin/python
# -*- encoding:utf-8 -*-
import logging
import logging.config

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

# create logger
logger_name = "example"
logger = logging.getLogger(logger_name)

logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')```

##### 字典配置
有兴趣的童靴可以使用```logging.config.dictConfig(config)```编写一个示例程序发给我,以提供给我进行完善本文。

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

推荐阅读更多精彩内容