

How to Add Hosted Monitoring to Flask Web Applications
source link: https://www.fullstackpython.com/blog/hosted-monitoring-flask-web-apps.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
How do you know whether your application is running properly with minimal errors after building and deploying it? The fastest and easiest way to monitor your operational Flask web application is to integrate one of the many available fantastic hosted monitoring tools.
In this post we will quickly add Rollbar monitoring to catch errors and visualize our application is running properly. There are also many other great hosted monitoring tools, which you can check out on the monitoring page.
Our Tools
We can use either Python 2 or 3 to build this tutorial, but Python 3 is strongly recommended for all new applications. I used Python 3.6.2 to execute my code. We will also use the following application dependencies throughout the post:
- Flask web framework, version 0.12.2
- pyrollbar monitoring instrumentation library, version 0.13.12
- blinker for signaling support in Flask applications so pyrollbar can report on all errors
- A free Rollbar account where we will send error data and view it when it is captured
- pip and the virtualenv virtual environment library, which come packaged with Python 3, to install and isolate the Flask and Rollbar libraries from other Python projects you are working on
If you need help getting your development environment configured before running this code, take a look at this guide for setting up Python 3 and Flask on Ubuntu 16.04 LTS.
All code in this blog post is available open source under the MIT license on GitHub under the monitor-flask-apps directory of the blog-code-examples repository. Use and abuse the source code as you desire for your own applications.
Installing Dependencies
Change into the directory where you keep your Python virtualenvs. Create a new virtual environment for this project using the following command.
python3 -m venv monitorflask
Activate the virtualenv.
source monitorflask/bin/activate
The command prompt will change after activating the virtualenv:
Remember that you need to activate the virtualenv in every new terminal window where you want to use the virtualenv to run the project.
Flask, Rollbar and Blinker can now be installed into the now-activated virtualenv.
pip install flask==0.12.2 rollbar==0.13.12 blinker==1.4
Our required dependencies should be installed within our virtualenv after a short installation period. Look for output like the following to confirm everything worked.
Installing collected packages: blinker, itsdangerous, click, MarkupSafe, Jinja2, Werkzeug, Flask, idna, urllib3, chardet, certifi, requests, six, rollbar Running setup.py install for blinker ... done Running setup.py install for itsdangerous ... done Running setup.py install for MarkupSafe ... done Running setup.py install for rollbar ... done Successfully installed Flask-0.12.2 Jinja2-2.9.6 MarkupSafe-1.0 Werkzeug-0.12.2 blinker-1.4 certifi-2017.4.17 chardet-3.0.4 click-6.7 idna-2.5 itsdangerous-0.24 requests-2.18.1 rollbar-0.13.12 six-1.10.0 urllib3-1.21.1
Now that we have our Python dependencies installed into our virtualenv we can create the initial version of our application.
Building Our Flask App
Create a folder for your project named monitor-flask-apps
. Change into
the folder and then create a file named app.py
with the following
code.
import re from flask import Flask, render_template, Response from werkzeug.exceptions import NotFound app = Flask(__name__) MIN_PAGE_NAME_LENGTH = 2 @app.route("/<string:page>/") def show_page(page): try: valid_length = len(page) >= MIN_PAGE_NAME_LENGTH valid_name = re.match('^[a-z]+$', page.lower()) is not None if valid_length and valid_name: return render_template("{}.html".format(page)) else: msg = "Sorry, couldn't find page with name {}".format(page) raise NotFound(msg) except: return Response("404 Not Found") if __name__ == "__main__": app.run(debug=True)
The above application code has some standard Flask imports so we can
create a Flask web app and render template files. We have a single
function named show_page
to serve a single Flask route. show_page
checks if the URL path contains only lowercase alpha characters for a
potential page name. If the page name can be found in the templates
folder then the page is rendered, otherwise an exception is thrown
that the page could not be found. We need to create at least one template
file if our function is ever going to return a non-error reponse.
Save app.py
and make a new subdirectory named templates
under your
project directory. Create a new file named battlegrounds.html
and put
the following Jinja2 template markup into it.
<!DOCTYPE html> <html> <head> <title>You found the Battlegrounds GIF!</title> </head> <body> <h1>PUBG so good.</h1> <img src="https://media.giphy.com/media/3ohzdLMlhId2rJuLUQ/giphy.gif"> </body> </html>
The above Jinja2 template is basic HTML without any embedded template tags. The template creates a very plain page with a header description of "PUBG so good" and a GIF from this excellent computer game.
Time to run and test our code. Change into the base directory of your
project where app.py
file is located. Execute app.py
using the python
command as follows (make sure your virtualenv is still activated in the
terminal where you are running this command):
python app.py
The Flask development server should start up and display a few lines of output.

What happens when we access the application running on localhost port 5000?

HTTP status 404 page not found, which is what we expected because we only defined a single route and it did not live at the base path.
We created a template named battlegrounds.html
that should be accessible
when we go to
localhost:5000/battlegrounds/.

The application successfully found the battlegrounds.html
template but
that is the only one available. What if we try
localhost:5000/fullstackpython/?

