Setting Up New Relic on Django, Apache HTTPD, and mod_wsgi
Using New Relic's Python agent on a Django application deployed with Apache HTTPD and mod_wsgi makes it a little harder to integrate.
Join the DZone community and get the full member experience.Join For Free
If you've used New Relic before, then you know that it's normally pretty easy to integrate and doesn't require any code modifications — at least, it didn't when I was using their Java agent.
Using their Python agent on my Django application deployed with
Apache HTTPD and
mod_wsgi didn’t turn out to be so straightforward.
You can’t use their simple install process on the
Apache HTTPD and
mod_wsgi combination. You need to import and initialize the agent in your code manually.
Let’s see how that’s going to work.
Installing the Library
Installation is pretty straight forward if you have
pip install newrelic
sudo pip install newrelic
...depending on your setup.
Creating the Configuration File
Once New Relic is installed through
pip , you can create the default configuration file with:
newrelic-admin generate-config <new relic license key> newrelic.ini
This generates a basic
.ini file with a bunch of properties that can be used to configure the details of New Relic. You should have a look at the offered options in due time; however, the one setting worth noting is the
app_name = <Your application name>
This is the name that will be displayed in the New Relic dashboard, so change it to something that will help you identify it quickly.
Initializing the Agent
To manually initialize the New Relic agent, you need to import it in your code and then initialize it by providing the path to the configuration file.
While New Relic stresses that this snippet must be placed before your other imports, it didn’t matter if we load it a few lines down the file. For Django, the place to do this is in the
import newrelic.agent newrelic.agent.initialize('/path/to/newrelic.ini')
After initialization of the agent, we need to wrap our WSGI application object in New Relic’s
WSGIApplicationWrapper. This will allow New Relic to provide us with additional instrumentation designed specifically for various frameworks (in our case, Django).
While New Relic automatically wraps some WSGI servers, that is not the case for the
Apache HTTPD and
mod_wsgi combo. A direct quote from their documentation:
Note: A WSGI application only generally needs to be wrapped where no framework specific instrumentation is provided for the web framework being used, and the WSGI server being used also isn’t being instrumented such that any WSGI application is automatically wrapped. The main WSGI server where the WSGI application is not automatically wrapped is Apache/mod_wsgi.
Here is how you wrap the WSGI application object.
application = get_wsgi_application() application = newrelic.agent.WSGIApplicationWrapper(application)
And viola! You are done. Exercise your application a bit and you should see data metrics coming into the New Relic dashboard.
Now that everything is running, it’s time to do a few improvements to the code. In a real life application we will need New Relic to be configurable, an option to enable disable it and an externally configurable configuration file path.
Let’s see what that will look like in Django.
We will add two configurations to the
# New Relic settings ENABLE_NEW_RELIC = os.environ['ENABLE_NEW_RELIC'] in ['True','true'] NEW_RELIC_CONFIG_FILE = os.environ['NEW_RELIC_CONFIG_FILE'] #End of New Relic settings
As you can see, we are retrieving two environment parameters:
ENABLE_NEW_RELIC: A boolean value to enable or disable New Relic initialization
NEW_RELIC_CONFIG_FILE: The path to the
Let’s see how we can use these configurations in the
import os from django.conf import settings from django.core.wsgi import get_wsgi_application os.environ.setdefault("DJANGO_SETTINGS_MODULE", "one_face_in.settings") application = get_wsgi_application() if settings.ENABLE_NEW_RELIC: import newrelic.agent newrelic.agent.initialize(settings.NEW_RELIC_CONFIG_FILE) application = newrelic.agent.WSGIApplicationWrapper(application)
We have moved all the New Relic initialization code to the bottom of the file. The agent will only be initialized if the settings have been set to do so, and the config file path is also loaded from the settings.
Opinions expressed by DZone contributors are their own.