Flask记录日志

作者: Rethink | 来源:发表于2020-06-28 17:55 被阅读0次

    关于Flask日志记录,网上的文章大多都已过时,我在项目开发过程中,结合实际情况,初步采用以下日志方案,后续遇到问题会不断进行优化,并更新文章内容。

    日志记录的总体思路如下:

    1. 在 Flask 工厂函数中,利用钩子函数,将接口每次的请求参数和响应内容写入到日志文件中,并利用flask_sqlalchemy提供的get_debug_queries方法,实现当执行时间超过阈值时,将查询信息按照指定的格式写入到日志文件中;
    2. 接入Sentry SDK,收集项目错误日志,然后在Sentry Dashboard查看异常信息;(点击查看官方文档)

    工厂函数相关内容如下,注释已经写得很清楚了:

    from pathlib import Path
    from logging.handlers import RotatingFileHandler
    
    from flask import Flask
    from flask_sqlalchemy import get_debug_queries
    import sentry_sdk
    from sentry_sdk.integrations.flask import FlaskIntegration
    
    
    from .config import config
    
    # 递归创建日志存放目录
    basedir = Path(__file__).parent.parent  # 项目根目录
    logdir = basedir.joinpath(r'rethink/logs')
    if not logdir.is_dir():
        os.makedirs(logdir)
    
    # 初始化Sentry, 必须在工厂函数之前
    sentry_sdk.init(
        dsn="官网注册账号后会给出",
        integrations=[FlaskIntegration()]
    )
    
    def make_app(config_name=None):
        if config_name is None:
            config_name = os.getenv("FLASK_CONFIG", "development")
    
        # 加载配置文件
        app = Flask(__name__)
        app.config.from_object(config[config_name])
    
        register_logger(app)  # 注册日志处理器
    
        # 如果没有未处理的异常抛出,会在每个请求结束后运行
        # 必须接受一个响应类对象作为参数,并返回同一个或更新后的响应对象
        @app.after_request
        def response_logger(response):
            # 获取接口响应数据
            api_path = request.full_path
            api_method = request.method
            ip_addr = request.remote_addr
            # 获取接口请求数据
            try:
                request_data = request.get_json(force=True)
            except Exception as e:
                request_data = request.form.to_dict()
    
            request_data, response_data = str(request_data), str(response.json)
    
            with open(logdir.joinpath('runtime.log'), 'a+', encoding="utf-8") as f:
                asctime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                f.write(
                    asctime + " " + ip_addr + " " + api_method + " " + api_path + '->' + request_data + '\n' + response_data + '\n')
    
            # 记录慢查询日志,在日志处理器函数中会将其写入到文件中
            for query in get_debug_queries():
                if query.duration >= app.config['FLASK_SLOW_DB_QUERY_TIME']:
                    app.logger.warning(
                        'Slow query: %s\n Parameters: %s\n Duration: %fs\n Context: %s'
                        % (query.statement, query.parameters, query.duration, query.context))
    
            return response
    
        return app
    
    
    def register_logger(app):
        app.logger.setLevel(logging.INFO)
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        # 设置日志文件最大尺寸和备份数量
        # 最大尺寸为10M,当超过10M产生备份文件,最多产生10个备份文件,10个备份文件全部存满后,会开始覆盖之前的文件
        file_handler = RotatingFileHandler(logdir.joinpath('runtime.log'), maxBytes=10 * 1024 * 1024, backupCount=10)
        file_handler.setFormatter(formatter)
        file_handler.setLevel(logging.INFO)
        
        app.logger.addHandler(file_handler)
        app.logger.info('Autoline Startup...')  # 这里额外在日志文件中记录下每次应用服务的启动时间
    

    config.py是项目配置文件,相关内容如下:

    class BaseConfig(object):
        # 启用慢查询记录功能(调试模式下自动启用), 为了在生产环境下可用,必须手动配置此项为True
        SQLALCHEMY_RECORD_QUERIES = True
        # 慢查询阈值
        FLASK_SLOW_DB_QUERY_TIME = 0.001
        
    class DevelopmentConfig(BaseConfig):
        SQLALCHEMY_DATABASE_URI = os.getenv("DB_DEVELOPMENT_URI")
    
    class TestingConfig(BaseConfig):
        SQLALCHEMY_DATABASE_URI = os.getenv("DB_Testing_URI")
    
    
    class ProductionConfig(BaseConfig):
        SQLALCHEMY_DATABASE_URI = os.getenv('DB_PRODUCTION_URI')
    
    config = {
        'development': DevelopmentConfig,
        'testing': TestingConfig,
        'production': ProductionConfig
    }
    

    在配置文件中,为了测试慢查询日志记录,特意将FLASK_SLOW_DB_QUERY_TIME设置为0.001s. 在本地开发环境下请求下flask接口,在控制台可以看到有相关的日志输出,如下:

    查看runtime.log,可以看到接口请求日志和慢查询日志都已经被写入了: 当接口出现异常时,在Sentry Dashboard中可以看到非常详细的日志信息。

    【To Be Continued...】

    相关文章

      网友评论

        本文标题:Flask记录日志

        本文链接:https://www.haomeiwen.com/subject/wyyifktx.html