Python中如何详细掌握logging模块的特性和应用技巧?

2026-05-27 00:521阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计3378个文字,预计阅读时间需要14分钟。

Python中如何详细掌握logging模块的特性和应用技巧?

Python 日志模块功能与用法简介

本文介绍了Python的logging模块,并分享了其基本使用方法和扩展应用。

内容概述:- logging模块介绍- logging模块的基本使用- logging模块的扩展使用- logging中的Filter- 使用配置

logging模块介绍Python的logging模块提供了强大的日志记录功能,可以记录程序运行过程中的各种信息,包括调试信息、错误信息等。

logging模块的基本使用pythonimport logging

创建loggerlogger=logging.getLogger('my_logger')logger.setLevel(logging.DEBUG) # 设置日志级别

创建handler,用于写入日志文件file_handler=logging.FileHandler('example.log')file_handler.setLevel(logging.DEBUG)

创建formatter,设置日志格式formatter=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')file_handler.setFormatter(formatter)

将handler添加到loggerlogger.addHandler(file_handler)

记录日志logger.debug('This is a debug message')logger.info('This is an info message')logger.warning('This is a warning message')logger.error('This is an error message')logger.critical('This is a critical message')

logging模块的扩展使用python创建handler,用于输出到控制台console_handler=logging.StreamHandler()console_handler.setLevel(logging.ERROR)console_handler.setFormatter(formatter)

将handler添加到loggerlogger.addHandler(console_handler)

记录日志logger.error('This is an error message')

logging中的FilterFilter允许你根据特定的条件来过滤日志记录,以下是一个简单的示例:

pythonclass MyFilter(logging.Filter): def filter(self, record): return 'error' in record.getMessage()

logger.addFilter(MyFilter())

记录日志logger.error('This is an error message')

使用配置你可以通过配置文件来设置logging模块的参数,例如:

pythonimport logging.config

配置文件内容LOGGING_CONFIG=[loggers]keys=root

[handlers]keys=file_handler,console_handler

[formatters]keys=simple_formatter

[logger_root]level=DEBUGhandlers=file_handler,console_handler

[handler_file_handler]class=FileHandlerlevel=DEBUGformatter=simple_formatterargs=('example.log', 'a')

[handler_console_handler]class=StreamHandlerlevel=ERRORformatter=simple_formatterargs=(sys.stdout,)

[formatter_simple_formatter]format=%(asctime)s - %(name)s - %(levelname)s - %(message)sdatefmt=

应用配置logging.config.fileConfig(LOGGING_CONFIG)logger=logging.getLogger('root')logger.debug('This is a debug message')logger.error('This is an error message')

本文实例讲述了Python日志logging模块功能与用法。分享给大家供大家参考,具体如下:

本文内容:

  • logging模块的介绍
  • logging模块的基础使用
  • logging模块的扩展使用
  • logging中的Filter
  • 使用配置文件配置logging和logger
  • 小技巧
  • 想要了解更多?不如看看官方文档。

首发日期:2018-07-05


logging模块的介绍:

  • 它是一个python标准库,所以它的通用性很高,所有的python模块都可以与它合作参与日志记录。

日志级别:

基本 中文意义 触发情况 DEBUG 调试 调试时期 INFO 提示 正常运行时 WARINING 警告 现在可运行,但未来可能发生错误时(例如未来存储空间可能不足) ERROR 错误 当程序发生错误,无法执行某些功能时 CRITICAL 严重的、致命的 当程序发生严重错误,无法继续运行时

默认是WARNING。

基本类:

  • Loggers :日志器,负责开放接口来调用功能,比如它负责添加Handlers和Filters 。有默认的Loggers 对象
  • Handlers :负责日志记录的传输目的地,比如有FileHandler(写入目标为文件)和StreamHandler(写入目标为流,默认为标准输出流)
  • Filters :负责过滤哪些日志是要输出的 。
  • Formatters :负责对日志输出格式的格式化。

