Flask + SQLAlchemy高级日志记录 [英] Flask + sqlalchemy advanced logging

查看:1573
本文介绍了Flask + SQLAlchemy高级日志记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在此上发现了其他一些帖子,但对我没有任何帮助,因此我想伸出援手,看看是否有人可以解释如何正确地获取Flask/Werkzeurg/中存在的某些记录器的/重定向/设置处理程序. sqlalchemy.

I found a few other posts on this but none that worked for me yet so I wanted to reach out and see if anyone could explain how to properly get / redirect / set handlers on some of the loggers present in Flask / Werkzeurg / sqlalchemy.

先前的研究无法回答我的问题:

Research prior that could not answer my question:

https://github.com/pallets/flask/issues/1359

http://flask.pocoo.org/docs/dev/logging/

https://gist.github.com/ibeex/3257877

我的配置:

main.py

    ...

    def init_app():
    """ Runs prior to app launching, contains initialization code """

    # set logging level
    if not os.path.exists(settings.LOG_DIR):
        os.makedirs(settings.LOG_DIR)

    # default level
    log_level = logging.CRITICAL

    if settings.ENV == 'DEV':
        log_level = logging.DEBUG
    elif settings.ENV == 'TEST':
        log_level = logging.WARNING
    elif settings.ENV == 'PROD':
        log_level = logging.ERROR

    log_formatter = logging.Formatter("[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s")
    api_logger = logging.getLogger()
    api_handler = TimedRotatingFileHandler(
            settings.API_LOG_FILE,
            when='midnight',
            backupCount=10
        )
    api_handler.setLevel(log_level)
    api_handler.setFormatter(log_formatter)
    api_logger.addHandler(api_handler)
    logging.getLogger('werkzeug').addHandler(api_handler)


    db_logger = logging.getLogger('sqlalchemy')
    db_handler = TimedRotatingFileHandler(
            settings.DB_LOG_FILE,
            when='midnight',
            backupCount=10
        )
    db_handler.setLevel(log_level)
    db_handler.setFormatter(log_formatter)
    db_logger.addHandler(db_handler)
    logging.getLogger('sqlalchemy.engine').addHandler(db_handler)
    logging.getLogger('sqlalchemy.dialects').addHandler(db_handler)
    logging.getLogger('sqlalchemy.pool').addHandler(db_handler)
    logging.getLogger('sqlalchemy.orm').addHandler(db_handler)



# add endpoints

...


if __name__ == '__main__':
    init_app()
    app.run(host='0.0.0.0', port=7777)

我尝试以几种不同的方式获取和更改记录器上的设置,但最终还是将werkzeug调试输出输出到控制台,而不是我的日志,我可以看到正在创建日志,但看起来好像不是记录器实际上是向他们输出:

I tried grabbing and changes settings on the loggers a few different ways but I still end up with the werkzeug debug outputting to console and not my logs, I can see the logs are being created but it doesn't look like the loggers are actually outputting to them:

api.log(格式化程序已写入该文件)

api.log (formatter wrote to it)

2018-02-15 12:03:03,944] {/usr/local/lib/python3.5/dist-packages/werkzeug/_internal.py:88} WARNING -  * Debugger is active!

db.log(空)

任何对此的见解将不胜感激!

Any insight on this would be much appreciated!

更新

我能够使用长手版本来运行werkzeug记录器,看来所示的速记函数调用返回的是空对象. sqlalchemy logger仍在输出到控制台..引擎配置可以覆盖我的文件处理程序吗?

I was able to get the werkzeug logger working using the long hand version, it seems the shorthand function calls shown were returning null objects. The sqlalchemy logger is still outputting to console though.. Could the engine configuration be overriding my filehandler?

...

# close current file handlers
for handler in copy(logging.getLogger().handlers):
    logging.getLogger().removeHandler(handler)
    handler.close()
for handler in copy(logging.getLogger('werkzeug').handlers):
    logging.getLogger('werkzeug').removeHandler(handler)
    handler.close()
for handler in copy(logging.getLogger('sqlalchemy.engine').handlers):
    logging.getLogger('sqlalchemy.engine').removeHandler(handler)
    handler.close()
for handler in copy(logging.getLogger('sqlalchemy.dialects').handlers):
    logging.getLogger('sqlalchemy.dialects').removeHandler(handler)
    handler.close()
