logging日志文件配置

 

脚本配置如下:

可以输出console也可以输出文件

import os
import logging
from logging import handlers


class Logger:
    level_relations = {
       "debug": logging.DEBUG,
       "info": logging.INFO,
       "warning": logging.WARNING,
       "error": logging.ERROR
    }

    def __init__(self,
                 filename,
                 level="debug",
                 when="H",
                 back_count=2,
                 fmt="%(asctime)s - %(filename)s - "
                     "[line:%(lineno)4d]: %(message)s"):
        """
        日志配置类
        :param filename:
        :param level:
        :param when:
        :param back_count:
        :param fmt:
        """
        self.logger = logging.getLogger(filename)
        format_str = logging.Formatter(fmt)
        log_level = self.level_relations.get(level)
        # 设置日志级别
        self.logger.setLevel(log_level)
        # console输出配置
        screen_hd = logging.StreamHandler()
        # 文件输出配置
        time_file_handler = handlers.TimedRotatingFileHandler(
            filename=filename,
            when=when,
            interval=1,
            backupCount=back_count,
            encoding="utf8"
        )
        # 设置handler格式
        screen_hd.setFormatter(format_str)
        # 把handler对象加入到logger里面
        self.logger.addHandler(screen_hd)
        self.logger.addHandler(time_file_handler)



# 日志使用
# current_dir = os.getcwd()  # 拿到当前文件的绝对路径
# log_dir_ = add_log_dir(current_dir, "接口运行日志log")  # 在项目路径下面,外包一层文件夹
# log_obj = Logger(os.path.join(log_dir_, "interface_.log"))  # 创建日志路径以及日志文件名称
# log_obj.logger.error("test log work or not")

 

 

Django配置如下