logging模块的基础使用:

  • 基础使用使用就是使用默认logger对象的使用。
  1. 设置logging,调用logging.basicConfig()来配置日志信息。
    • 可设置的参数:filename日志文件名,filemode打开文件的方式,format日志的输出格式,datefmt日期输出格式,style设置format的类型,level日志记录的最低级别,stream输出流(不与filename并存,filename优先),handlers日志处理对象(默认是根处理对象),
    • 一般使用的参数:filename日志文件名,format日志的输出格式,level日志记录的最低级别,stream设置输出流
      • filename是日志文件名,就是一个普通文件名
      • format是日志的输出格式,设置方法下面讲
      • level的设置值为debug等值,使用方法为logging.DEBUG,logging.INFO,logging.WARNING,logging.ERROR,logging.CRITICAL
      • style影响format的类型,它的值有'%','{','$',默认是'%',不同的style可以识别以下不同的message标识符:%(message)s、{message}、$message
  2. 输出日志信息:
    • 调试级别日志信息:logging.debug(信息)
    • 提示级别信息:logging.info(信息)
    • 警告基本信息:loggin.warning(信息)
    • 错误级别信息:logging.error(信息)
    • 严重级别信息:logging.critical(信息)

信息输出的格式化(指的是logging.info等函数里面的信息):

这个表述可能不是很清晰,但意义类似程序报错信息,(假如)普通的异常信息只有一个报错原因,(那么为了方便观看)可能还需要一些如错误地点,错误事件等信息,而这些附加的统一的时间不应该由生产错误信息的部分来添加(可能有很多个模块),而应该将这个信息给专门做这事的部分来处理(交个formatter来处理)。

1.支持普通字符串%格式化,例如:

logging.info('Started %s'%tag)

2.支持普通字符串format格式化,例如:

logging.info('{} started '.format(tag))

3.logging自带的,例如:

logging.info('%s start in', tag) logging.info('%s start in %s',tag,address)

format设置方法:

  • 常用特殊字符:
    • message是日志信息
    • levelname日志信息等级
    • asctime是字符串形式的日期时间
    • name是logger的名字
    • levelno是数字形式的日志信息等级
    • module是调用日志输出函数的模块名
    • funcName是调用日志输出函数的函数名
    • lineno是调用日志输出函数的代码行数

根据不同的style,可以使用%(message)s或{message}或$message类似的格式来标注指定位置使用指定信息来取代。

  • 默认格式:
    • asctime 使用%(asctime)s
    • funcName使用%(funcName)s
    • levelname使用%(levelname)s
    • message使用%(message)s
    • lineno使用%(lineno)d
    • module使用%(module)s
    • name使用%(name)s

官方文档:

docs.python.org/3.6/library/logging.html

datefmt日期输出格式的设置方法:

设置format中特殊字符asctime(日期时间)的输出格式

  • 特殊字符:
    • %y 两位数的年份表示(00-99)
    • %Y 四位数的年份表示(000-9999)
    • %m 月份(01-12)
    • %d 月内中的一天(0-31)
    • %H 24小时制小时数(0-23)
    • %I 12小时制小时数(01-12)
    • %M 分钟数(00=59)
    • %S 秒(00-59)

使用自己想要的分隔符和顺序来定义日期时间的格式,例如:

datefmt='%m/%d/%Y %I:%M:%S %p'

使用小例子:

不使用format的:

import logging def show(): print("wechat running...") return "wechat" def main(): logging.basicConfig(filename='myapp.log', level=logging.INFO) tag=show() logging.info('Started %s'%tag) logging.info('Finished %s'%tag) if __name__ == '__main__' : main()

使用format和datefmt的:

import logging def show(): print("wechat running...") return "wechat" def main(): logging.basicConfig(filename='myapp.log', format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p',level=logging.INFO) tag=show() logging.info('%s start in', tag) logging.info('%s Finished',tag) if __name__ == '__main__' : main()

PS:虽然上面没有说到logger对象,handler对象(默认方向是标准输出流),formatter对象,但实际上,它是有默认的。不要因为默认值而搞错。所以不建议混杂基础版的和扩展版的使用。


logging模块的扩展使用:

1.导入模块:

import logging

2.获取logger对象:

logger = logging.getLogger("AppName")

在模块中使用时,官方文档中有一个这样的代码,有点意思:

logger = logging.getLogger(__name__)

3.设置最低日志输出级别:

logger.setlevel()

例如:

logger.setLevel(logging.INFO)

4.创建并绑定handler:

handler用于处理日志信息的输出方向,可以添加多个handler,代表同时向多个方向输出信息

Python中如何详细掌握logging模块的特性和应用技巧?

  • 创建handler:

输出方向为文件,使用FileHandler,例如:

logging.FileHandler("test.log")

输出方向为流,使用StreamHandler,例如:

logging.StreamHandler(sys.stdout)

PS:想了解更多Handler,可以自己查看官方文档docs.python.org/3.6/howto/logging.html

  • 绑定handler,使用addHandler():

例如:

logger.addHandler(handler)

  • 绑定后如果想解绑handler,使用removeHandler():

例如:

logger.removeHandler(handler)

5.定义handler的输出格式formatter并绑定到handler上,formatter的设置方法类似上面基础使用中的format:

  • 创建:

例如:

formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s')

  • 绑定:

handler.setFormatter(formatter) 或handler.formatter=formatter

6.将handle绑定到logger对象上。

logger.addHandler(file_handler) logger.addHandler(console_handler)

7.输出日志:

调试级别: logger.debug(信息)

提示级别: logger.info(信息)

警告级别: logger.warn(信息)

错误级别:

logger.error(信息)

logger.exception(信息)

严重级别:

logger.fatal(信息)

logger.critical(信息)

使用示例:

import logging def demo(): #获取logger对象 logger=logging.getLogger("WeChat") #设置日志等级 logger.setLevel(logging.DEBUG) #创建绑定handler handler=logging.FileHandler('wechat.log') logger.addHandler(handler) # 创建绑定formatter formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s') formatter.datefmt = '%m/%d/%Y %I:%M:%S %p' #可选的 handler.setFormatter(formatter) #尝试输出错误信息 logger.debug("debug message") logger.info("info message") logger.warning("warining message") logger.error("error message") logger.critical("critical message") if __name__=="__main__" : demo()

补充:

  • 如果你不想新建handler和formatter,可以使用basicConfig方式(可以使用basicConfig来配置所有的logger对象的handler和formatter),当要注意混杂风险。
  • logging模块中还有一个filter,由于它涉及的内容较多,单独列在下面讲。

logging中的Filter:

  • Filter用来过滤日志信息,例如你想输出A类信息,但不想输出C类信息,就可以进行过滤
  • 而由于所有的信息都有经过过滤器,也可以使用过滤器来增加一些信息。

使用方法1:建立子类

下面的例子可能不是很符合应用,仅用于举例:

过滤非允许用户的日志信息:

import logging import sys class ContextFilter(logging.Filter): def filter(self, record): if record.role=="admin" : return True else: return False if __name__ == '__main__': logger=logging.getLogger("Wechat") logger.setLevel(logging.DEBUG) handler=logging.StreamHandler(sys.stdout) formatter=logging.Formatter('%(asctime)s %(levelname)s: %(message)s Role: %(role)s') handler.setFormatter(formatter) logger.addHandler(handler) #创建绑定fiter f = ContextFilter() logger.addFilter(f) logger.info('An info message with %s', 'some parameters',extra={"role":"admin"}) logger.info('An info message with %s', 'some parameters',extra={"role":"hacker"})#hacker的被过滤掉了

官网版的加信息版本:

import logging from random import choice class ContextFilter(logging.Filter): """ This is a filter which injects contextual information into the log. Rather than use actual contextual information, we just use random data in this demo. """ USERS = ['jim', 'fred', 'sheila'] IPS = ['123.231.231.123', '127.0.0.1', '192.168.0.1'] def filter(self, record): record.ip = choice(ContextFilter.IPS) record.user = choice(ContextFilter.USERS) return True if __name__ == '__main__': levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL) logging.basicConfig(level=logging.DEBUG, format='%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s') a1 = logging.getLogger('a.b.c') a2 = logging.getLogger('d.e.f') f = ContextFilter() a1.addFilter(f) a2.addFilter(f) a1.debug('A debug message') a1.info('An info message with %s', 'some parameters') for x in range(10): lvl = choice(levels) lvlname = logging.getLevelName(lvl) a2.log(lvl, 'A message at %s level with %d %s', lvlname, 2, 'parameters')

