Flask support
editFlask support
editGetting Elastic APM set up for your Flask project is easy, and there are various ways you can tweak it to fit to your needs.
Installation
editInstall the Elastic APM agent using pip:
$ pip install elastic-apm[flask]
or add elastic-apm[flask]
to your project’s requirements.txt
file.
For apm-server 6.2+, make sure you use version 2.0 or higher of elastic-apm
.
If you use Flask with uwsgi, make sure to enable threads.
Setup
editTo set up the agent, you need to initialize it with appropriate settings.
The settings are configured either via environment variables, the application’s settings, or as initialization arguments.
You can find a list of all available settings in the Configuration page.
To initialize the agent for your application using environment variables:
from elasticapm.contrib.flask import ElasticAPM app = Flask(__name__) apm = ElasticAPM(app)
To configure the agent using ELASTIC_APM
in your application’s settings:
from elasticapm.contrib.flask import ElasticAPM app.config['ELASTIC_APM'] ={ 'SERVICE_NAME': '<SERVICE-NAME>', 'SECRET_TOKEN': '<SECRET-TOKEN>', } apm = ElasticAPM(app)
The final option is to initialize the agent with the settings as arguments:
from elasticapm.contrib.flask import ElasticAPM apm = ElasticAPM(app, service_name='<APP-ID>', secret_token='<SECRET-TOKEN>')
Debug Mode
editPlease note that errors and transactions will only be sent to the apm server if your app is not in debug mode.
To force the agent to send data while the app is in debug mode,
set the value of DEBUG
in the ELASTIC_APM
dictionary to True
:
app.config['ELASTIC_APM'] = { 'SERVICE_NAME': '<SERVICE-NAME>', 'SECRET_TOKEN': '<SECRET-TOKEN>', 'DEBUG': True }
Building applications on the fly?
editYou can use the agent’s init_app
hook for adding the application on the fly:
from elasticapm.contrib.flask import ElasticAPM apm = ElasticAPM() def create_app(): app = Flask(__name__) apm.init_app(app, service_name='<SERVICE-NAME>', secret_token='<SECRET-TOKEN>') return app
Usage
editOnce you have configured the agent, it will automatically track transactions and capture uncaught exceptions within Flask. If you want to send additional events, a couple of shortcuts are provided on the ElasticAPM Flask middleware object by raising an exception or logging a generic message.
Capture an arbitrary exception by calling capture_exception
:
try: 1 / 0 except ZeroDivisionError: apm.capture_exception()
Log a generic message with capture_message
:
apm.capture_message('hello, world!')
Logging
editPassing logging=True
to the ElasticAPM constructor will make the agent automatically log all log messages from Python’s built-in logging
module.
from elasticapm.contrib.flask import ElasticAPM apm = ElasticAPM(app, logging=True)
For fine-grained control, you can initialize a logging handler and add it, just as you would with any other handler.
from flask import Flask from elasticapm.contrib.flask import ElasticAPM from elasticapm.handlers.logging import LoggingHandler app = Flask(__name__) apm = ElasticAPM(app) if __name__ == '__main__': # Create a logging handler and attach it. handler = LoggingHandler(client=apm.client) handler.setLevel(logging.WARN) app.logger.addHandler(handler)
You can also capture exceptions and send them explictly:
@app.route('/') def bar(): try: 1 / 0 except ZeroDivisionError: app.logger.error( 'I cannot math', exc_info=True)
exc_info=True
adds the exception info to the data that gets sent to the APM server.
Without it, only the message is sent.
Extra data
editIn addition to what the agents log by default, you can send extra information:
@app.route('/') def bar(): try: 1 / 0 except ZeroDivisionError: app.logger.error('Math is hard', exc_info=True, extra={ 'good_at_math': False, } ) )
Celery tasks
editThe Elastic APM agent will automatically send errors and performance data from your Celery tasks to the APM server.
Performance Metrics
editIf you’ve followed the instructions above, the agent has already hooked into the right signals and should be reporting performance metrics.
Ignoring specific routes
editYou can use the TRANSACTIONS_IGNORE_PATTERNS
configuration option to ignore specific routes.
The list given should be a list of regular expressions which are matched against the transaction name:
app.config['ELASTIC_APM'] = { ... 'TRANSACTIONS_IGNORE_PATTERNS': ['^OPTIONS ', '/api/'] ... }
This would ignore any requests using the OPTIONS
method
and any requests containing /api/
.