logging模块简介
Python的logging模块提供了通用的日志系统,可以方便第三方模块或者是应用使用。这个模块提供不同的日志级别,并可以采用不同的方式记录日志,比如文件,HTTP GET/POST,SMTP,Socket等,甚至可以自己实现具体的日志记录方式。
logging模块提供logger,handler,filter,formatter。
logger: 提供日志接口,供应用代码使用。logger最长用的操作有两类:配置和发送日志消息。可以通过logging.getLogger(name)获取logger对象,如果不指定name则返回root对象,多次使用相同的name调用getLogger方法返回同一个logger对象。
handler:将日志记录发送到合适的目的地,比如文件,socket等。一个logger对象可以通过addHandler方法添加0到多个handler,每个handler又可以定义不同日志级别,以实现日志分级过滤显示。
filter:提供一种优雅的方式决定一个日志记录是否发送到handler。
formatter:指定日志记录输出的具体格式。formatter的构造方法需要两个参数:消息的格式字符串和日期字符串,这两个参数都是可选的。
logging 模块对多线程支持得很好,但不支持多进程
使用
- formatter
%(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(filename)s 调用日志输出函数的模块的文件名
%(lineno)d 调用日志输出函数的语句所在的代码行
%(funcName)s 调用日志输出函数的函数名
%(message)s 用户输出的消息 - handler:
StreamHandler:logging.StreamHandler日志输出到流,可以是sys.stderr,sys.stdout或者文件
FileHandler:logging.FileHandler日志输出到文件
RotatingHandler:logging.handlers.RotatingHandler日志回滚方式,支持日志文件最大数量和日志文件回滚
TimeRotatingHandler:logging.handlers.TimeRotatingHandler日志回滚方式,在一定时间区域内回滚日志文件
import logging.handlers
import os
from source.env import IS_DEV
class Logger:
def __init__(self, file_path, app_name):
self.logger = self.init_logger(file_path, app_name)
def init_logger(self, file_path, app_name):
if IS_DEV:
level = logging.DEBUG
else:
level = logging.INFO
my_log = logging.getLogger()
my_log.setLevel(level=level)
log_format = logging.Formatter('%(asctime)s [%(filename)s:%(lineno)s - %(funcName)20s()] %(message)s')
# print log to file
time_file_handler = logging.handlers.TimedRotatingFileHandler(
os.path.join(file_path, app_name + '.log'),
when='D',
interval=2,
backupCount=180
)
time_file_handler.suffix = '%Y-%m-%d-%H-%M-%S.log' # 按 秒
time_file_handler.setLevel(level)
time_file_handler.setFormatter(log_format)
# print log to console
console = logging.StreamHandler()
console.setFormatter(log_format)
console.setLevel(level)
my_log.addHandler(time_file_handler)
my_log.addHandler(console)
return my_log
def debug(self, message):
self.logger.debug(message)
def info(self, message):
self.logger.info(message)
def error(self, message):
self.logger.error(message)
def exception(self, message):
self.logger.exception(message)
多模块使用Logging
logging模块保证在同一个python解释器内,多次调用logging.getLogger(‘log_name’)都会返回同一个logger实例,即使是在多个模块的情况下。所以典型的多模块场景下使用logging的方式是在main模块中配置logging,这个配置会作用于多个的子模块,然后在其他模块中直接通过getLogger获取Logger对象即可
main.py
if __name__ == '__main__':
logger = Logger(LOG_FILE_PATH, 'monitor')
logger.info('application start at {}'.format(datetime.datetime.utcnow()))
子模块
logger = logging.getLogger()
class Sub:
def do_something(self):
logger.info('hello world')