Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my gunicorn process ignoring the log-level setting with Django?

I have Nginx, Gunicorn, and Django all running on the same Ubuntu EC2 instance. I have a fairly conventional setup and would like to log all gunicorn errors to a particular file.

My configuration for Gunicorn is:

#!/bin/bash

NAME="server"
GUNICORNDIR=/ebs/env/bin
DJANGODIR=/ebs/server/
SOCKFILE=/tmp/gunicorn.sock
LOGFILE=/var/log/gunicorn/gunicorn.error
USER=ubuntu
GROUP=ubuntu
NUM_WORKERS=5
TIMEOUT=60
DJANGO_SETTINGS_MODULE=settings
DJANGO_WSGI_MODULE=wsgi

echo "Starting $NAME"

RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR

exec $GUNICORNDIR/gunicorn ${DJANGO_WSGI_MODULE}:application \
  --name $NAME \
  --workers $NUM_WORKERS \
  --timeout=$TIMEOUT \
  --user=$USER --group=$GROUP \
  --log-level=error --log-file=$LOGFILE \
  --bind=unix:$SOCKFILE

However with this configuration I am getting all logs from DEBUG and above written to the file. My log-level parameter appears to be getting ignored.

What I am looking for is to only have these types of log messages written:

2014-01-02 13:54:53 [3327] [CRITICAL] WORKER TIMEOUT (pid:3338)
2014-01-02 13:54:53 [3327] [CRITICAL] WORKER TIMEOUT (pid:3338)

I thought that the Django logging config specified in my settings.py might be interfering so I added a handler and a logger to try and target gunicorn but that did not work.

'handlers': {
'gunicorn': {
    'level': 'ERROR',
    'class': 'logging.handlers.RotatingFileHandler',
    'formatter': 'verbose',
    'filename': '/ebs/log/gunicorn.error',
    'maxBytes': 1024 * 1024 * 100,
},
}
'loggers': {
'gunicorn.errors': {
'level': 'ERROR',
'handlers': ['gunicorn'],
'propagate': False,
},

Here are the versions that I am running

Django 1.5.4 Nginx nginx/1.1.19 Gunicorn 18.0

Any thoughts on what is wrong here?

** Update **

Here is what my django logging config looks like:

LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'root': {
    'level': 'WARNING',
    'handlers': ['sentry'],
},
'formatters': {
    'verbose': {
        'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
    },
    'simple': {
        'format': '%(levelname)s %(asctime)s -- %(message)s'
    }
},
'handlers': {
    'sentry': {
        'level': 'ERROR',
        'class': 'raven.contrib.django.raven_compat.handlers.SentryHandler',
    },
    'sentry_file': {
        'level': 'ERROR',
        'class': 'logging.handlers.RotatingFileHandler',
        'formatter': 'verbose',
        'filename': '/ebs/log/sentry_log.txt',
        'maxBytes': 1024 * 1024 * 100,  # 100 mb
    },
    'celery': {
        'level': 'DEBUG',
        'class': 'logging.handlers.RotatingFileHandler',
        'filename': '/ebs/log/celery/celery.log',
        'formatter': 'verbose',
        'maxBytes': 1024 * 1024 * 100,
    },
    'apps': {
        'level': 'DEBUG',
        'class': 'logging.handlers.RotatingFileHandler',
        'formatter': 'verbose',
        'filename': '/ebs/log/apps.log',
        'maxBytes': 1024 * 1024 * 100,
    },
    'apps.dss': {
        'level': 'DEBUG',
        'class': 'logging.handlers.RotatingFileHandler',
        'formatter': 'verbose',
        'filename': '/ebs/log/dss_apps.log',
        'maxBytes': 1024 * 1024 * 100,
    },

},
'loggers': {
    'django.db.backends': {
        'level': 'DEBUG',
        'handlers': ['sentry'],
        'propagate': False,
    },
    'sentry': {
        'level': 'DEBUG',
        'handlers': ['sentry'],
        'propagate': False,
    },
    'sentry.errors': {
        'level': 'ERROR',
        'handlers': ['sentry_file', 'sentry'],
        'propagate': False,
    },
    'celery': {
        'level': 'INFO',
        'handlers': ['sentry', 'celery'],
        'propagate': False
    },
    'apps': {
        'level': 'DEBUG',
        'handlers': ['apps', 'sentry'],
        'propagate': False
    },
    'apps.dss' : {
        'level': 'DEBUG',
        'handlers': ['apps.dss', 'sentry'],
        'propagate': False,
    },
},
}
like image 837
Dana Ford Avatar asked Jan 02 '14 14:01

Dana Ford


People also ask

How do I enable logging in Django?

By default, the LOGGING setting is merged with Django's default logging configuration using the following scheme. If the disable_existing_loggers key in the LOGGING dictConfig is set to True (which is the dictConfig default if the key is missing) then all loggers from the default configuration will be disabled.

How does Gunicorn work with Django?

Gunicorn implements the PEP3333 WSGI server standard specification so that it can run Python web applications that implement the application interface. For example, if you write a web application with a web framework such as Django, Flask or Bottle, then your application implements the WSGI specification.

How do I get the Gunicorn log?

¶ In version 19.0, Gunicorn doesn't log by default in the console. To watch the logs in the console you need to use the option --log-file=- . In version 19.2, Gunicorn logs to the console by default again.

What is the type of configuration Django requires for logging?

In Django, the LOGGING setting is most commonly used. The setting uses the dictConfig format, and extends the default logging configuration.


1 Answers

The --log-level setting of gunicorn only affects gunicorns own error logging facility. But the standard error and standard output of your application will also end up in the gunicorn log. I think you might have a StreamHandler somewhere in your Django logging config. StreamHandler logs to stderr by default, so it ends up in your gunicorn log. Remove the StreamHandler or increase the level to fix your problem.

like image 58
sk1p Avatar answered Oct 27 '22 12:10

sk1p