logging 模块是 python 中用于打印日志。
日志系统有如下几种等级:DEBUG INFO WARNING ERROR CRITICAL,默认等级是 WARNING。
简单示例
import logging logging.warning('Watch out!') # will print a message to the console logging.info('I told you so') # will not print anything
输出日志到文件
import logging logging.basicConfig(filename='example.log',level=logging.DEBUG) logging.debug('This message should go to the log file') logging.info('So should this') logging.warning('And this, too')
修改日志打印格式
import logging logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') logging.warning('is when this event was logged.')
datefmt 是可选参数。
logging 库采用了模块化方法,并且提供了以下几种组件:
- loggers 提供接口可供应用程序的代码直接使用
- handlers 将日志记录(由 loggers 创建)发送到适当的目标
- filters 提供了更精细的设施,用于确定要输出的日志记录
- formatters 指定最终输出中日志记录的布局
通过调用Logger类实例上的方法(以下称为 logger)来执行日志记录。每个实例都有一个名称,它们在概念上以点(句点)作为分隔符排列在命名空间层次结构中。Logger 名称可以是您想要的任何名称,并指示记录消息源自的应用程序区域。
命名 loggers 时使用的一个好习惯是在每个使用日志记录的模块中使用模块级记录器,命名如下:
logger = logging.getLogger(__name__)
Loggers 模块常用的配置方法:Logger.setLevel( ) Logger.addHandler( ) Logger.removeHandler( ) Logger.addFilter( ) Logger.removeFilter( )
Handlers 模块常用的实例有 StreamHandler FileHandler 等, 常用的配置方法有 setLevel( ) setFormatter( ) addFilter( ) removeFilter( )
Formatters 模块中的 Formatter 对象配置日志消息的最终顺序,结构和内容。构造函数有两个可选参数, 消息格式字符串和日期格式字符串。
logging.Formatter.__init__(fmt=None, datefmt=None)
下面是一个实例:
import logging # create logger logger = logging.getLogger('simple_example') logger.setLevel(logging.DEBUG) # create console handler and set level to debug ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) # create formatter formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # add formatter to ch ch.setFormatter(formatter) # add ch to logger logger.addHandler(ch) # 'application' code logger.debug('debug message') logger.info('info message') logger.warn('warn message') logger.error('error message') logger.critical('critical message')
下面是从配置文件读取日志文件配置信息的示例:
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')
这是 loggin.conf 的配置信息:
[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=
配置文件可以参考官方文档。
配置文件中必须包含的三个 section 是 [loggers] [handlers] [formatters],例如 loggers 中又包含一些 entity,例如 logger 中 log01 的 entity,它相应的 section 就是 [logger_log01],例如 [formatters] 中 form01 的 section 是 [formatter_form01]。
可以按照天来分割日志文件,使用的 handler 是 logging.handlers 包下的 TimedRotatingFileHandler 类。参考文档是在这里。
例如下面这个 handler 可以按照每分钟分割日志文件。
# add time rotating file handler th = logging.handlers.TimedRotatingFileHandler('my.log', when='M') th.setLevel(logging.DEBUG) th.setFormatter(formatter01) logger.addHandler(th)
如何将上面的代码转化成配置呢?如下:
[handler_fileHandler] class=handlers.TimedRotatingFileHandler level=DEBUG formatter=formatter01 args=('my.log', 'M')
logging 是线程安全的,在一个进程内的多个线程同时往同一个文件写日志是安全的。但是多个进程往同一个文件写日志是不安全的。
参考: