Setting up logging for Gunicorn in a Flask application using Python's dictConfig

喜欢而已 提交于 2020-05-17 02:57:49

问题


I want to send my error logs via email or slack webhook and also save access log in a file. And when I try to run with Gunicorn as my application server, I don't see any logs in my terminal. What's the right way to setup Flask application logging with Gunicorn.

# This is the command I am using
gunicorn app:app -b 0.0.0.0:5000

回答1:


  1. Add a custom HTTPHandler for sending logs to Slack since the data must be sent via application/json in post request
  2. For email you can you SMTPHandler
  3. Use gunicorn.error and gunicorn.access loggers to get errors from Gunicorn
  4. Use root if you are using python loggers
  5. Use RotatingFileHandler for access log file rotation
import json
import requests
import logging
from logging.config import dictConfig

from flask import Flask

# for sending error logs to slack
class HTTPSlackHandler(logging.Handler):
    def emit(self, record):
        log_entry = self.format(record)
        json_text = json.dumps({"text": log_entry})
        url = SLACK_WEBHOOK
        return requests.post(url, json_text, headers={"Content-type": "application/json"}).content


dictConfig({
    "version": 1,
    "disable_existing_loggers": True,
    "formatters": {
        "default": {
            "format": "[%(asctime)s] %(levelname)s in %(module)s: %(message)s",
        },
        "access": {
            "format": "%(message)s",
        }
    },
    "handlers": {
        "console": {
            "level": "INFO",
            "class": "logging.StreamHandler",
            "formatter": "default",
            "stream": "ext://sys.stdout",
        },
        "email": {
            "class": "logging.handlers.SMTPHandler",
            "formatter": "default",
            "level": "ERROR",
            "mailhost": ("smtp.example.com", 587),
            "fromaddr": "devops@example.com",
            "toaddrs": ["receiver@example.com", "receiver2@example.com"],
            "subject": "Error Logs",
            "credentials": ("username", "password"),
        },
        "slack": {
            "class": "app.HTTPSlackHandler",
            "formatter": "default",
            "level": "ERROR",
        },
        "error_file": {
            "class": "logging.handlers.RotatingFileHandler",
            "formatter": "default",
            "filename": "/var/log/gunicorn.error.log",
            "maxBytes": 10000,
            "backupCount": 10,
            "delay": "True",
        },
        "access_file": {
            "class": "logging.handlers.RotatingFileHandler",
            "formatter": "access",
            "filename": "/var/log/gunicorn.access.log",
            "maxBytes": 10000,
            "backupCount": 10,
            "delay": "True",
        }
    },
    "loggers": {
        "gunicorn.error": {
            "handlers": ["console"] if debug else ["console", "slack", "error_file"],
            "level": "INFO",
            "propagate": False,
        },
        "gunicorn.access": {
            "handlers": ["console"] if debug else ["console", "access_file"],
            "level": "INFO",
            "propagate": False,
        }
    },
    "root": {
        "level": "DEBUG" if debug else "INFO",
        "handlers": ["console"] if debug else ["console", "slack"],
    }
})

app = Flask(__name__)

if __name__ == "__main__":
    app.run(debug=debug, host="0.0.0.0", port="5000")

This is the right way to run the above application

# make sure to give --access-logfile and --error-logfile as '-' to make gunicorn send logs to stdout
gunicorn app:app -b 0.0.0.0:5000 --workers 2 -k gevent --timeout 300 --worker-connections 1000 --max-requests 1000000 --limit-request-line 8190 --access-logfile '-' --error-logfile '-'

Hope this helps!



来源:https://stackoverflow.com/questions/61257818/setting-up-logging-for-gunicorn-in-a-flask-application-using-pythons-dictconfig

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!