HTTP 500 error. That's no good.
The 404 and 500 errors are obvious to us right now because we are testing the application locally. However, what happens when the app is deployed and a user gets the error in their own web browser? They will typically quit out of frustration and you will never know what happened unless you add some error tracking and application monitoring.
We will now modify our code to add Rollbar to catch and report those errors that occur for our users.
Handling Errors
Head to Rollbar's homepage so we can add their hosted monitoring tools to our oft-erroring Flask app.

Click the "Sign Up" button in the upper right-hand corner. Enter your email address, a username and the password you want on the sign up page.

After the sign up page you will see the onboarding flow where you can enter a project name and select a programming language. For project name enter "Battlegrounds" and select that you are monitoring a Python app.

Press the "Continue" button at the bottom to move along. The next screen shows us a few quick instructions to add monitoring to our Flask application.

Let's modify our Flask application to test whether we can properly connect
to Rollbar's service. Change app.py
to include the following highlighted
lines.
import os import re import rollbar from flask import Flask, render_template, Response from werkzeug.exceptions import NotFound app = Flask(__name__) MIN_PAGE_NAME_LENGTH = 2 @app.before_first_request def add_monitoring(): rollbar.init(os.environ.get('ROLLBAR_SECRET')) rollbar.report_message('Rollbar is configured correctly') @app.route("/<string:page>/") def show_page(page): try: valid_length = len(page) >= MIN_PAGE_NAME_LENGTH valid_name = re.match('^[a-z]+$', page.lower()) is not None if valid_length and valid_name: return render_template("{}.html".format(page)) else: msg = "Sorry, couldn't find page with name {}".format(page) raise NotFound(msg) except: return Response("404 Not Found") if __name__ == "__main__": app.run(debug=True)
We added a couple of new imports, os
and rollbar
. os
allows us to
grab environment variable values, such as our Rollbar secret key. rollbar
is the library we installed earlier. The two lines below the Flask app
instantiation are to initialize Rollbar using the Rollbar secret token and
send a message to the service that it started correctly.
The ROLLBAR_SECRET
token needs to be set in an environment variable.
Save an quit the app.py
. Run export ROLLBAR_SECRET='token here'
on the
command line where your virtualenv is activated. This token can be found
on the Rollbar onboarding screen.
I typically store all my environment variables in a file like
template.env and invoke it from the terminal using
the . ./template.env
command. Make sure to avoid committing your secret
tokens to a source control repository, especially if the repository is
public!
After exporting your ROLLBAR_SECRET
key as an environment variable
we can test that Rollbar is working as we run our application. Run it
now using python
:
python app.py
Back in your web browser press the "Done! Go to Dashboard" button. Don't worry about the "Report an Error" section code, we can get back to that in a moment.
If the event hasn't been reported yet we'll see a waiting screen like this one:

Once Flask starts up though, the first event will be populated on the dashboard.

Okay, our first test event has been populated, but we really want to see all the errors from our application, not a test event.
Testing Error Handling
How do we make sure real errors are reported rather than just a simple test event? We just need to add a few more lines of code to our app.
import os import re import rollbar import rollbar.contrib.flask from flask import Flask, render_template, Response from flask import got_request_exception from werkzeug.exceptions import NotFound app = Flask(__name__) MIN_PAGE_NAME_LENGTH = 2 @app.before_first_request def add_monitoring(): rollbar.init(os.environ.get('ROLLBAR_SECRET')) ## delete the next line if you dont want this event anymore rollbar.report_message('Rollbar is configured correctly') got_request_exception.connect(rollbar.contrib.flask.report_exception, app) @app.route("/<string:page>/") def show_page(page): try: valid_length = len(page) >= MIN_PAGE_NAME_LENGTH valid_name = re.match('^[a-z]+$', page.lower()) is not None if valid_length and valid_name: return render_template("{}.html".format(page)) else: msg = "Sorry, couldn't find page with name {}".format(page) raise NotFound(msg) except: rollbar.report_exc_info() return Response("404 Not Found") if __name__ == "__main__": app.run(debug=True)
The above highlighted code modifies the application so it reports all Flask
errors as well as our HTTP 404 not found issues that happen within the
show_page
function.
Make sure your Flask development server is running and try to go to localhost:5000/b/. You will receive an HTTP 404 exception and it will be reported to Rollbar. Next go to localhost:5000/fullstackpython/ and an HTTP 500 error will occur.
You should see an aggregation of errors as you test out these errors:

Woohoo, we finally have our Flask app reporting all errors that occur for any user back to the hosted Rollbar monitoring service!
What's Next?
We just learned how to catch and handle errors with Rollbar as a hosted monitoring platform in a simple Flask application. Next you will want to add monitoring to your more complicated web apps. You can also check out some of Rollbar's more advanced features such as:
There is a lot more to learn about web development and deployments so keep learning by reading up on Flask and other web frameworks such as Django, Pyramid and Sanic. You can also learn more about integrating Rollbar with Python applications via their Python documentation.
Questions? Let me know via a GitHub issue ticket on the Full Stack Python repository, on Twitter @fullstackpython or @mattmakai.
See something wrong in this blog post? Fork this page's source on GitHub and submit a pull request with a fix.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK