Why Flask logger does not log in docker when using UWSGI in front?

后端 未结 2 1001

I have a Flask application inside of Docker that was logging into docker logs when it was running without UWSGI in front. Now

相关标签:
2条回答
  • 2021-02-07 07:29

    First of all, there are recent changes in the way Flask logs are initialized from version 0.9 to the current stable 1.0.2, for example. You can check this here. I am assuming your docker image uses the most recent version.

    If that is the case, even without any custom logging config, actually it is logging for your output stream, but it is filtering out lower than WARNING logs (DEBUG and INFO). This happens when you rely on Flask initializing the log for you and you do not set a --debug flag (uwsgi case).

    There are multiple strategies that can be looked at when you configure logging. One suggestion is to use the dictConfig initialization mentioned by the library itself, at the uwsgi master, before defining the app, which then forks. Following your example, at __init__.py:

    from flask import Flask
    from logging.config import dictConfig
    
    dictConfig({
        'version': 1,
        'formatters': {'default': {
            'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
        }},
        'handlers': {'wsgi': {
            'class': 'logging.StreamHandler',
            'formatter': 'default'
        }},
        'root': {
            'level': 'DEBUG',
            'handlers': ['wsgi']
        }
    })
    
    app = Flask(__name__)
    

    The problem you mention in EDIT-1 looks like a python logging propagation issue. There is a standalone case, easier to debug, here.

    Even though you have only set one Stream Handler, as your log shows, it probably has a parent attached. If you check for its parent it will probably have a handler attached different from the one you mentioned in EDIT-2 :

    print logger.handlers
    [<logging.StreamHandler object at 0x7f15669c1550>]
    print logger.parent.handlers
    [<logging.StreamHandler object at 0x7f15669c1610>]
    

    This happens when the logging propagation is enabled and there happened some logging initialization elsewhere. You can check how propagation works by looking at callHandlers in python's source code:

        ...
        hdlr.handle(record)
        if not c.propagate:
            c = None    #break out
        else:
            c = c.parent
        ...
    

    Back to your case (Flask), by looking at the traces in your logs, there is a logger named flask.app, which is the one created by Flask itself. There is the formatted version, and the unformatted one (logging.BASIC_FORMAT), respectively. So it is probably being initialized somewhere in your code or in one of the libraries you import.

    There are multiple ways you can solve this:

    • Setting the propagation to false (easy solution, but workaround)
    • Searching for the "invalid" configuration and removing it
    • Use the dictConfig initialization, before instantiating the app, as the Flask logging tutorial suggests
    0 讨论(0)
  • 2021-02-07 07:34

    I had a similar problem (Special: I wanted to use the syslog). First I had to add a rule to the Dockerfile:

    RUN apt-get install -y rsyslog
    service rsyslog start
    

    Flask comes with build-in logging, so I just had to add some twigs

    from flask import Flask
    import logging
    import logging.handlers
    
    handler = logging.handlers.SysLogHandler(address = '/dev/log')
    handler.setFormatter(logging.Formatter('flask [%(levelname)s] %(message)s'))
    
    app = Flask(__name__)
    app.logger.addHandler(handler)
    

    Additional settings can be handled through the syslog-daemon

    0 讨论(0)
提交回复
热议问题