opbeat_python icon indicating copy to clipboard operation
opbeat_python copied to clipboard

Unable to log celery tasks with settings extended via DJANGO_SETTINGS_MODULE

Open bendemboski opened this issue 9 years ago • 0 comments

Django 1.10.4 Celery 4.0.2 Opbeat 3.5.2

My production deployment pattern involves creating a separate settings module that imports my project's default settings file and then overrides some values with production-specific settings, meaning that when I run in production I use the DJANGO_SETTINGS_MODULE environment variable to point to a module outside my project's main app. After updating to the latest celery, uninstalling djcelery, and following the Logging Celery Tasks instructions, running my app results in

ImproperlyConfigured("The SECRET_KEY setting must not be empty.")

The problem is that with this setup, importing from opbeat.contrib.django.models from celery.py creates a circular dependency:

django.conf.settings -> DJANGO_SETTINGS_MODULE
                     -> myapp.settings
                     -> (implicit) myapp/__init__.py
                     -> myapp.celery
                     -> opbeat.contrib.django.models
                     -> django.conf.settings
                     -> DJANGO_SETTINGS_MODULE
                     -> myapp.settings
                     -> (implicit) myapp/__init__.py
                     ...

You can reproduce this issue with the following steps:

  1. django-admin.py startproject myapp
  2. Run the Logging Celery Tasks (including the linked Celery Django setup instructions)
  3. Create custom_settings.py at the root of the project containing from myapp.settings import *
  4. Run DJANGO_SETTINGS_MODULE=custom_settings ./manage.py runserver

the result will be:

Traceback (most recent call last):
  File "./manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/venv/lib/python2.7/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
    utility.execute()
  File "/venv/lib/python2.7/site-packages/django/core/management/__init__.py", line 359, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/venv/lib/python2.7/site-packages/django/core/management/base.py", line 306, in run_from_argv
    connections.close_all()
  File "/venv/lib/python2.7/site-packages/django/db/utils.py", line 229, in close_all
    for alias in self:
  File "/venv/lib/python2.7/site-packages/django/db/utils.py", line 223, in __iter__
    return iter(self.databases)
  File "/venv/lib/python2.7/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/venv/lib/python2.7/site-packages/django/db/utils.py", line 156, in databases
    self._databases = settings.DATABASES
  File "/venv/lib/python2.7/site-packages/django/conf/__init__.py", line 53, in __getattr__
    self._setup(name)
  File "/venv/lib/python2.7/site-packages/django/conf/__init__.py", line 41, in _setup
    self._wrapped = Settings(settings_module)
  File "/venv/lib/python2.7/site-packages/django/conf/__init__.py", line 97, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/projects/myapp/custom_settings.py", line 1, in <module>
    from myapp.settings import *
  File "/projects/myapp/myapp/__init__.py", line 5, in <module>
    from .celery import app as celery_app  # noqa
  File "/projects/myapp/myapp/celery.py", line 28, in <module>
    from opbeat.contrib.django.models import client, logger, register_handlers # noqa
  File "/venv/lib/python2.7/site-packages/opbeat/contrib/django/models.py", line 226, in <module>
    if 'opbeat.contrib.django' in django_settings.INSTALLED_APPS:
  File "/venv/lib/python2.7/site-packages/django/conf/__init__.py", line 53, in __getattr__
    self._setup(name)
  File "/venv/lib/python2.7/site-packages/django/conf/__init__.py", line 41, in _setup
    self._wrapped = Settings(settings_module)
  File "/venv/lib/python2.7/site-packages/django/conf/__init__.py", line 116, in __init__
    raise ImproperlyConfigured("The SECRET_KEY setting must not be empty.")
django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.

bendemboski avatar Dec 28 '16 21:12 bendemboski