graphite-project / graphite-web

A highly scalable real-time graphing system
http://graphite.readthedocs.org/
Apache License 2.0
5.89k stars 1.26k forks source link

[Q]ImportError: No module named django.conf #2761

Closed itinneed2022 closed 2 years ago

itinneed2022 commented 2 years ago

OS: Centos 7 Deployment: VirtualEnv using the Source installation Python Version: 3.6 Requirements file:

Django 2.1.5
python-memcached==1.50
txAMQP==0.8
django-tagging==0.4.6
gunicorn
pytz
pyparsing>=2.3.0
cairocffi
whitenoise==4.1.4
urllib3
six

After manually moving a bunch of files around (its a mess) I finally got past the DB problem but I'm stuck with SQLlite 3.7.3 for some reason. Moving past that, this is the error I'm seeing in /opt/graphite/storage/log/webapp/errors.log:

[Thu Jun 02 22:09:44.846137 2022] [:error] [pid 5659] mod_wsgi (pid=5659): Target WSGI script '/opt/graphite/conf/graphite.wsgi' cannot be loaded as Python module.
[Thu Jun 02 22:09:44.846168 2022] [:error] [pid 5659] mod_wsgi (pid=5659): Exception occurred processing WSGI script '/opt/graphite/conf/graphite.wsgi'.
[Thu Jun 02 22:09:44.846182 2022] [:error] [pid 5659]  Traceback (most recent call last):
[Thu Jun 02 22:09:44.846197 2022] [:error] [pid 5659]   File "/opt/graphite/conf/graphite.wsgi", line 12, in <module>
[Thu Jun 02 22:09:44.846219 2022] [:error] [pid 5659]   from django.conf import settings
[Thu Jun 02 22:09:44.846231 2022] [:error] [pid 5659]  ImportError: No module named django.conf

my wsgi file:

import os
import sys
sys.path.append('/opt/graphite/webapp')

try:
    from importlib import import_module
except ImportError:
    from django.utils.importlib import import_module

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'graphite.settings') # noqa

from django.conf import settings
from django.core.wsgi import get_wsgi_application
from graphite.logger import log

application = get_wsgi_application()

[log.info](("graphite.wsgi - pid %d - reloading search index" % os.getpid())
import graphite.metrics.search # noqa

Finally my vhost file:

# Enable virtualhosts, perhaps by adding this to your server's config somewhere,
# probably the main httpd.conf
# NameVirtualHost *:80

# This line also needs to be in your server's config.
# LoadModule wsgi_module modules/mod_wsgi.so

# You need to manually edit this file to fit your needs.
# This configuration assumes the default installation prefix
# of /opt/graphite/, if you installed graphite somewhere else
# you will need to change all the occurrences of /opt/graphite/
# in this file to your chosen install location.

<IfModule !wsgi_module.c>
    LoadModule wsgi_module modules/mod_wsgi.so
</IfModule>

# XXX You need to set this up!
# Read [http://code.google.com/p/modwsgi/wiki/ConfigurationDirectives#WSGISocketPrefix]
# For example, create a directory /var/run/wsgi and use that.
WSGISocketPrefix run/wsgi

<VirtualHost *:80>
        ServerName graphite1
        DocumentRoot "/opt/graphite/webapp"
        ErrorLog /opt/graphite/storage/log/webapp/error.log
        CustomLog /opt/graphite/storage/log/webapp/access.log common

        # I've found that an equal number of processes & threads tends
        # to show the best performance for Graphite (ymmv).
        WSGIDaemonProcess graphite processes=5 threads=5 display-name='%{GROUP}' inactivity-timeout=120
        WSGIProcessGroup graphite
        WSGIApplicationGroup %{GLOBAL}
        WSGIImportScript /opt/graphite/conf/graphite.wsgi process-group=graphite application-group=%{GLOBAL}

        # XXX You will need to create this file! There is a graphite.wsgi.example
        # file in this directory that you can safely use, just copy it to graphite.wgsi
        WSGIScriptAlias / /opt/graphite/conf/graphite.wsgi

        # XXX To serve static files, either:
        # * Install the whitenoise Python package (pip install whitenoise)
        # * Collect static files in a directory by running:
        #     django-admin.py collectstatic --noinput --settings=graphite.settings
        #   And set an alias to serve static files with Apache:
        Alias /static/ /opt/graphite/static/

        ########################
        # URL-prefixed install #
        ########################
        # If using URL_PREFIX in local_settings for URL-prefixed install (that is not located at "/"))
        # your WSGIScriptAlias line should look like the following (e.g. URL_PREFX="/graphite"

        # WSGIScriptAlias /graphite /srv/graphite-web/conf/graphite.wsgi/graphite
        # Alias /graphite/static /opt/graphite/webapp/content
        #  <Location "/graphite/static/">
        #        SetHandler None
        # </Location>

        # XXX In order for the django admin site media to work you
        # must change @DJANGO_ROOT@ to be the path to your django
        # installation, which is probably something like:
        # /usr/lib/python2.6/site-packages/django
        Alias /media/ "/opt/graphite/lib/python3.6/site-packages/django/contrib/admin/media/"

        # The graphite.wsgi file has to be accessible by apache. It won't
        # be visible to clients because of the DocumentRoot though.
        <Directory /opt/graphite/conf/>
                <IfVersion < 2.4>
                        Order deny,allow
                        Allow from all
                </IfVersion>
                <IfVersion >= 2.4>
                        Require all granted
                </IfVersion>
        </Directory>

</VirtualHost>

Where have I gone wrong?

jguzman-tech commented 2 years ago

Sorry to bump an old issue, maybe you already found a workaround, but generally whenever you see ImportError: No module named X, it means there's a problem with the python module search path.

To debug errors like this on any python application you can print the paths python is looking through:

import sys
print(sys.path)

Your error means that none of these directories contains the django module. To be more specific, it did not find a django/conf directory in any of these paths since you were importing from "django.conf". If you put a venv at /opt/graphite, like the docs recommend for graphite, then django should be in a directory like /opt/graphite/lib/python3.6/site-packages.

It's a hard-coded solution, but I put this at the top of my graphite.wsgi file:

import sys
sys.path = ['', '/usr/lib64/python36.zip', '/usr/lib64/python3.6', '/usr/lib64/python3.6/lib-dynload', '/opt/graphite/lib64/python3.6/site-packages', '/opt/graphite/lib/python3.6/site-packages', '/opt/graphite/webapp']

The unix command find /opt/graphite -name django -type d could help you verify the directory path.

edit: typo

deniszh commented 2 years ago

Thanks, @jguzman-tech, I always struggled with compile small manual how to fix that issue (partially because it's rather quite generic and not graphite-specific).

itinneed2022 commented 2 years ago

The issue in this case was that the django modules at /usr/local/lib/python3.6/site-packages had very restricted permissions. Adding the +x option to them fixed it.

jguzman-tech commented 2 years ago

That makes sense, too bad python's error messages didn't clearly indicate a permissions problem. This issue can probably be closed.

jguzman-tech commented 2 years ago

My first comment here would apply more to a ModuleNotFoundError in python.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.