for handler in copy(logging.getLogger('sqlalchemy.pool').handlers):
    logging.getLogger('sqlalchemy.pool').removeHandler(handler)
    handler.close()
for handler in copy(logging.getLogger('sqlalchemy.orm').handlers):
    logging.getLogger('sqlalchemy.orm').removeHandler(handler)
    handler.close()


# create our own custom handlers
log_formatter = logging.Formatter("[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s")
api_handler = TimedRotatingFileHandler(
        settings.API_LOG_FILE,
        when='midnight',
        backupCount=10
    )
api_handler.setLevel(log_level)
api_handler.setFormatter(log_formatter)
logging.getLogger().setLevel(log_level)
logging.getLogger().addHandler(api_handler)
logging.getLogger('werkzeug').setLevel(log_level)
logging.getLogger('werkzeug').addHandler(api_handler)


db_handler = TimedRotatingFileHandler(
        settings.DB_LOG_FILE,
        when='midnight',
        backupCount=10
    )
db_handler.setLevel(log_level)
db_handler.setFormatter(log_formatter)
logging.getLogger('sqlalchemy.engine').addHandler(db_handler)
logging.getLogger('sqlalchemy.engine').setLevel(log_level)
logging.getLogger('sqlalchemy.dialects').addHandler(db_handler)
logging.getLogger('sqlalchemy.dialects').setLevel(log_level)
logging.getLogger('sqlalchemy.pool').addHandler(db_handler)
logging.getLogger('sqlalchemy.pool').setLevel(log_level)
logging.getLogger('sqlalchemy.orm').addHandler(db_handler)
logging.getLogger('sqlalchemy.orm').setLevel(log_level)

database.py

...
engine = create_engine(getDBURI(), echo="debug", echo_pool=True, pool_recycle=10)

答案

如果有人遇到此问题,以供将来参考,sqlalchemy引擎配置echo=True|'debug'将覆盖您的记录器.通过将引擎配置更改为以下方式解决了该问题:

For future reference if anyone runs into this issue, sqlalchemy engine configuration echo=True|'debug' will OVERRIDE your loggers. Fixed the issue by changing my engine configuration to:

engine = create_engine(getDBURI(), echo_pool=True, pool_recycle=10)

然后所有东西都像魅力一样起作用.干杯! :D

And then everything worked like a charm. Cheers! :D

推荐答案

据我了解,您针对werkzeug的基于文件的日志配置实际上正在工作=>它输出到api.log

as i understand it your file based log configuration for werkzeug is actually working => it outputs into api.log

db日志处理程序也正在工作(文件已创建等),但是没有输出. 这可能是由于默认情况下这些记录器的日志级别处于错误"状态.您需要像这样在较低级别上手动设置它们:

The db log handler is also working (file gets created etc.) but there is no output. This is probably due to the loglevel of those loggers beeing on Error by default. You need to set them manually on a lower level like this:

logging.getLogger('sqlalchemy.engine').setLevel(logging.DEBUG)
logging.getLogger('sqlalchemy.dialects').setLevel(logging.DEBUG)
logging.getLogger('sqlalchemy.pool').setLevel(logging.DEBUG)
logging.getLogger('sqlalchemy.orm').setLevel(logging.DEBUG)

werkzeug仍在输出到控制台,可能是因为始终定义了根记录器.在添加新的处理程序之前,应执行以下操作删除所有日志处理程序:

That werkzeug is still outputting to console is probably because there is allways a root logger defined. Before you add your new handlers you should do the following to remove all log handlers:

    for handler in copy(logging.getLogger().handlers):
        logging.getLogger().removeHandler(handler)
        handler.close()  # clean up used file handles

然后,您还可以使用以下方式将应用日志处理程序分配为根日志处理程序

Then you can also assign your app log handler as the root log handler with

logging.getLogger().addHandler(api_handler)

如果不是root记录器,而只是定义了默认控制台记录器的werkzeug记录器,则还可以从werkzeug记录器中删除所有处理程序,然后再添加以下内容:

If its not the root logger but just the werkzeug logger which has a default console logger defined you can also just remove all handlers from the werkzeug logger before adding yours like this:

    for handler in copy(logging.getLogger('werkzeug').handlers):
        logging.getLogger('werkzeug').removeHandler(handler)
        handler.close()  # clean up used file handles
    logging.getLogger('werkzeug').addHandler(api_handler)

这篇关于Flask + SQLAlchemy高级日志记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