1.示例代码可直接放在项目py文件中即可使用。
2.project_name,logfile_name变量需根据你的项目进行修改。
3.日志输出格式format选择(可根据你的需要替换或修改示例代码中的format)
%(levelno)s: 打印日志级别的数值 %(levelname)s: 打印日志级别名称 %(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0] %(filename)s: 打印当前执行程序名 %(funcName)s: 打印日志的当前函数 %(lineno)d: 打印日志的当前行号 %(asctime)s: 打印日志的时间 %(thread)d: 打印线程ID %(threadName)s: 打印线程名称 %(process)d: 打印进程ID %(message)s: 打印日志信息
示例代码
import os import re import logging.config # 定义三种日志输出格式 # 其中name为make_logger的参数name standard_format = '[%(levelname)s][%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s]' \ '\n[%(filename)s:%(lineno)d][%(message)s]' simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s' id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s' # 项目名 project_name = 'dev' # 日志文件名 logfile_name = 'logs' # 日志配置 LOGGING_DIC = { 'version': 1, # 禁用已经存在的logger实例 'disable_existing_loggers': False, # 日志格式化(负责配置log message 的最终顺序,结构,及内容) 'formatters': { 'distinct': { 'format': standard_format }, 'simple': { 'format': simple_format }, 'less_simple': { 'format': id_simple_format }, }, # 过滤器,决定哪个log记录被输出 'filters': {}, # 负责将Log message 分派到指定的destination 'handlers': { # 打印到终端的日志 'console': { 'level': 'INFO', 'class': 'logging.StreamHandler', # 打印到屏幕 'formatter': 'distinct' }, # 打印到common文件的日志,收集info及以上的日志 'common': { 'level': 'INFO', 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件 'formatter': 'simple', 'filename': './%s/access.log' % logfile_name, # 日志文件路径 'maxBytes': 1024*1024*5, # 日志大小 5M 'backupCount': 5, # 备份5个日志文件 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了 }, # 打印到importance文件的日志,收集error及以上的日志 'importance': { 'level': 'ERROR', 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件 'formatter': 'distinct', 'filename': './%s/importance.log' % logfile_name, # 日志文件 # 'maxBytes': 1024*1024*5, # 日志大小 5M 'maxBytes': 300, # 日志大小 5M 'backupCount': 5, # 备份5个日志文件 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了 }, }, # logger实例 'loggers': { # 默认的logger应用如下配置 '': { 'handlers': ['console'], # log数据打印到控制台 'level': 'DEBUG', 'propagate': True, # 向上(更高level的logger)传递 }, 'default': { 'handlers': ['console', 'common', 'importance'], 'level': 'INFO', 'propagate': True, # 向上(更高level的logger)传递 }, 'common': { 'handlers': ['console', 'common'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到控制台 'level': 'INFO', 'propagate': True, # 向上(更高level的logger)传递 }, 'importance': { 'handlers': ['console', 'importance'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到控制台 'level': 'ERROR' }, }, } class Log(object): @staticmethod def isdir_logs(): """ 判断日志文件是否存在,不存在则创建 :return: """ # 当前文件的目录 basedir = os.path.dirname(os.path.abspath(__file__)) pattern = '(.*/%s)' % project_name project_dir = re.search(pattern, basedir).group() # logs文件的路径 log_path = os.path.join(project_dir, logfile_name) # 判断日志文件夹是否在项目文件中 if not os.path.isdir(log_path): os.mkdir(log_path) @staticmethod def make_logger(name=None): """ 1. 如果不传name,则根据__name__去loggers里查找__name__对应的logger配置(__name__为调用文件名) 获取logger对象通过方法logging.getLogger(__name__),不同的文件__name__不同,这保证了打印日志时标识信息不同, 2. 如果传name,则根据name获取loggers对象 3. 如果拿着name或者__name__去loggers里找key名时却发现找不到,于是默认使用key=''的配置 :return: logger """ logging.config.dictConfig(LOGGING_DIC) # 导入上面定义的logging配置 if name: logger = logging.getLogger(name) else: logger = logging.getLogger(__name__) return logger if __name__ == '__main__': Log().isdir_logs() importance_logger = Log.make_logger('default') importance_logger.error('787878')
说明:
logger:日志对象,logging模块中最基础的对象,用logging.getLogger(name)方法进行初始化,name可以不填。通常logger的名字我们对应模块名,如聊天模块、数据库模块、验证模块等。
logger对象的常用方法有:
setLevel:设置日志等级
日志等级分别有以下几种:
CRITICAL : 'CRITICAL',
ERROR : 'ERROR',
WARNING : 'WARNING',
INFO : 'INFO',
DEBUG : 'DEBUG',
NOTSET : 'NOTSET',
一旦设置了日志等级,则调用比等级低的日志记录函数则不会输出。