31👍
From your comment I think this is a config problem in your django site, not a matter of gunicorn log, logs will not show more than django send to it.
Here is an example of how you can configure django setting to send log to your file (instead of send it to admins by email as default):
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'formatters': {
'verbose': {
'format': '%(asctime)s %(levelname)s [%(name)s:%(lineno)s] %(module)s %(process)d %(thread)d %(message)s'
}
},
'handlers': {
'gunicorn': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'formatter': 'verbose',
'filename': '/opt/djangoprojects/reports/bin/gunicorn.errors',
'maxBytes': 1024 * 1024 * 100, # 100 mb
}
},
'loggers': {
'gunicorn.errors': {
'level': 'DEBUG',
'handlers': ['gunicorn'],
'propagate': True,
},
}
}
Read configuring logging (it provide a very well explanations of log settings options) and study the file django/utils/log.py to configure django loggin to appears more detailed on gunicorn logs.
Also check this answer and this which provide setting examples to send logs errors directly to a file. And consider to use Sentry to handle log errors, as is recomended by django guys.
Hope this helps.
27👍
This configuration worked for me. Add --capture-output --enable-stdio-inheritance
with gunicorn command like below.
/home/ubuntu/inside-env/bin/gunicorn --access-logfile /var/log/access_file_g.log --error-logfile /var/log/error_file_g.log --capture-output --enable-stdio-inheritance --workers 3 --bind unix:/home/ubuntu/path-to-project/webapp.sock project.wsgi:application
With this setup, do enable logging in this way
import logging
logging.basicConfig(level='DEBUG')
logging.info('hello world')
This way you will get to see the errors in the App as well.
- [Django]-How can i set the size of rows , columns in textField in Django Models
- [Django]-Python Django Rest Framework UnorderedObjectListWarning
- [Django]-How to change field name in Django REST Framework
13👍
Short answer:
With following logging configuration, your errors will start showing up in Gunicorn output(undaemonized) or runserver even when DEBUG is False. They anyways should be showing up when DEBUG is True.
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse',
},
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'formatters': {
'django.server': {
'()': 'django.utils.log.ServerFormatter',
'format': '[%(server_time)s] %(message)s',
}
},
'handlers': {
'console': {
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
},
# Custom handler which we will use with logger 'django'.
# We want errors/warnings to be logged when DEBUG=False
'console_on_not_debug': {
'level': 'WARNING',
'filters': ['require_debug_false'],
'class': 'logging.StreamHandler',
},
'django.server': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'formatter': 'django.server',
},
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'django': {
'handlers': ['console', 'mail_admins', 'console_on_not_debug'],
'level': 'INFO',
},
'django.server': {
'handlers': ['django.server'],
'level': 'INFO',
'propagate': False,
},
}
}
If you want to see the Django errors in gunicorn error log, run gunicorn with –capture-output.
http://docs.gunicorn.org/en/stable/settings.html#capture-output
Long answer
There are two confusions involved when logging:
- Whether
runserver
provide better log thangunicorn
- Does
settings.DEBUG=True
provide better log thansettings.DEBUG=False
Any log record you see with runserver can be seen with Gunicorn too as long as you have appropriate logging configuration.
Any log record you see with DEBUG=True can be seen while DEBUG=False too as long as you have appropriate logging configuration.
You can see default Django logging configuration at:
https://github.com/django/django/blob/1.10.8/django/utils/log.py#L18
It looks like: (I have stripped out parts which don’t concern this answer)
DEFAULT_LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse',
},
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': {
'console': {
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
},
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'django': {
'handlers': ['console', 'mail_admins'],
'level': 'INFO',
},
}
}
What this says is:
-
Send
django
logger log record to handlersconsole
andmail_admins
. -
Handler
console
has a filterrequire_debug_true
on it. When settings.DEBUG is True, then handlerconsole
sends/prints the log on the Stream (because oflogging.StreamHandler
).
When settings.DEBUG is False, then handler console
ignores the log message sent to it by logger django
.
If you want logs to be printed with DEBUG=False too, then add a handler
and make logger django
use it.
Handler would look like:
'console_on_not_debug': {
'level': 'WARNING',
'filters': ['require_debug_false'],
'class': 'logging.StreamHandler',
},
And use this handler with logger django
:
'django': {
'handlers': ['console', 'mail_admins', 'console_on_not_debug'],
'level': 'INFO',
},
You can see the entire snippet in short answer.
With this, the logs will be printed on stream irrespective of if you are using runserver or gunicorn.
If you want the logs to be shown in gunicorn error log, then you need to run gunicorn with –capture-output.
- [Django]-Migrating Django fixtures?
- [Django]-What is a "slug" in Django?
- [Django]-How to get the current url namespace using Django?
7👍
1. sending errors to the console
These are the loggers
that use mail_admins
by default (see django/utils/log.py
):
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
'django.security': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
you would need to change the handlers to go to the console
so that it appears in your gunicorn log rather than send emails with mail_admins
. Please note that it’s not as chatty as when DEBUG=True
.
'loggers': {
'django': {
'level': 'ERROR',
'handlers': ['console'],
},
}
2. sending errors via mail_admins
Also based on configuring logging, explicitly create a handler that calls mail_admins
; e.g. based on django/utils/log.py
:
'handlers': {
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler'
},
},
'loggers': {
'django': {
'handlers': ['mail_admins'],
},
}
This requires you to set email related settings
.
3. other solutions
If you were not looking for solution #1, then your question is a duplicate of:
How do you log server errors on django sites
- [Django]-Django: Use of DATE_FORMAT, DATETIME_FORMAT, TIME_FORMAT in settings.py?
- [Django]-How to get superuser details in Django?
- [Django]-Django: Redirect to previous page after login
5👍
Running Django 3.8 on Heroku with gunicorn 20.1, I had the problem that application errors were not showing up in the Papertrail logs.
To fix this all I had to do was add the minimal recommended logging configuration from the Django docs to settings.py:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'root': {
'handlers': ['console'],
'level': 'WARNING',
},
}
This is necessary because in Django’s default logging configuration in production (when DEBUG
is False
) the django logger sends messages to AdminEmailHandler
, instead of to the console.
I am starting gunicorn in the Procfile with web: gunicorn my_project.wsgi
, and I did not need to change that (i.e. I did not need to use --capture-output
or --enable-stdio-inheritance
).
- [Django]-Django – Reverse for '' not found. '' is not a valid view function or pattern name
- [Django]-Django – Where are the params stored on a PUT/DELETE request?
- [Django]-What is the use of PYTHONUNBUFFERED in docker file?
3👍
The simplest solution is to configure the variable ADMINS with email addresses of people who should get error notifications.
When DEBUG=False and a view raises an exception, Django will email these people with the full exception information.
settings.py
ADMINS = (('John', 'john@example.com'), ('Mary', 'mary@example.com'))
# or only ADMINS = (('John', 'john@example.com'),)
Maybe you need also EMAIL_HOST and EMAIL_PORT if the right SMTP server is not localhost
on port 25
. This simple solution is good enough for trial production operation, otherwise it can produce suddenly too much emails.
- [Django]-Testing admin.ModelAdmin in django
- [Django]-How do I use a dictionary to update fields in Django models?
- [Django]-Dropdown in Django Model