使用方法2:使用filter函数

python3.2后,可以使用filter函数来做到上面方法1的效果

例子1:

import logging import sys def myfilter(record): if record.role == "admin": return True else: return False if __name__ == '__main__': logger=logging.getLogger("Wechat") logger.setLevel(logging.DEBUG) handler=logging.StreamHandler(sys.stdout) formatter=logging.Formatter('%(asctime)s %(levelname)s: %(message)s Role: %(role)s') handler.setFormatter(formatter) logger.addHandler(handler) #创建绑定fiter f = logging.Filter() f.filter=myfilter logger.addFilter(f) logger.info('An info message with %s', 'some parameters',extra={"role":"admin"}) logger.info('An info message with %s', 'some parameters',extra={"role":"hacker"})#hacker的被过滤掉了

例子2,利用lambda:

logger=logging.getLogger("Wechat") logger.setLevel(logging.DEBUG) handler=logging.StreamHandler(sys.stdout) formatter=logging.Formatter('%(asctime)s %(levelname)s: %(message)s Role: %(role)s') handler.setFormatter(formatter) logger.addHandler(handler) #创建绑定fiter # f = ContextFilter() f = logging.Filter() f.filter=lambda record: record.role=="admin" logger.addFilter(f) logger.info( 'An info message with %s', 'some parameters',extra={"role":"admin"}) logger.info('An info message with %s', 'some parameters',extra={"role":"hacker"})#hacker的被过滤掉了


使用配置文件配置logger对象:

注意:logging默认使用的logger对象叫做root

config文件配置方式:

import logging import logging.config logging.config.fileConfig('logging.conf') # create logger logger = logging.getLogger('simpleExample') # 'application' code logger.debug('debug message') logger.info('info message') logger.warn('warn message') logger.error('error message') logger.critical('critical message')

文件内容:

[loggers] keys=root,simpleExample [handlers] keys=consoleHandler [formatters] keys=simpleFormatter [logger_root] level=DEBUG handlers=consoleHandler [logger_simpleExample] level=DEBUG handlers=consoleHandler qualname=simpleExample propagate=0 [handler_consoleHandler] class=StreamHandler level=DEBUG formatter=simpleFormatter args=(sys.stdout,) [formatter_simpleFormatter] format=%(asctime)s - %(name)s - %(levelname)s - %(message)s datefmt=

PS:也支持YAML方式,这里不讲述


小技巧:

如果留意到过滤器例子的话,你可以发现

在formatter内可以附加参数:

输出信息时,附加一个参数extra,附加的参数可以被formatter使用

import logging import sys class ContextFilter(logging.Filter): def filter(self, record): if record.role=="admin" : return True else: return False if __name__ == '__main__': logger=logging.getLogger("Wechat") logger.setLevel(logging.DEBUG) handler=logging.StreamHandler(sys.stdout) formatter=logging.Formatter('%(asctime)s %(levelname)s: %(message)s Role: %(role)s') handler.setFormatter(formatter) logger.addHandler(handler) #创建绑定fiter f = ContextFilter() logger.addFilter(f) logger.info('An info message with %s', 'some parameters',extra={"role":"admin"}) logger.info('An info message with %s', 'some parameters',extra={"role":"hacker"})#hacker的被过滤掉了


想要了解更多?不如看看官方文档。

docs.python.org/3.6/library/logging.html

更多关于Python相关内容感兴趣的读者可查看本站专题:《Python日志操作技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》

