import logging
logging.debug('This is debug message.')
logging.info('This is info message.')
logging.warning('This is warning message.')
logging.error('This is error message.')
logging.critical('This is critical message.')
# Output in stdout:
# WARNING:root:This is warning message.
# ERROR:root:This is error message.
# CRITICAL:root:This is critical message.
import logging
logging.basicConfig(level=logging.INFO,
filename='log.log',
filemode='w',
format='%(levelname)s - %(name)s - %(message)s')
logging.debug('This is debug message.')
logging.info('This is info message.')
logging.warning('This is warning message.')
logging.error('This is error message.')
logging.critical('This is critical message.')
# Output in log.log:
# INFO - root - This is info message.
# WARNING - root - This is warning message.
# ERROR root - This - is error message.
# CRITICAL - root - This is critical message.
日志共有 5 个级别,由高到低分别是 CRITICAL > ERROR > WARNING > INFO > DEBUG
级别 | 使用 |
---|---|
DEBUG | 详细信息,调试问题时用到 |
INFO | 表明程序按照预期运行 |
WARNING | 程序出现一些意外,或者在将来可能出现问题,目前程序仍可正常运行 |
ERROR | 程序的部分功能已经不可用 |
CRITICAL | 程序崩溃,已经不能继续运行 |
import logging
logger = logging.getLogger('foo')
logger.setLevel(logging.INFO)
sh = logging.StreamHandler()
sh.setLevel(logging.INFO)
fmt = logging.Formatter(fmt='%(levelname)s - %(name)s - %(message)s')
sh.setFormatter(fmt)
logger.addHandler(sh)
logger.info('info message')
# INFO - foo - info message
"""StreamHandler example
"""
import logging
import sys
logger = logging.getLogger('stream')
logger.setLevel(logging.INFO)
sh = logging.StreamHandler(stream=sys.stdout)
sh.setLevel(logging.INFO)
fmt = Formatter(fmt='%(levelname)s:%(name)s:%(message)s')
sh.setFormatter(fmt)
logger.addHandler(sh)
logger.info('info message')
# INFO:stream:info message
"""FileHandler example
"""
import logging
logger = logging.getLogger('file')
logger.setLevel(logging.DEBUG)
fh = logging.FileHandler(filename='log.log', mode='w')
fh.setLevel(logging.DEBUG)
fmt = Formatter('%(name)s - line:%(lineno)d - %s')
fh.setFormatter(fmt)
logger.addHandler(fh)
logger.debug('debug message')
# file - line:16 - debug message
"""RotatingFileHandler example
"""
import logging
import glob
from logging.handlers import RotatingFileHandler
logger = logging.getLogger('rotatingfile')
logger.setLevel(logging.INFO)
rfh = RotatingFileHandler(
filename='log.out',
maxBytes=20,
backupCount=5)
logger.addHandler(rfh)
for i in range(20):
logger.info('i = {}'.format(i))
logfiles = glob.glob('log.out*')
for filename in logfiles:
print filename
# log.out
# log.out.1
# log.out.2
# log.out.3
# log.out.4
# log.out.5
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 = logging.Filter(name='')
指定日志记录输出的具体格式。Formatter 的构造方法需要两个参数:消息的格式字符串 fmt 和日期字符串 datefmt,这两个参数都是可选的。
格式 | 描述 |
---|---|
%(name) s | 日志名称 |
%(levelno) s | 日志级别数值 |
%(levelname) s | 日志级别 |
%(pathname) s | 当前程序执行路径 |
%(filename) s | 当前执行程序名称 |
%(module) s | 当前模块 |
%(funcName) s | 当前函数名称 |
%(lineno) d | 行号 |
%(asctime) s | 日志时间 |
%(thread) d | 线程 ID |
%(threadName) s | 线程名称 |
%(process) d | 进程 ID |
%(message) s | 日志消息 |
# -*- coding: utf-8 -*-
import logging
logger_name = "example"
logger = logging.getLogger(logger_name)
logger.setLevel(logging.DEBUG)
log_path = "./log.log"
fh = logging.FileHandler(log_path)
fh.setLevel(logging.WARN)
fmt = "%(asctime)-15s %(levelname)s %(lineno)d %(process)d %(message)s"
datefmt = "%a %d %b %Y %H:%M:%S"
formatter = logging.Formatter(fmt, datefmt)
fh.setFormatter(formatter)
logger.addHandler(fh)
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
# Thu 06 Apr 2017 16:58:09 WARNING 20 7472 warn message
# Thu 06 Apr 2017 16:58:09 ERROR 21 7472 error message
# Thu 06 Apr 2017 16:58:09 CRITICAL 22 7472 critical message
# logging.conf
[loggers]
keys=runner,monitor
[handlers]
keys=runnerHand,monitorHand
[formatters]
keys=defaultForm
[logger_runner]
level=DEBUG
handlers=runnerHand
propagate=0
qualname=runner
[logger_monitor]
level=INFO
handlers=monitorHand
propagate=0
qualname=monitor
[handler_runnerHand]
class=FileHandler
level=DEBUG
formatter=defaultForm
args=('log\\runner.log', 'w')
[handler_monitorHand]
class=FileHandler
level=INFO
formatter=defaultForm
args=('log\\monitor.log', 'w')
[formatter_defaultForm]
format=%(asctime)s - %(levelname)s - %(message)s
# -*- coding: utf-8 -*-
import logging
from logging.config import fileConfig
fileConfig('logging.conf')
if __name__ == '__main__':
monitor_logger = logging.getLogger('monitor')
monitor_logger.info('This is monitor log')
runer_logger = logging.getLogger('runner')
runer_logger.info('This is runner log')
# -*- coding: utf-8 -*-
import logging
from logging.config import dictConfig
logging_conf = dict(
version=1,
loggers={
'runner': {
'level': logging.INFO,
'handlers': ['runnerHand'],
'propagate': 0,
'qualname': 'runner'
},
'monitor': {
'level': logging.INFO,
'handlers': ['monitorHand'],
'propagate': 0,
'qualname': 'monitor'
}
},
handlers={
'runnerHand': {
'class': 'logging.FileHandler',
'level': logging.INFO,
'formatter': 'defaultFormatter',
'filename': 'runner.log',
'mode': 'w'
},
'monitorHand': {
'class': 'logging.FileHandler',
'level': logging.INFO,
'formatter': 'defaultFormatter',
'filename': 'monitor.log',
'mode': 'w'
}
},
formatters={
'defaultFormatter': {
'format': '%(asctime)s - %(levelname)s - %(message)s'
}
}
)
dictConfig(logging_conf)
if __name__ == '__main__':
monitor_logger = logging.getLogger('monitor')
monitor_logger.info('This is monitor log')
runer_logger = logging.getLogger('runner')
runer_logger.info('This is runner log')