【问题标题】:Logging stdout to gunicorn access log?将标准输出记录到 gunicorn 访问日志?
【发布时间】:2014-01-28 07:47:00
【问题描述】:

当我将我的 Flask 应用程序包装在 gunicorn 中时,写入标准输出似乎不再适用(简单的 print 语句不会出现)。有没有办法将标准输出捕获到 gunicorn 访问日志中,或者获取访问日志的句柄并直接写入它?

【问题讨论】:

  • 我发现错误不会出现在任何地方,而print 语句将提供没有错误。

标签: flask gunicorn


【解决方案1】:

使用日志记录:将流设置为标准输出

import logging

app.logger.addHandler(logging.StreamHandler(sys.stdout))
app.logger.setLevel(logging.DEBUG)

app.logger.debug("Hello World")

【讨论】:

    【解决方案2】:

    这个问题的两个解决方案。它们可能比其他的更长,但最终它们会利用 Python 的底层日志记录。

    1。在 Flask 应用中设置日志记录配置

    关于日志记录的官方 Flask 文档适用于 gunicorn。 https://flask.palletsprojects.com/en/1.1.x/logging/#basic-configuration

    • 一些示例代码可以试用:
    from logging.config import dictConfig
    
    from flask import Flask
    
    dictConfig(
        {
            "version": 1,
            "disable_existing_loggers": False,
            "formatters": {
                "default": {
                    "format": "[%(asctime)s] [%(process)d] [%(levelname)s] in %(module)s: %(message)s",
                    "datefmt": "%Y-%m-%d %H:%M:%S %z"
                }
            },
            "handlers": {
                "wsgi": {
                    "class": "logging.StreamHandler",
                    "stream": "ext://flask.logging.wsgi_errors_stream",
                    "formatter": "default",
                }
            },
            "root": {"level": "DEBUG", "handlers": ["wsgi"]},
        }
    )
    app = Flask(__name__)
    
    @app.route("/")
    def hello():
        app.logger.debug("this is a DEBUG message")
        app.logger.info("this is an INFO message")
        app.logger.warning("this is a WARNING message")
        app.logger.error("this is an ERROR message")
        app.logger.critical("this is a CRITICAL message")
        return "hello world"
    
    • 使用gunicorn 运行
    gunicorn -w 2 -b 127.0.0.1:5000 --access-logfile - app:app
    
    • 使用 curl 请求它
    curl http://127.0.0.1:5000
    
    • 这将生成以下日志
    [2020-09-04 11:24:43 +0200] [2724300] [INFO] Starting gunicorn 20.0.4
    [2020-09-04 11:24:43 +0200] [2724300] [INFO] Listening at: http://127.0.0.1:5000 (2724300)
    [2020-09-04 11:24:43 +0200] [2724300] [INFO] Using worker: sync
    [2020-09-04 11:24:43 +0200] [2724311] [INFO] Booting worker with pid: 2724311
    [2020-09-04 11:24:43 +0200] [2724322] [INFO] Booting worker with pid: 2724322
    [2020-09-04 11:24:45 +0200] [2724322] [DEBUG] in flog: this is a DEBUG message
    [2020-09-04 11:24:45 +0200] [2724322] [INFO] in flog: this is an INFO message
    [2020-09-04 11:24:45 +0200] [2724322] [WARNING] in flog: this is a WARNING message
    [2020-09-04 11:24:45 +0200] [2724322] [ERROR] in flog: this is an ERROR message
    [2020-09-04 11:24:45 +0200] [2724322] [CRITICAL] in flog: this is a CRITICAL message
    127.0.0.1 - - [04/Sep/2020:11:24:45 +0200] "GET / HTTP/1.1" 200 11 "-" "curl/7.68.0"
    

    2。在 Gunicorn 中设置日志记录配置

    • 与上述相同的应用程序代码,但没有 dictConfig({...}) 部分

    • 创建一个logging.ini 文件

    [loggers]
    keys=root
    
    [handlers]
    keys=consoleHandler
    
    [formatters]
    keys=simpleFormatter
    
    [logger_root]
    level=DEBUG
    handlers=consoleHandler
    
    [handler_consoleHandler]
    class=StreamHandler
    level=DEBUG
    formatter=simpleFormatter
    args=(sys.stdout,)
    
    [formatter_simpleFormatter]
    format=[%(asctime)s] [%(process)d] [%(levelname)s] - %(module)s - %(message)s
    datefmt=%Y-%m-%d %H:%M:%S %z
    
    • 使用--log-config logging.ini 选项运行 gunicorn,即gunicorn -w 2 -b 127.0.0.1:5000 --access-logfile - --log-config logging.ini app:app

    【讨论】:

      【解决方案3】:

      John mee 的解决方案有效,但它复制了 gunicorn 标准输出中的日志条目。

      我用过这个:

      import logging
      from flask import Flask
      
      app = Flask(__name__)
      
      if __name__ != '__main__':
          gunicorn_logger = logging.getLogger('gunicorn.error')
          app.logger.handlers = gunicorn_logger.handlers
          app.logger.setLevel(gunicorn_logger.level)
      

      https://medium.com/@trstringer/logging-flask-and-gunicorn-the-manageable-way-2e6f0b8beb2f得到这个

      【讨论】:

        【解决方案4】:

        您可以将标准输出重定向到 errorlog 文件,这对我来说已经足够了。

        注意that

        capture_output

        --capture-output
        False
        将 stdout/stderr 重定向到 errorlog

        中的指定文件

        我的配置文件gunicorn.config.py设置

        accesslog = 'gunicorn.log'
        errorlog = 'gunicorn.error.log'
        capture_output = True
        

        然后用gunicorn app_py:myapp -c gunicorn.config.py运行

        等价的命令行是

        gunicorn app_py:myapp --error-logfile gunicorn.error.log --access-logfile gunicorn.log --capture-output

        【讨论】:

          猜你喜欢
          • 2019-01-30
          • 2016-09-24
          • 1970-01-01
          • 2017-04-13
          • 1970-01-01
          • 2020-10-12
          • 1970-01-01
          • 2019-01-10
          • 2011-09-18
          相关资源
          最近更新 更多