希望本文所述对大家Python程序设计有所帮助。

本文共计3378个文字,预计阅读时间需要14分钟。

Python中如何详细掌握logging模块的特性和应用技巧?

Python 日志模块功能与用法简介

本文介绍了Python的logging模块,并分享了其基本使用方法和扩展应用。

内容概述:- logging模块介绍- logging模块的基本使用- logging模块的扩展使用- logging中的Filter- 使用配置

logging模块介绍Python的logging模块提供了强大的日志记录功能,可以记录程序运行过程中的各种信息,包括调试信息、错误信息等。

logging模块的基本使用pythonimport logging

创建loggerlogger=logging.getLogger('my_logger')logger.setLevel(logging.DEBUG) # 设置日志级别

创建handler,用于写入日志文件file_handler=logging.FileHandler('example.log')file_handler.setLevel(logging.DEBUG)

创建formatter,设置日志格式formatter=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')file_handler.setFormatter(formatter)

将handler添加到loggerlogger.addHandler(file_handler)

记录日志logger.debug('This is a debug message')logger.info('This is an info message')logger.warning('This is a warning message')logger.error('This is an error message')logger.critical('This is a critical message')

logging模块的扩展使用python创建handler,用于输出到控制台console_handler=logging.StreamHandler()console_handler.setLevel(logging.ERROR)console_handler.setFormatter(formatter)

将handler添加到loggerlogger.addHandler(console_handler)

记录日志logger.error('This is an error message')

logging中的FilterFilter允许你根据特定的条件来过滤日志记录,以下是一个简单的示例:

pythonclass MyFilter(logging.Filter): def filter(self, record): return 'error' in record.getMessage()

logger.addFilter(MyFilter())

记录日志logger.error('This is an error message')

使用配置你可以通过配置文件来设置logging模块的参数,例如:

pythonimport logging.config

配置文件内容LOGGING_CONFIG=[loggers]keys=root

[handlers]keys=file_handler,console_handler

[formatters]keys=simple_formatter

[logger_root]level=DEBUGhandlers=file_handler,console_handler

[handler_file_handler]class=FileHandlerlevel=DEBUGformatter=simple_formatterargs=('example.log', 'a')

[handler_console_handler]class=StreamHandlerlevel=ERRORformatter=simple_formatterargs=(sys.stdout,)

[formatter_simple_formatter]format=%(asctime)s - %(name)s - %(levelname)s - %(message)sdatefmt=

应用配置logging.config.fileConfig(LOGGING_CONFIG)logger=logging.getLogger('root')logger.debug('This is a debug message')logger.error('This is an error message')

本文实例讲述了Python日志logging模块功能与用法。分享给大家供大家参考,具体如下:

本文内容:

  • logging模块的介绍
  • logging模块的基础使用
  • logging模块的扩展使用
  • logging中的Filter
  • 使用配置文件配置logging和logger
  • 小技巧
  • 想要了解更多?不如看看官方文档。

首发日期:2018-07-05


logging模块的介绍:

  • 它是一个python标准库,所以它的通用性很高,所有的python模块都可以与它合作参与日志记录。

日志级别:

基本 中文意义 触发情况 DEBUG 调试 调试时期 INFO 提示 正常运行时 WARINING 警告 现在可运行,但未来可能发生错误时(例如未来存储空间可能不足) ERROR 错误 当程序发生错误,无法执行某些功能时 CRITICAL 严重的、致命的 当程序发生严重错误,无法继续运行时

默认是WARNING。

基本类:

  • Loggers :日志器,负责开放接口来调用功能,比如它负责添加Handlers和Filters 。有默认的Loggers 对象
  • Handlers :负责日志记录的传输目的地,比如有FileHandler(写入目标为文件)和StreamHandler(写入目标为流,默认为标准输出流)
  • Filters :负责过滤哪些日志是要输出的 。
  • Formatters :负责对日志输出格式的格式化。

logging模块的基础使用:

  • 基础使用使用就是使用默认logger对象的使用。
  1. 设置logging,调用logging.basicConfig()来配置日志信息。
    • 可设置的参数:filename日志文件名,filemode打开文件的方式,format日志的输出格式,datefmt日期输出格式,style设置format的类型,level日志记录的最低级别,stream输出流(不与filename并存,filename优先),handlers日志处理对象(默认是根处理对象),
    • 一般使用的参数:filename日志文件名,format日志的输出格式,level日志记录的最低级别,stream设置输出流
      • filename是日志文件名,就是一个普通文件名
      • format是日志的输出格式,设置方法下面讲
      • level的设置值为debug等值,使用方法为logging.DEBUG,logging.INFO,logging.WARNING,logging.ERROR,logging.CRITICAL
      • style影响format的类型,它的值有'%','{','$',默认是'%',不同的style可以识别以下不同的message标识符:%(message)s、{message}、$message
  2. 输出日志信息:
    • 调试级别日志信息:logging.debug(信息)
    • 提示级别信息:logging.info(信息)
    • 警告基本信息:loggin.warning(信息)
    • 错误级别信息:logging.error(信息)
    • 严重级别信息:logging.critical(信息)

信息输出的格式化(指的是logging.info等函数里面的信息):

这个表述可能不是很清晰,但意义类似程序报错信息,(假如)普通的异常信息只有一个报错原因,(那么为了方便观看)可能还需要一些如错误地点,错误事件等信息,而这些附加的统一的时间不应该由生产错误信息的部分来添加(可能有很多个模块),而应该将这个信息给专门做这事的部分来处理(交个formatter来处理)。

1.支持普通字符串%格式化,例如:

logging.info('Started %s'%tag)

2.支持普通字符串format格式化,例如:

logging.info('{} started '.format(tag))

3.logging自带的,例如:

logging.info('%s start in', tag) logging.info('%s start in %s',tag,address)

format设置方法:

  • 常用特殊字符:
    • message是日志信息
    • levelname日志信息等级
    • asctime是字符串形式的日期时间
    • name是logger的名字
    • levelno是数字形式的日志信息等级
    • module是调用日志输出函数的模块名
    • funcName是调用日志输出函数的函数名
    • lineno是调用日志输出函数的代码行数

根据不同的style,可以使用%(message)s或{message}或$message类似的格式来标注指定位置使用指定信息来取代。

  • 默认格式:
    • asctime 使用%(asctime)s
    • funcName使用%(funcName)s
    • levelname使用%(levelname)s
    • message使用%(message)s
    • lineno使用%(lineno)d
    • module使用%(module)s
    • name使用%(name)s

官方文档:

docs.python.org/3.6/library/logging.html

datefmt日期输出格式的设置方法:

设置format中特殊字符asctime(日期时间)的输出格式

  • 特殊字符:
    • %y 两位数的年份表示(00-99)
    • %Y 四位数的年份表示(000-9999)
    • %m 月份(01-12)
    • %d 月内中的一天(0-31)
    • %H 24小时制小时数(0-23)
    • %I 12小时制小时数(01-12)
    • %M 分钟数(00=59)
    • %S 秒(00-59)

使用自己想要的分隔符和顺序来定义日期时间的格式,例如:

datefmt='%m/%d/%Y %I:%M:%S %p'

使用小例子:

不使用format的:

import logging def show(): print("wechat running...") return "wechat" def main(): logging.basicConfig(filename='myapp.log', level=logging.INFO) tag=show() logging.info('Started %s'%tag) logging.info('Finished %s'%tag) if __name__ == '__main__' : main()

使用format和datefmt的:

import logging def show(): print("wechat running...") return "wechat" def main(): logging.basicConfig(filename='myapp.log', format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p',level=logging.INFO) tag=show() logging.info('%s start in', tag) logging.info('%s Finished',tag) if __name__ == '__main__' : main()

PS:虽然上面没有说到logger对象,handler对象(默认方向是标准输出流),formatter对象,但实际上,它是有默认的。不要因为默认值而搞错。所以不建议混杂基础版的和扩展版的使用。


logging模块的扩展使用:

1.导入模块:

import logging

2.获取logger对象:

logger = logging.getLogger("AppName")

在模块中使用时,官方文档中有一个这样的代码,有点意思:

logger = logging.getLogger(__name__)

3.设置最低日志输出级别:

logger.setlevel()

例如:

logger.setLevel(logging.INFO)

4.创建并绑定handler:

handler用于处理日志信息的输出方向,可以添加多个handler,代表同时向多个方向输出信息

Python中如何详细掌握logging模块的特性和应用技巧?

  • 创建handler:

输出方向为文件,使用FileHandler,例如:

logging.FileHandler("test.log")

输出方向为流,使用StreamHandler,例如:

logging.StreamHandler(sys.stdout)

PS:想了解更多Handler,可以自己查看官方文档docs.python.org/3.6/howto/logging.html

  • 绑定handler,使用addHandler():

例如:

logger.addHandler(handler)

  • 绑定后如果想解绑handler,使用removeHandler():

例如:

logger.removeHandler(handler)

5.定义handler的输出格式formatter并绑定到handler上,formatter的设置方法类似上面基础使用中的format:

  • 创建:

例如:

formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s')

  • 绑定:

handler.setFormatter(formatter) 或handler.formatter=formatter

6.将handle绑定到logger对象上。

logger.addHandler(file_handler) logger.addHandler(console_handler)

7.输出日志:

调试级别: logger.debug(信息)

提示级别: logger.info(信息)

警告级别: logger.warn(信息)

错误级别:

logger.error(信息)

logger.exception(信息)

严重级别:

logger.fatal(信息)

logger.critical(信息)

使用示例:

import logging def demo(): #获取logger对象 logger=logging.getLogger("WeChat") #设置日志等级 logger.setLevel(logging.DEBUG) #创建绑定handler handler=logging.FileHandler('wechat.log') logger.addHandler(handler) # 创建绑定formatter formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s') formatter.datefmt = '%m/%d/%Y %I:%M:%S %p' #可选的 handler.setFormatter(formatter) #尝试输出错误信息 logger.debug("debug message") logger.info("info message") logger.warning("warining message") logger.error("error message") logger.critical("critical message") if __name__=="__main__" : demo()

补充:

  • 如果你不想新建handler和formatter,可以使用basicConfig方式(可以使用basicConfig来配置所有的logger对象的handler和formatter),当要注意混杂风险。
  • logging模块中还有一个filter,由于它涉及的内容较多,单独列在下面讲。

logging中的Filter:

  • Filter用来过滤日志信息,例如你想输出A类信息,但不想输出C类信息,就可以进行过滤
  • 而由于所有的信息都有经过过滤器,也可以使用过滤器来增加一些信息。

使用方法1:建立子类

下面的例子可能不是很符合应用,仅用于举例:

过滤非允许用户的日志信息:

import logging import sys class ContextFilter(logging.Filter): def filter(self, record): if record.role=="admin" : return True else: return False if __name__ == '__main__': logger=logging.getLogger("Wechat") logger.setLevel(logging.DEBUG) handler=logging.StreamHandler(sys.stdout) formatter=logging.Formatter('%(asctime)s %(levelname)s: %(message)s Role: %(role)s') handler.setFormatter(formatter) logger.addHandler(handler) #创建绑定fiter f = ContextFilter() logger.addFilter(f) logger.info('An info message with %s', 'some parameters',extra={"role":"admin"}) logger.info('An info message with %s', 'some parameters',extra={"role":"hacker"})#hacker的被过滤掉了

官网版的加信息版本:

import logging from random import choice class ContextFilter(logging.Filter): """ This is a filter which injects contextual information into the log. Rather than use actual contextual information, we just use random data in this demo. """ USERS = ['jim', 'fred', 'sheila'] IPS = ['123.231.231.123', '127.0.0.1', '192.168.0.1'] def filter(self, record): record.ip = choice(ContextFilter.IPS) record.user = choice(ContextFilter.USERS) return True if __name__ == '__main__': levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL) logging.basicConfig(level=logging.DEBUG, format='%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s') a1 = logging.getLogger('a.b.c') a2 = logging.getLogger('d.e.f') f = ContextFilter() a1.addFilter(f) a2.addFilter(f) a1.debug('A debug message') a1.info('An info message with %s', 'some parameters') for x in range(10): lvl = choice(levels) lvlname = logging.getLevelName(lvl) a2.log(lvl, 'A message at %s level with %d %s', lvlname, 2, 'parameters')

