Flask-socketio: Newrelic

Created on 8 Apr 2017  路  15Comments  路  Source: miguelgrinberg/Flask-SocketIO

I've seen that people are using gunicorn with Newrelic to monitor their flask-socketio. I was wondering if there is a setup for the recommended eventlet deployment. I'm not really sure where to start so I'm asking for help.

I tried the usual newrelic-admin run-program python3 socketio_app.py, but no data is being sent to newrelic. I'm guessing because NewRelic needs to create a wrapper or something into the WSGI app.

question

All 15 comments

Looking at the docs it seems this is the wrapper that they have:
https://docs.newrelic.com/docs/agents/python-agent/installation-configuration/python-agent-integration#wsgi-application

import myapp
application = myapp.WSGIHandler()

application = newrelic.agent.WSGIApplicationWrapper(application)

The question is how I wrap the socketio app.

Doesn't the first example in this page work? That is explicitly documented as being compatible with the eventlet worker of gunicorn.

Just to clarify. I'm not using gunicorn to run flask-socketio, I run it directly using eventlet.
Looking at their agent source code it seems that they do some wrapping specific for gunicorn.

@miguelgrinberg to answer your question the example in their docs does not work for me.

It does not look like they do anything special for gunicorn, they just use their admin script wrapper. I think that should work the same with a bare eventlet server. So something like this (from this page):

NEW_RELIC_CONFIG_FILE=newrelic.ini newrelic-admin run-program python your-eventlet-server.py

I just tried with no results:

from newrelic.agent import WSGIApplicationWrapper
socketio = SocketIO(app)

if __name__ == '__main__':
    socketio.run(WSGIApplicationWrapper(app), host='0.0.0.0', port=7777)

@miguelgrinberg maybe it's something specific to my application. I'm going to try in a simpler project to see if it works.

I just tried with the example app here: https://github.com/miguelgrinberg/Flask-SocketIO/tree/master/example

NEW_RELIC_CONFIG_FILE=newrelic.ini NEW_RELIC_ENVIRONMENT=development-socketio newrelic-admin run-program python app.py

Nothing is logged for that environment even after a few minutes of usage. While this one below logs stuff almost immediately.

NEW_RELIC_CONFIG_FILE=newrelic.ini NEW_RELIC_ENVIRONMENT=development newrelic-admin run-program python my_flask_app.py

Ok, so I got something. When switching to eventlet in the https://github.com/miguelgrinberg/Flask-SocketIO/tree/master/example/app.py

it does send logs to NewRelic, so it seems that's it's something with my app.

馃槥 I just tried with python3.6 in a virtualenv and the same example/app.py does not work anymore.

It worked with python2.7 however.

Here's a more complete example that reproduces this: https://github.com/xarg/flask-socketio-eventlet-example

Not sure how I can help with this. It all points out to an issue in the 3.6 python agent. Have you asked New Relic if they support eventlet on Python 3?

It does look like a NewRelic issue and I did contact them. I just wanted to leave a comment here for posterity just in case someone else encounters this. I'll get back here when I receive a response from them.

@miguelgrinberg: thanks for your support btw! 馃憤

Absolutely. I'm also curious to know what you learn from them.

Got a response from NewRelic support. @hakimy's response below:

Thanks for providing a great test case! This is a very interesting scenario and the problem is related to the monkeypatching of the SSL library.

When using the newrelic-admin script, the Python agent is bootstrapped before any other code is run. During startup, the agent will import a number of libraries, including a vendored version of requests + urllib3 which in turn imports the ssl library.

Later, the eventlet monkeypatching code comes in and patches the ssl library. This leaves the code in an inconsistent state since the Python agent has a reference to the unpatched library but any future code that uses ssl will reference the patched library.

In Python3.6, this inconsistent state causes a change in behavior. In order to keep the state consistent, the following manual integration method is recommended:

#!/usr/bin/env python
import eventlet
eventlet.monkey_patch()

import newrelic.agent
newrelic.agent.initialize('newrelic.ini')

from flask import Flask, render_template
from flask_socketio import SocketIO, emit

with a startup command of

NEW_RELIC_CONFIG_FILE=newrelic.ini NEW_RELIC_ENVIRONMENT=socketio-py3 python app.py

This guarantees that all instances of ssl will be the patched version.

I have tested this and indeed it fixes the issue as expected.
Thanks @hakimu for the excellent support!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lnunno picture lnunno  路  4Comments

EndenDragon picture EndenDragon  路  3Comments

hrmon picture hrmon  路  5Comments

j2logo picture j2logo  路  3Comments

nh916 picture nh916  路  3Comments