- Developer Tools
Troy Topnik, November 15, 2011
Guest post: Graham Dumpleton, author of mod_wsgi for Apache and software developer at New Relic
With the recent official release of the Python agent for New Relic (our application monitoring partner) we're featuring this guest post by Graham Dumpleton. I had the pleasure of working with Graham as we tested the Python agent and the New Relic service with Stackato in recent weeks. --TT
Back in January, I could see that it was going to be an important year for Python web hosting. A number of new Python web hosting services had sprung up promising an easier way of pushing up Python web applications for hosting.
At PyCon US in March I got wind that ActiveState was looking into this area as well. Based on what I was hearing it was clear that they were approaching it in a different way, but I had no real idea what they were up to. I had thought they might just be another option amongst the public PaaS offerings. When they ﬁnally revealed Stackato it was actually a pleasant surprise and not what I had been expecting.
As I looked more closely at Stackato and actually worked out how it differed, the solution grew on me very quickly.
The primary reason Stackato was appealing was that when it comes to web application deployment I like to feel that I am in control of the environment. I am also very wary of shared hosting environments, my work on Apache and mod_wsgi making me appreciate the security issues with that style of hosting.
At the same time I can be quite lazy and don't like doing all the hard work of building a complete system from scratch each time one is required. The idea of a prepackaged private PaaS environment where I could decide where it got deployed was thus very enticing. Especially since I could also deploy it to my local system as well, allowing me to deploy during development to the same environment using the same mechanisms as I would when moving to a production setting.
The concept of a private PaaS also held interest due to my residing in Australia. The problem is that the legal and regulatory regime in Australia is such that if you were doing web application development for government organizations, you would in many cases be prohibited from deploying a web site you had developed for them outside of Australia. This would immediately rule out using any of the main Python web hosting services available as they are located overseas.
Even large private corporations here in Australia can be hesitant about overseas hosting, sometimes for legal and regulatory reasons, but also simply because of the preference for hosting the web site locally, be that internally to the organization or with a local web hosting service. Australia doesn't exactly have the best pipes out to the rest of the Internet and as a result you don't want to be running a high trafﬁc site on the other side of the world for a local market.
As far as ease of deployment, local Python web hosting services still have some way to go though. There are however local companies which offer to host any virtual machine image you want as long as you supply it. Stackato therefore provided the best of both worlds. An easy way of deploying your web applications and an ability to deploy it where you wanted. So Stackato had certainly got my interest personally. I have as a result obviously been keen to try out the New Relic Python agent with Stackato and ensure that it works as seamlessly as possible. The remainder of this post describes doing just that, providing a mini tutorial on how to get started with the New Relic Python agent on Stackato.
Step 1: Getting your application working.
The steps outlined here assume that you are relying on the default WSGI hosting mechanism provided by Stackato. This is using uWSGI as the WSGI hosting container. Further, the speciﬁc examples provided here are based on using the 'django-gtd' sample application provided by ActiveState on github. Where 'gtd' is used as the application name argument to the 'stackato' command, replace this with the name of your application.
Step 2: Installing the New Relic Python agent package.
To install the Python package for the New Relic agent you should add into the 'requirements.txt' ﬁle in the local project directory:
Push up this change by running:
stackato update -n
This will cause the 'newrelic' package to be installed into the Python virtual environment on your Stackato instance.
Note: An alternative way to configure the New Relic Python agent using environment variables in the 'stackato.yml' file is outlined in the Stackato documentation. The procedure below shows off Stackato's 'run' command, which can be useful in some scenarios. There are no Python or New Relic dependencies on the local system - all the config generation is done on the server. --TT
Step 3: Generating the Python agent conﬁguration ﬁle.
Now generate the Python agent conﬁguration ﬁle. We will initially do this on the target Stackato instance rather than into the local project directory by running the command:
stackato run gtd newrelic-admin generate-config KEY newrelic.ini
Replace 'KEY' with the license key for your New Relic account. You can obtain the license key from the 'Support' page when logged into your New Relic account. The license key should be a 40 character alpha numeric string.
The 'newrelic-admin' command is a script which was installed along with the Python agent into the 'bin' directory of the Python virtual environment on your Stackato instance. When the command is run with the 'generate-conﬁg' option it will create the ﬁle 'newrelic.ini' in the 'app' project directory on the Stackato instance.
Step 4: Validate the agent conﬁguration and test the Python agent.
To test that the license key is correct and that an application running on your Stackato instance is able to contact the New Relic servers, run the command:
stackato run gtd newrelic-admin validate-config newrelic.ini newrelic.log
The 'validate-conﬁg' option to 'newrelic-admin' will read the agent conﬁguration ﬁle saved above as 'newrelic.ini' to obtain the license key and other settings. It will then attempt to contact the New Relic servers and will report some test metric data. If this succeeds, after a few minutes you should ﬁnd that the application 'Python Agent Test' now appears in the application list in your New Relic account. This should show the test web transaction.
If no data gets through for the agent test, retrieve the 'newrelic.log' ﬁle created by the test to look for errors using the command:
stackato files gtd app/newrelic.log
Step 5: Retrieve the agent conﬁguration ﬁle and customize it.
The agent conﬁguration ﬁle was initially created on the Stackato instance. You now need to pull back that ﬁle so that you have a persistent copy in your local project directory which will be pushed up with each update. To pull back a copy of the 'newrelic.ini' ﬁle run:
stackato files gtd app/newrelic.ini > newrelic.ini
Now edit the local copy of the 'newrelic.ini' ﬁle.
The ﬁrst change you need to make to the ﬁle is to uncomment and modify the value of the 'log_ﬁle' setting. You should set this to:
log_file = stderr
By setting this to 'stderr', any logging output from the Python agent will be directed to standard error output for the web process and recorded in the web process log ﬁle. You can later retrieve the log ﬁle for the web process using the command:
stackato logs gtd
While editing the agent conﬁguration ﬁle, you can also optionally change the 'app_name' setting to be an alternate name under which the Python agent should report data. By default this name is 'Python Application' and that will be the name used for the application in the New Relic UI.
Step 6: Specifying the location of the agent conﬁguration ﬁle.
When the agent test was run the name of the agent conﬁguration ﬁle was listed explicitly as a command line option. When your web process is run, we instead need to use an environment variable to tell it where it is located. To set additional environment variables for the web process, you need to add them to the 'env' section of your 'stackato.yml' ﬁle.
The name of the environment variable to add is 'NEW_RELIC_CONFIG_FILE'.
env: NEW_RELIC_CONFIG_FILE: newrelic.ini
Step 7: Running the web processes with the Python agent.
So long as you provide a 'wsgi.py' ﬁle containing a WSGI application entry point called 'application', the Stackato instance will automatically pick that up and use it. To perform the actual hosting of your WSGI application it will default to using uWSGI.
To have the resulting web process use the Python agent you will need to add a new 'processes' section to your 'stackato.yml' ﬁle. This section should deﬁne the 'web' command, which is how your web process will be started.
It is when the 'web' command is not provided that uWSGI will be automatically used. We want to override that command in order to wrap it, instead starting it up from the 'newrelic-admin' command with the 'run-program' option.
In overriding the command we don't want to have to replicate the original command that Stackato used by default. So that we don't need to, Stackato keeps a copy of the original command in the 'PROCESSES_WEB' environment variable and we can use that. The overridden 'web' command should therefore read:
processes: web: newrelic-admin run-program $PROCESSES_WEB
We are now ready to push all these changes up to the Stackato instance and try it out. To do that, again run:
stackato update -n
Access your web application and click around in the application for a while. Like with the agent test, the resulting web transactions should start showing up in the New Relic UI after a few minutes. This time the data will show up under whatever application you speciﬁed in the 'app_name' setting in the agent conﬁguration ﬁle.
If you don't see any data after ﬁve minutes, try clicking around in your application some more. The Python agent will only attempt to register with the New Relic servers on the ﬁrst request and depending on the network that may take a moment. It is only once it has been able to successfully register that it will start collecting data.
If you still have issues, then check the web process log output for any errors indicating that there is a problem.
Getting more information.
For further information on the Python agent and how to set it up for different Python WSGI applications, see the New Relic documentation on the Python agent and speciﬁcally that for using the Python agent with Stackato.