Gunicorn logging #111

This commit is contained in:
Daniel Grams 2021-02-14 09:57:57 +01:00
parent 78728ab6bf
commit 3ef8b9b3c6
6 changed files with 48 additions and 24 deletions

View File

@ -36,7 +36,7 @@ source venv/bin/activate
(venv) pip install -r requirements.txt (venv) pip install -r requirements.txt
(venv) export DATABASE_URL='postgresql://postgres@localhost/gsevpt' (venv) export DATABASE_URL='postgresql://postgres@localhost/gsevpt'
(venv) flask db upgrade (venv) flask db upgrade
(venv) gunicorn -c gunicorn.conf.py --bind 0.0.0.0:5000 project:app (venv) gunicorn -c gunicorn.conf.py project:app
``` ```
## Scheduled/Cron jobs ## Scheduled/Cron jobs
@ -62,27 +62,27 @@ Create `.env` file in the root directory or pass as environment variables.
### Security ### Security
| Variable | Function | | Variable | Function |
| --- | --- | | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| SECRET_KEY | A secret key for verifying the integrity of signed cookies. Generate a nice key using `python3 -c "import secrets; print(secrets.token_urlsafe())"`. | | SECRET_KEY | A secret key for verifying the integrity of signed cookies. Generate a nice key using `python3 -c "import secrets; print(secrets.token_urlsafe())"`. |
| SECURITY_PASSWORD_HASH | Bcrypt is set as default SECURITY_PASSWORD_HASH, which requires a salt. Generate a good salt using: `python3 -c "import secrets; print(secrets.SystemRandom().getrandbits(128))"`. | | SECURITY_PASSWORD_HASH | Bcrypt is set as default SECURITY_PASSWORD_HASH, which requires a salt. Generate a good salt using: `python3 -c "import secrets; print(secrets.SystemRandom().getrandbits(128))"`. |
### Send notifications via Mail ### Send notifications via Mail
| Variable | Function | | Variable | Function |
| --- | --- | | ------------------- | ------------------------------------------ |
| MAIL_DEFAULT_SENDER | see <https://pythonhosted.org/Flask-Mail/> | | MAIL_DEFAULT_SENDER | see <https://pythonhosted.org/Flask-Mail/> |
| MAIL_PASSWORD | " | | MAIL_PASSWORD | " |
| MAIL_PORT | " | | MAIL_PORT | " |
| MAIL_SERVER | " | | MAIL_SERVER | " |
| MAIL_USERNAME | " | | MAIL_USERNAME | " |
### Misc ### Misc
| Variable | Function | | Variable | Function |
| --- | --- | | ------------------- | -------------------------------------------------------------------------------------------- |
| CACHE_PATH | Absolute or relative path to root directory for dump and image caching. Default: project/tmp | | CACHE_PATH | Absolute or relative path to root directory for dump and image caching. Default: project/tmp |
| GOOGLE_MAPS_API_KEY | Resolve addresses with Google Maps: API Key with Places API enabled | | GOOGLE_MAPS_API_KEY | Resolve addresses with Google Maps: API Key with Places API enabled |
## Development ## Development

View File

@ -6,5 +6,4 @@ do
sleep 2 sleep 2
done done
BIND_PORT=${PORT:-5000} gunicorn -c gunicorn.conf.py project:app
gunicorn -c gunicorn.conf.py --bind 0.0.0.0:$BIND_PORT project:app

View File

@ -1,5 +1,22 @@
import multiprocessing import multiprocessing
import os
# Bind
port = os.getenv(
"PORT", "5000"
) # No Prefix here because some hosting provider use 'PORT'
bind = os.getenv("GUNICORN_BIND", f"0.0.0.0:{port}")
# Workers
workers = multiprocessing.cpu_count() * 2 + 1 workers = multiprocessing.cpu_count() * 2 + 1
# Logging
capture_output = True capture_output = True
errorlog = "-" accesslog = os.getenv("GUNICORN_ACCESS_LOG", None)
access_log_format = os.getenv(
"GUNICORN_ACCESS_LOG_FORMAT",
'%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"',
)
errorlog = os.getenv("GUNICORN_ERROR_LOG", "-")
loglevel = os.getenv("GUNICORN_LOG_LEVEL", "info")
logconfig = os.getenv("GUNICORN_LOG_CONFIG", None)

View File

@ -1,3 +1,4 @@
import logging
import os import os
from flask import Flask, jsonify, redirect, request, url_for from flask import Flask, jsonify, redirect, request, url_for
@ -36,6 +37,13 @@ app.config["SECURITY_PASSWORD_SALT"] = os.environ.get(
"SECURITY_PASSWORD_SALT", "146585145368132386173505678016728509634" "SECURITY_PASSWORD_SALT", "146585145368132386173505678016728509634"
) )
# Gunicorn logging
if __name__ != "__main__":
gunicorn_logger = logging.getLogger("gunicorn.error")
if gunicorn_logger.hasHandlers():
app.logger.handlers = gunicorn_logger.handlers
app.logger.setLevel(gunicorn_logger.level)
# Gzip # Gzip
gzip = Gzip(app) gzip = Gzip(app)
@ -76,8 +84,8 @@ mail = Mail(app)
if app.config["MAIL_SUPPRESS_SEND"]: if app.config["MAIL_SUPPRESS_SEND"]:
def log_message(message, app): def log_message(message, app):
print(message.subject) app.logger.info(message.subject)
print(message.body) app.logger.info(message.body)
email_dispatched.connect(log_message) email_dispatched.connect(log_message)

View File

@ -68,6 +68,6 @@ def developer():
"ctime": os.path.getctime(all_path), "ctime": os.path.getctime(all_path),
} }
else: else:
print("No file at %s" % all_path) app.logger.info("No file at %s" % all_path)
return render_template("developer/read.html", dump_file=dump_file) return render_template("developer/read.html", dump_file=dump_file)

View File

@ -4,7 +4,7 @@ from flask_mail import Message
from psycopg2.errorcodes import UNIQUE_VIOLATION from psycopg2.errorcodes import UNIQUE_VIOLATION
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from project import db, mail from project import app, db, mail
from project.models import Analytics from project.models import Analytics
@ -91,9 +91,9 @@ def send_mails(recipients, subject, template, **context):
msg.html = render_template("email/%s.html" % template, **context) msg.html = render_template("email/%s.html" % template, **context)
if not mail.default_sender: if not mail.default_sender:
print(",".join(msg.recipients)) app.logger.info(",".join(msg.recipients))
print(msg.subject) app.logger.info(msg.subject)
print(msg.body) app.logger.info(msg.body)
return return
mail.send(msg) mail.send(msg)