使用方法2:使用filter函数

python3.2后,可以使用filter函数来做到上面方法1的效果

例子1:

import logging import sys def myfilter(record): if record.role == "admin": return True else: return False if __name__ == '__main__': logger=logging.getLogger("Wechat") logger.setLevel(logging.DEBUG) handler=logging.StreamHandler(sys.stdout) formatter=logging.Formatter('%(asctime)s %(levelname)s: %(message)s Role: %(role)s') handler.setFormatter(formatter) logger.addHandler(handler) #创建绑定fiter f = logging.Filter() f.filter=myfilter logger.addFilter(f) logger.info('An info message with %s', 'some parameters',extra={"role":"admin"}) logger.info('An info message with %s', 'some parameters',extra={"role":"hacker"})#hacker的被过滤掉了

例子2,利用lambda:

logger=logging.getLogger("Wechat") logger.setLevel(logging.DEBUG) handler=logging.StreamHandler(sys.stdout) formatter=logging.Formatter('%(asctime)s %(levelname)s: %(message)s Role: %(role)s') handler.setFormatter(formatter) logger.addHandler(handler) #创建绑定fiter # f = ContextFilter() f = logging.Filter() f.filter=lambda record: record.role=="admin" logger.addFilter(f) logger.info( 'An info message with %s', 'some parameters',extra={"role":"admin"}) logger.info('An info message with %s', 'some parameters',extra={"role":"hacker"})#hacker的被过滤掉了


使用配置文件配置logger对象:

注意:logging默认使用的logger对象叫做root

config文件配置方式:

import logging import logging.config logging.config.fileConfig('logging.conf') # create logger logger = logging.getLogger('simpleExample') # 'application' code logger.debug('debug message') logger.info('info message') logger.warn('warn message') logger.error('error message') logger.critical('critical message')

文件内容:

[loggers] keys=root,simpleExample [handlers] keys=consoleHandler [formatters] keys=simpleFormatter [logger_root] level=DEBUG handlers=consoleHandler [logger_simpleExample] level=DEBUG handlers=consoleHandler qualname=simpleExample propagate=0 [handler_consoleHandler] class=StreamHandler level=DEBUG formatter=simpleFormatter args=(sys.stdout,) [formatter_simpleFormatter] format=%(asctime)s - %(name)s - %(levelname)s - %(message)s datefmt=

PS:也支持YAML方式,这里不讲述


小技巧:

如果留意到过滤器例子的话,你可以发现

在formatter内可以附加参数:

输出信息时,附加一个参数extra,附加的参数可以被formatter使用

import logging import sys class ContextFilter(logging.Filter): def filter(self, record): if record.role=="admin" : return True else: return False if __name__ == '__main__': logger=logging.getLogger("Wechat") logger.setLevel(logging.DEBUG) handler=logging.StreamHandler(sys.stdout) formatter=logging.Formatter('%(asctime)s %(levelname)s: %(message)s Role: %(role)s') handler.setFormatter(formatter) logger.addHandler(handler) #创建绑定fiter f = ContextFilter() logger.addFilter(f) logger.info('An info message with %s', 'some parameters',extra={"role":"admin"}) logger.info('An info message with %s', 'some parameters',extra={"role":"hacker"})#hacker的被过滤掉了


想要了解更多?不如看看官方文档。

docs.python.org/3.6/library/logging.html

更多关于Python相关内容感兴趣的读者可查看本站专题:《Python日志操作技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》

希望本文所述对大家Python程序设计有所帮助。