Open-source project
flask-dashboard/Flask-MonitoringDashboard avatar
flask-dashboard/Flask-MonitoringDashboard

Flask-MonitoringDashboard: request profiling that lives inside your Flask app

Automatically monitor the evolving performance of Flask/Python web services.

828 stars167 forksPythonMIT

At a glance

What is it?
Flask-MonitoringDashboard is an MIT licensed Flask extension that records the execution path of every request into a database, detects slow outliers with their stack traces, captures unhandled exceptions and adds a dashboard route to your own application. It suits a developer who wants to see which endpoint and which function is slow, and it is a poor fit if your app is short lived, serverless, or cannot spare the database writes.
Who is it for?
Flask-MonitoringDashboard suits a team with a long lived Flask service that has a performance question it cannot answer from access logs alone, because the extension records which functions ran on which endpoint, not just how long the request took, and it ships a micro build that collects the same data without the dashboard.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 28 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

An extension that lives inside the application it watches

The Flask Monitoring Dashboard is described as a dashboard for automatic monitoring of Flask web services, and its stated purpose is to automatically monitor the evolving performance of Flask and Python web services.

The architecture decision is the interesting one. There is no agent, no sidecar and no proxy in front of the application. The extension is bound to your Flask app, which means it runs inside the same process, sees the same request objects, and can attribute time to individual functions in your own code rather than only to whole endpoints.

That is why the feature list is what it is. The dashboard shows which endpoints process a lot of requests and how fast, and, the README says, it provides information about the evolving performance of an endpoint throughout different versions if you are using git. So the second dimension is not just time, it is time across deployments, which is the question a developer actually asks when a release got slower.

The other half of the design is that the data goes into a database. The execution path of every request is tracked and stored into the database, which lets the dashboard show which functions in your code take the most time, and, because all requests for an endpoint are merged together, it shows an overview of which functions are used in which endpoint.

The project is MIT licensed, the primary language is Python, the documentation is at flask-monitoringdashboard.readthedocs.io, and the last push to the repository was on 2026-09-28.

bind(app) has to come after your routes

The setup is four lines of code, and one of them has an ordering requirement that the README states explicitly.

python
from flask import Flask
import flask_monitoringdashboard as dashboard

app = Flask(__name__)

@app.route("/test")
def test():
    return 'ok'

dashboard.bind(app) # Should be added after all endpoints have been defined
app.run()

The comment on the bind call is not decoration. The extension attaches to the application and needs to know which routes exist, so binding before the routes are defined gives you a dashboard that does not know about them, and the natural way to write a Flask app, defining routes as you go, puts the bind at the bottom. A developer who binds at the top of the module will spend an afternoon wondering why the endpoint list is short.

Installation is either from source or from PyPI.

python
python setup.py install
python
pip install flask_monitoringdashboard

The PyPI name is flask_monitoringdashboard with a different separator, and the project name in the setup metadata is Flask-MonitoringDashboard with hyphens, which is one of those small mismatches that costs ten minutes the first time it happens.

Once bound, the dashboard is reachable at the /dashboard route by default, and the README notes that this can be configured to another route. The documentation site has a separate functionality page for the advanced options, which is where the monitoring level, the database configuration and the alert channels are described.

Micro mode is the same code without the dashboard

The setup.py file contains a detail that is easy to miss and that determines whether this package is right for you.

There is a --micro flag. When it is passed, the package name becomes Flask-MonitoringDashboard-Micro, the requirements are read from requirements-micro.txt instead of the full requirements.txt, and the package list is restricted to a specific set of subpackages.

python
micro = False
if '--micro' in sys.argv:
    micro = True
    sys.argv.remove('--micro')
    print('In micro mode')

The included packages in micro mode are the library, the database, the core, the core config, the custom graph and the profiler. The excluded ones are the controllers, the frontend, the views and the static files.

Read that list and the design intent becomes clear. The dashboard itself, which is the controllers and the views and the frontend and the static assets, is what gets dropped. The collection machinery is what stays.

So micro mode is a metrics and profiling agent that runs inside your Flask app and writes to a database, with no user interface of its own. You point an existing dashboard, a BI tool or a notebook at the database and read the results there.

That is a meaningfully different use case from the full package, and it is the one that scales to a fleet of services. The full package gives one developer a UI for one application. The micro package lets a hundred applications feed one store, which is how profiling is normally done in a larger environment.

The requirements files match the split. The full requirements.txt includes requirements-micro.txt and adds scipy, with the comment that it is for statistical analysis of latency measurements. So the statistical work is part of the extra weight the full build carries.

Profiling stores the execution path of every request

Most request logs tell you that an endpoint took four hundred milliseconds. That is rarely enough to act on.

The dashboard stores the execution path of every request, which is a much more expensive thing to do and much more useful. Because it records which functions ran, the dashboard can tell you that the slow part of a request was a particular function, and because all requests for an endpoint are merged together, it can tell you which functions are used by that endpoint at all.

That last point is the one that catches people out. A function that is called from three places has a cost in all three, and a function that is dead code in one path and hot in another will look hot on a flat profile. The endpoint-oriented view in the dashboard answers the question a flat profile cannot, which is where does this endpoint actually spend its time.

The outlier feature follows from storing the path rather than just the duration. Outliers are requests that take much longer to process than regular requests, and the dashboard detects them automatically and stores extra information: the stack trace, the request values, the request headers and the request environment.

That is a security consideration as well as a debugging one. A request environment and a full set of headers can contain session cookies, authorisation tokens and form fields with personal data, and the dashboard stores them on disk for the outliers. Before you turn this on against a real application, decide where that database lives and who can read it.

The third feature is the one that sounds the least like a monitoring tool and is arguably the most useful. You can configure a query of your own, for example a count of the users table, and the dashboard will provide that information per day or other time interval. The README's framing is that running the query manually is annoying to do regularly, which is accurate.

Exceptions are captured automatically, or by hand

Exception monitoring is a separate feature, and the README is specific about when it applies.

Flask-MonitoringDashboard automatically logs unhandled exceptions with full stack traces, showing where and why errors occur, if you have monitoring level 1 or above. The monitoring level matters, and the phrase if you have monitoring level 1 or above tells you that there is a configuration value controlling how much is collected.

Handled exceptions are not captured by default, and the README gives the two line pattern for doing it yourself.

python
try:
    # Your code
except Exception as e:
    dashboard.capture(e)  # Logs exception with stack trace for debugging

That is a small API, and it is the right shape, because most exceptions in a Flask application are handled somewhere, usually by a generic handler that turns them into a 500, and a stack trace that only exists for the unhandled ones loses the majority of what you want to see.

Alerting can also be configured optionally, to notify you when unhandled or manually captured exceptions occur during runtime. When alerting is enabled, FMD collects information about the exception and sends it to one or more configured alerting channels.

The word optionally matters here, because the exception data is the most sensitive thing the extension collects. A stack trace with local variable names, a request body and a set of headers ends up in the database and possibly in a notification channel. That is a reasonable trade for a team that needs the error detail, and an unreasonable one for a team that has never thought about it.

The live demo logs in with admin and admin

There is a live deployment linked from the README, hosted on Heroku, and the credentials are printed in the text.

Use the credentials u:`admin`, p:`admin` to log in.

This is worth commenting on rather than just using. The demo exists so that you can see the interface before installing anything, which is genuinely useful, and the fact that the dashboard is a Flask app with its own login page means there is an authentication story.

The same logic applies to your own deployment. The extension adds a route to your application, and that route shows request data, stack traces, headers and possibly captured exceptions. Whether it is protected by the dashboard's own login, by a reverse proxy, or by nothing at all is a decision you have to make, and the README does not describe the authentication options in detail, so the documentation site is where to look.

The other thing the demo makes clear is the shape of the interface. The README shows five screenshots, and the visualisation of an endpoint's functions over time is the part that makes the per-request path storage worth the cost, because the value is in seeing a change between two versions, not in seeing one slow request.

One more detail from the README worth knowing: there is a section on migrating from version 1.X.X to version 2.0.0 in the documentation, which tells you the project went through a large structural change at the 2.0 boundary. If you are evaluating this against an older copy of a blog post or a tutorial, that migration note is the version of the truth.

Released in 2020, pushed in 2026

The release history and the commit history tell different stories, and the difference is large.

The listed releases are v3.0.7 from 2020-02-28, v2.1.0 from 2019-02-25 and v2.0.0 from 2018-06-11. Meanwhile the last push to the repository was on 2026-09-28, and the repository carries a continuous integration workflow for Python tests, a read the docs configuration, a codecov configuration and a .readthedocs.yaml.

So the code is being worked on, the docs are being built, and the coverage is being measured, but there has been no published release since February 2020. If you install from PyPI you get the 3.0.7 code, and the current tree is something else.

That is not automatically a problem. A monitoring extension does not need a new release for every commit, and pinning to a known version is often the right thing to do for a component that sits inside a production application. But it does mean that the README and the documentation site may describe a version you do not have, and that the pinned dependency set in requirements.txt reflects a 2020 view of Flask, and of its own dependencies.

The repository layout gives a sense of the scope. The flask_monitoringdashboard package holds the library, with subdirectories for the database, the core, the controllers, the views, the frontend and the static files, and the core itself contains the config, the custom graph and the profiler. There is a migration directory for database schema changes, a config directory with an install script used in development, a docs directory, a tests directory, a Procfile for Heroku, and separate requirements files for the full build, the micro build and development.

The practical advice is short. If you adopt this, pin the version, read the documentation for that version, and check that the extension's database writes are compatible with the load your application actually takes.

Editorial conclusion

Flask-MonitoringDashboard suits a team with a long lived Flask service that has a performance question it cannot answer from access logs alone, because the extension records which functions ran on which endpoint, not just how long the request took, and it ships a micro build that collects the same data without the dashboard. It does not suit a serverless deployment, a request volume you cannot afford to write to a database for, or a team that expects a hosted replacement for its APM stack. Before you adopt it, check the install path you want, since pip install flask_monitoringdashboard pulls the full package with its UI while the micro variant is a separate distribution, and note the maintenance signal: the last push to the repository was on 2026-09-28 but the newest release tag is v3.0.7 from 2020-02-28, so you would be installing a published package that predates the current tree.

Frequently asked questions

What does Flask-MonitoringDashboard do?

It is a Flask extension that records the execution path of every request into a database, detects slow outliers and stores their stack traces, request values, headers and environment, captures unhandled exceptions, can run a custom query on a schedule, and adds a dashboard route to your application.

How do I install and set up Flask-MonitoringDashboard?

Install it with pip install flask_monitoringdashboard or from source with python setup.py install, then import flask_monitoringdashboard as dashboard and call dashboard.bind(app) after all endpoints have been defined, as the README notes. The dashboard is then available at the /dashboard route by default.

What is the difference between the full package and the micro package?

Building with the --micro flag produces a package named Flask-MonitoringDashboard-Micro that includes the library, database, core, config, custom graph and profiler packages but excludes the controllers, frontend, views and static files, so it collects the same data without shipping the dashboard interface.

How do I capture handled exceptions?

Call dashboard.capture(e) in the except block, as the README shows. Unhandled exceptions are logged automatically with full stack traces when you have monitoring level 1 or above, and alerting to configured channels is optional.

Is Flask-MonitoringDashboard still released?

The listed releases end with v3.0.7 from 2020-02-28, while the last push to the repository was on 2026-09-28. Installing from PyPI therefore gives you the 2020 release rather than the current tree.

Official sources

  1. flask-dashboard/Flask-MonitoringDashboard on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/flask-dashboard-flask-monitoringdashboard.svg)](https://hysenlabs.com/projects/flask-dashboard-flask-monitoringdashboard)

Was this useful?