with postgres ocean digitalocean deploy aws django bash nginx gunicorn django-errors

postgres - django gunicorn service



¿Cómo ver los detalles de los errores de Django con Gunicorn? (5)

1. Enviar errores a la consola.

Estos son los loggers que usan mail_admins por defecto (ver django/utils/log.py ):

''django.request'': { ''handlers'': [''mail_admins''], ''level'': ''ERROR'', ''propagate'': False, }, ''django.security'': { ''handlers'': [''mail_admins''], ''level'': ''ERROR'', ''propagate'': False, },

necesitaría cambiar los controladores para ir a la console para que aparezca en su registro de Gunicorn en lugar de enviar correos electrónicos con mail_admins . Tenga en cuenta que no es tan hablador como cuando DEBUG=True .

''loggers'': { ''django'': { ''level'': ''ERROR'', ''handlers'': [''console''], }, }

2. enviando errores vía mail_admins

También basado en la configuración del registro, cree explícitamente un controlador que llame a mail_admins ; Por ejemplo, basado en django/utils/log.py :

''handlers'': { ''mail_admins'': { ''level'': ''ERROR'', ''class'': ''django.utils.log.AdminEmailHandler'' }, }, ''loggers'': { ''django'': { ''handlers'': [''mail_admins''], }, }

Esto requiere que establezca la settings relacionada con el correo electrónico.

3. otras soluciones

Si no estaba buscando la solución # 1, entonces su pregunta es un duplicado de: ¿Cómo se registran los errores del servidor en los sitios de django?

Acabo de implementar mi proyecto Django (1.6) con gunicorn y Nginx.

Parece que funciona bien, pero tengo una página en la que recibo un error HTTP 500 y no puedo encontrar ningún detalle sobre el error en ningún lado.

¿Cómo consigo gunicorn para mostrarme errores?

Aquí está todo lo que veo actualmente en el archivo de registro cuando llego a la página con el error:

>tail gunicorn.errors 2014-02-21 14:41:02 [22676] [INFO] Listening at: unix:/opt/djangoprojects/reports/bin/gunicorn.sock (22676) 2014-02-21 14:41:02 [22676] [INFO] Using worker: sync 2014-02-21 14:41:02 [22689] [INFO] Booting worker with pid: 22689 ... 2014-02-21 19:41:10 [22691] [DEBUG] GET /reports/2/

Aquí está mi script de bash que utilizo para iniciar gunicorn:

>cat gunicorn_start #!/bin/bash NAME="reports" # Name of the application DJANGODIR=/opt/djangoprojects/reports # Django project directory SOCKFILE=/opt/djangoprojects/reports/bin/gunicorn.sock # we will communicte using this unix socket USER=reportsuser # the user to run as GROUP=webapps # the group to run as NUM_WORKERS=4 # how many worker processes should Gunicorn spawn DJANGO_SETTINGS_MODULE=reports.settings # which settings file should Django use DJANGO_WSGI_MODULE=reports.wsgi # WSGI module name #echo "Starting $NAME as `whoami`" # Activate the virtual environment cd $DJANGODIR source pythonenv/bin/activate export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE export PYTHONPATH=$DJANGODIR:$PYTHONPATH # Create the run directory if it doesn''t exist RUNDIR=$(dirname $SOCKFILE) test -d $RUNDIR || mkdir -p $RUNDIR # Start your Django Unicorn # Programs meant to be run under supervisor should not daemonize themselves (do not use --daemon) exec gunicorn ${DJANGO_WSGI_MODULE}:application / --name $NAME / --workers $NUM_WORKERS / --user=$USER --group=$GROUP / --log-level=debug / --bind=unix:$SOCKFILE / --error-logfile /opt/djangoprojects/reports/bin/gunicorn.errors / --log-file /opt/djangoprojects/reports/bin/gunicorn.errors

Más información:

Estoy iniciando / deteniendo gunicorn con esta secuencia de comandos init.d que copié y modifiqué utilizando sudo service reports start|stop|restart :

>cat /etc/init.d/reports #!/bin/sh ### BEGIN INIT INFO # Provides: django_gunicorn # Required-Start: $local_fs $network $remote_fs # Required-Stop: $local_fs $network $remote_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Starts django_unicorn reports at boot time. # Description: Starts django_unicorn reports at boot time. ### END INIT INFO name=`basename $0` dir="/opt/djangoprojects/reports" cmd="${dir}/bin/gunicorn_start" pid_file="/var/run/$name.pid" log_file="${dir}/bin/reports.log" get_pid() { cat "$pid_file" } is_running() { [ -f "$pid_file" ] && ps `get_pid` > /dev/null 2>&1 } case "$1" in start) if is_running; then echo "Already running" else echo -n "Starting ${name}... " cd "$dir" #sudo -u "$user" $cmd &>> "$log_file" $cmd &>> "$log_file" & echo $! > "$pid_file" if ! is_running; then echo "Unable to start; see $log_file" exit 1 else echo "[STARTED]" fi fi ;; stop) if is_running; then echo -n "Stopping ${name}... " kill `get_pid` for i in {1..10} do if ! is_running; then break fi echo -n "." sleep 1 done echo if is_running; then echo "Not stopped; may still be shutting down or shutdown may have failed" exit 1 else echo "[STOPPED]" if [ -f "$pid_file" ]; then rm "$pid_file" fi fi else echo "Not running" fi ;; restart) $0 stop if is_running; then echo "Unable to stop, will not attempt to start" exit 1 fi $0 start ;; status) if is_running; then echo "[RUNNING]" else echo "[STOPPED]" exit 1 fi ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0


Respuesta corta:

Con la siguiente configuración de registro, sus errores comenzarán a aparecer en la salida de Gunicorn (sin demonios) o en el servidor de ejecución incluso cuando DEBUG es Falso. De todos modos, deberían aparecer cuando DEBUG es Verdadero.

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, }, } }

Si desea ver los errores de Django en el registro de errores de gunicorn, ejecute gunicorn con --capture-output.

http://docs.gunicorn.org/en/stable/settings.html#capture-output

Respuesta larga

Hay dos confusiones involucradas cuando se registra:

  1. Si runserver proporciona mejor registro que gunicorn
  2. ¿ settings.DEBUG=True proporciona mejor registro que settings.DEBUG=False

Cualquier registro de registro que vea con runserver puede verse también con Gunicorn siempre que tenga la configuración de registro adecuada.

Cualquier registro de registro que vea con DEBUG = Verdadero puede verse mientras DEBUG = Falso también, siempre y cuando tenga la configuración de registro apropiada.

Puede ver la configuración de registro de Django predeterminada en:

https://github.com/django/django/blob/1.10.8/django/utils/log.py#L18

Parece que: (He eliminado partes que no conciernen a esta respuesta)

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'', }, } }

Lo que esto dice es:

  1. Envíe el registro de registro del registrador django a la console manejadores y a los mail_admins .

  2. La console controlador tiene un filtro require_debug_true en él. Cuando settings.DEBUG es True, la console controlador envía / imprime el registro en el Stream (debido a logging.StreamHandler ).

Cuando settings.DEBUG es False, entonces la console controlador ignora el mensaje de registro que le envió el registrador django .

Si desea que los registros se impriman con DEBUG = False, agregue un handler y haga que el registrador django use.

El manejador se vería así:

''console_on_not_debug'': { ''level'': ''WARNING'', ''filters'': [''require_debug_false''], ''class'': ''logging.StreamHandler'', },

Y usa este manejador con logger django :

''django'': { ''handlers'': [''console'', ''mail_admins'', ''console_on_not_debug''], ''level'': ''INFO'', },

Puedes ver el fragmento completo en breve respuesta.

Con esto, los registros se imprimirán en secuencia independientemente de si está utilizando runserver o gunicorn.

Si desea que los registros se muestren en el registro de errores de gunicorn, entonces necesita ejecutar gunicorn con --capture-output.


Desde su comentario, creo que este es un problema de configuración en su sitio de django, no es una cuestión de registro de Gunicorn, los registros no mostrarán más que el envío de django.

Este es un ejemplo de cómo puede configurar la configuración de django para enviar el registro a su archivo (en lugar de enviarlo a los administradores por correo electrónico de manera predeterminada):

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, }, } }

Lea la configuración del registro (proporciona una muy buena explicación de las opciones de configuración de registro) y estudie el archivo django/utils/log.py para configurar el django/utils/log.py de django para que aparezca más detallado en los registros de gunicorn.

También verifique esta respuesta y this proporciona ejemplos de configuración para enviar errores de registros directamente a un archivo. Y considere usar Sentry para manejar los errores de registro, como lo recomended los chicos de Django.

Espero que esto ayude.


Esta configuración funcionó para mí. Agregue --capture-output --enable-stdio-inheritance inheritance con el comando gunicorn como se muestra a continuación.

/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

Con esta configuración, habilite el registro de esta manera

import logging logging.basicConfig(level=''DEBUG'') logging.info(''hello world'')

De esta manera también podrás ver los errores en la aplicación.


La solución más sencilla es configurar la variable ADMINS con direcciones de correo electrónico de personas que deben recibir notificaciones de error. Cuando DEBUG = False y una vista genera una excepción, Django enviará un correo electrónico a estas personas con la información completa de la excepción.

settings.py

ADMINS = ((''John'', ''[email protected]''), (''Mary'', ''[email protected]'')) # or only ADMINS = ((''John'', ''[email protected]''),)

Quizás también necesite EMAIL_HOST y EMAIL_PORT si el servidor SMTP correcto no es localhost en el puerto 25 . Esta solución simple es lo suficientemente buena para la operación de producción de prueba, de lo contrario puede producir de repente demasiados correos electrónicos.