只有console控制台输出日志:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {  # 这里是打印console里面的sql语句的日志配置,
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

 

完整版:(我们的程序运行的时候,需要有日志记录运行的过程,每一次的点击交互事件都是程序在运行的过程,每一次都需要记录下来,我们不可能在程序里面加上成千上万的print然后都打印到屏幕里面,那样不便于整理,也不现实,这个时候我们的日志就应运而生了,我们在setting里面把日志配置好,然后根据我们配置的参数,我们的每一次程序运行都打印到一个文件里面,然后这个文件会根据我们设置的大小进行分割,就类似于换行,然后文件不会无限大,达到一定的上限之后就会自动开启另一个文件去保存数据,我们的程序上线之后,需要查bug都是通过日志去检验,看哪里有问题,需要进一步去调整,这就是我们的日志的关键所在)


Django项目常用LOGGING配置
BASE_LOG_DIR = os.path.join(BASE_DIR, "log")
if not os.path.isdir(BASE_LOG_DIR):
os.mkdir(BASE_LOG_DIR)

LOGGING = {
'version': 1,
'disable_existing_loggers': False, # 是否禁用已经存在的loggers示例,不禁用
'formatters': {
'standard': {
'format': '[%(asctime)s][%(threadName)s:%(thread)d]'
             '[task_id:%(name)s][%(filename)s:%(lineno)d]'
'[%(levelname)s][%(message)s]'
},
'simple': {
'format': '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
},
'collect': {
'format': '%(message)s'
}
},
'filters': {
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': {
'console': {
'level': 'DEBUG',
'filters': ['require_debug_true'], # 只有在Django debug为True时才在屏幕打印日志
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'default': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,自动切
'filename': os.path.join(BASE_DIR, "genius20F_info.log"),
# 日志文件路径,这里我们不要写绝对路径,就用系统内置的BASE_DIR,然后后面直接写文件名即可
'maxBytes': 1024 * 1024 * 50, # 日志大小 50M
'backupCount': 3,
'formatter': 'standard',
'encoding': 'utf-8',
},
     'SF': {
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,根据文件大小自动切
            'filename': os.path.join(BASE_LOG_DIR, "xxx_info.log"),  # 日志文件
            'maxBytes': 1024 * 1024 * 50,  # 日志大小 50M
            'backupCount': 3,  # 备份数为3  xx.log --> xx.log.1 --> xx.log.2 --> xx.log.3
            'formatter': 'standard',
            'encoding': 'utf-8',
        },
        'TF': {
            'level': 'INFO',
            'class': 'logging.handlers.TimedRotatingFileHandler',  # 保存到文件,根据时间自动切
            'filename': os.path.join(BASE_LOG_DIR, "xxx_info.log"),  # 日志文件
            'backupCount': 3,  # 备份数为3  xx.log --> 
# xx.log.2018-08-23_00-00-00 --> xx.log.2018-08-24_00-00-00 --> ... 'when': 'D', # 每天一切,
# 可选值有S/秒 M/分 H/小时 D/天 W0-W6/周(0=周一) midnight/如果没指定时间就默认在午夜 'formatter': 'standard', 'encoding': 'utf-8', },
        'error': {
'level': 'ERROR',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,自动切
'filename': os.path.join(BASE_DIR, "genius20F_err.log"), # 日志文件
'maxBytes': 1024 * 1024 * 50, # 日志大小 50M
'backupCount': 5,
'formatter': 'standard',
'encoding': 'utf-8',
},
'collect': {
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,自动切
'filename': os.path.join(BASE_DIR, "genius20F_collect.log"),
'maxBytes': 1024 * 1024 * 50, # 日志大小 50M
'backupCount': 5,
'formatter': 'collect',
'encoding': "utf-8"
}
},
'loggers': {
# 默认的logger应用如下配置
'django': { # *****这里是五星级提示:一定要写Django,
# 这样系统console控制台输出的信息才会全部都自动写入到文件中去,
# 官网说不能这样写,得写成不同的记录器,比如django.service,或者是django.request,django.template等,
# 亲测,直接写django,就能达到想要的效果。这里的django,需要在后面使用的时候,跟getLogger里面的名字需要对应上
'handlers': ['default', 'TF', 'error', 'console'], # 上线之后可以把'console'移除
'level': 'DEBUG',
'propagate': True, # 是否继承父类的log信息
},
'django.service': {
'handlers': ['default', ],
'propagate': True,
'level': 'DEBUG', },
# 名为 'collect'的logger还单独处理
'collect': {
'handlers': ['collect', ],
'level': 'INFO',
},
# 自定义logger处理方式,专门为文件genius20F.utils.commons.py单独做处理
# 'genius20F.utils.commons': {
# 'handlers': ['error', ],
# 'level': 'INFO',
# 'propagate': True,
# }
},
}
 

 

配置好之后,程序运行的时候就会自动生成日志文件在项目目录下面。

 

如下是常用简洁版,比较完整的核心功能

log_path = os.path.join(BASE_DIR, "{}-logs".format(time.strftime('%Y-%m-%d')))

if not os.path.exists(log_path):
os.mkdir(log_path) # 如果不存在这个logs文件夹,就自动创建一个,以日期命名

LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { # 日志格式 'standard': { 'format': '[%(asctime)s] [%(filename)s:%(lineno)d] [%(module)s:%(funcName)s] ' '[%(levelname)s]- %(message)s'}, 'simple': { # 简单格式 'format': '%(levelname)s %(message)s' }, }, # 过滤 'filters': { 'require_debug_true': { '()': 'django.utils.log.RequireDebugTrue', }, }, # 定义具体处理日志的方式 'handlers': { # 控制台输出 'console': { 'level': 'DEBUG', 'filters': ['require_debug_true'], 'class': 'logging.StreamHandler', 'formatter': 'simple' }, # 默认记录所有日志 'default': { 'level': 'DEBUG', 'class': 'logging.handlers.RotatingFileHandler', 'filename': os.path.join(log_path, 'all-{}.log'.format( time.strftime('%Y-%m-%d'))), 'maxBytes': 1024 * 1024 * 5, # 文件大小 'backupCount': 5, # 备份数 'formatter': 'standard', # 输出格式 'encoding': 'utf-8', # 设置默认编码,否则打印出来汉字乱码 }, # 输出错误日志 'error': { 'level': 'ERROR', 'class': 'logging.handlers.RotatingFileHandler', 'filename': os.path.join(log_path, 'error-{}.log'.format( time.strftime('%Y-%m-%d'))), 'maxBytes': 1024 * 1024 * 5, # 文件大小 'backupCount': 5, # 备份数 'formatter': 'standard', # 输出格式 'encoding': 'utf-8', # 设置默认编码 }, # 输出info日志 'info': { 'level': 'INFO', 'class': 'logging.handlers.RotatingFileHandler', 'filename': os.path.join(log_path, 'info-{}.log'.format( time.strftime('%Y-%m-%d'))), 'maxBytes': 1024 * 1024 * 5, 'backupCount': 5, 'formatter': 'standard', 'encoding': 'utf-8', # 设置默认编码 }, }, # 配置用哪几种 handlers 来处理日志 'loggers': { # 类型 为 django 处理所有类型的日志, 默认调用
     'django': { 'handlers': ['default', 'console', 'info', 'error'], 'level': 'INFO', 'propagate': True }, # record database change sql sentence # 'django.db.backends': { # 'handlers': ['default', "info", "error"], # 'level': 'DEBUG', # 'propagate': True # }, } }

 

 

在程序中使用log:

import logging

logger = logging.getLogger('django')  # 这里的django要跟上面loggers配置里面的django同名


def index(arg):
  try:
    if arg>10:
    print("hello")
  except Exception as e:
    logger.error(e)
  return arg

def get_people_data(request):
  if request.method=='GET':
    logger.info('get people data on here')
  return

 

程序走到这里的时候,就会在error的文件夹里面把信息记录下来。会根据上面settings的配置,决定记录到文件中或者是打印到console里。

在不同的文件中都可以同时引用logging模块,如果该文件中多次用到日志,就按照上面例子把实例化logger放在最上面即可。

 

 

flask配置如下

直接在项目根目录下创建logging文件,写入如下代码

import os
import logging
from logging.handlers import RotatingFileHandler

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


class LoggingSet():
    def __init__(self):
        self.path = os.path.join(BASE_DIR, "flask_check_list/flask_logs")
        self.maxBytes = 1024 * 1024 * 100
        self.default_formatter = logging.Formatter(
            '%(levelname)s %(filename)s:%(lineno)d %(message)s')
        self.error_formatter = logging.Formatter(
            '[%(asctime)s] [%(filename)s:%(lineno)d\t] [%(levelname)s]  %(message)s '
        )

    def debug_log(self, log_level):
        logging.basicConfig(level=log_level)
        file_log_handler = RotatingFileHandler(
            os.path.join(self.path, "flask.log"),
            # maxBytes=1024 * 1024 * 100,
            maxBytes=self.maxBytes,
            backupCount=10
        )
        file_log_handler.setFormatter(self.default_formatter)
        logging.getLogger().addHandler(file_log_handler)

    def error_log(self, log_level):
        logging.basicConfig(level=log_level)
        file_error_handler = RotatingFileHandler(
            os.path.join(self.path, 'error.log'),
            maxBytes=self.maxBytes,
            backupCount=5
        )
        file_error_handler.setFormatter(self.error_formatter)
        logging.getLogger().addHandler(file_error_handler)

 

在项目根目录的__init__文件中创建app,如下使用logging配置:

from .loggins import LoggingSet

logger = LoggingSet()

def create_app(): app = Flask(__name__) connect('test', host='127.0.0.1', port=27017) app.config.from_object("settings.DevelopmentConfig") app.config['MONGODB_SETTINGS'] = { 'db': 'test', 'host': 'localhost', 'port': 27017 } logger.debug_log(logging.DEBUG) logger.error_log(logging.ERROR) db.init_app(app) app.debug = True return app app = create_app()

 

这样就可以了,这是自己写的比较简单的类方法,与Django的配置比较起来确实寒酸些。。。。。。

posted @ 2018-01-30 20:04  dream-子皿  阅读(409)  评论(0编辑  收藏  举报