问题
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:
- Add a custom
HTTPHandler
for sending logs toSlack
since the data must be sent viaapplication/json
inpost
request - For
email
you can youSMTPHandler
- Use
gunicorn.error
andgunicorn.access
loggers to get errors from Gunicorn - Use
root
if you are usingpython
loggers - Use
RotatingFileHandler
foraccess
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