Skip to content

Commit

Permalink
Merge pull request #467 from MongoEngine/debug-toolbar
Browse files Browse the repository at this point in the history
Debug toolbar replaced with new version, based on pymongo monitoring
  • Loading branch information
insspb committed Jul 5, 2022
2 parents 44aea8c + db4d925 commit 12f837a
Show file tree
Hide file tree
Showing 14 changed files with 609 additions and 800 deletions.
Binary file added docs/_static/debug_toolbar.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/_static/debugtoolbar.png
Binary file not shown.
27 changes: 1 addition & 26 deletions docs/api/base.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,27 @@ flask_mongoengine.connection module
-----------------------------------

.. automodule:: flask_mongoengine.connection
:members:
:undoc-members:
:show-inheritance:

flask_mongoengine.json module
-----------------------------

.. automodule:: flask_mongoengine.json
:members:
:undoc-members:
:show-inheritance:

flask_mongoengine.operation_tracker module
------------------------------------------

.. automodule:: flask_mongoengine.operation_tracker
:members:
:undoc-members:
:show-inheritance:

flask_mongoengine.pagination module
-----------------------------------

.. automodule:: flask_mongoengine.pagination
:members:
:undoc-members:
:show-inheritance:

flask_mongoengine.panels module
-------------------------------

.. automodule:: flask_mongoengine.panels
:members:
:undoc-members:
:show-inheritance:
:member-order: bysource

flask_mongoengine.sessions module
---------------------------------

.. automodule:: flask_mongoengine.sessions
:members:
:undoc-members:
:show-inheritance:

Module contents
---------------
Expand All @@ -60,7 +38,4 @@ Module contents
provided parent documentation manually.

.. automodule:: flask_mongoengine
:members:
:undoc-members:
:show-inheritance:
:private-members: _abort_404
15 changes: 0 additions & 15 deletions docs/api/wtf.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,23 @@ flask_mongoengine.wtf.db_fields module
--------------------------------------

.. automodule:: flask_mongoengine.wtf.db_fields
:members:
:undoc-members:
:show-inheritance:

flask_mongoengine.wtf.fields module
-----------------------------------

.. automodule:: flask_mongoengine.wtf.fields
:members:
:undoc-members:
:show-inheritance:

flask_mongoengine.wtf.models module
-----------------------------------

.. automodule:: flask_mongoengine.wtf.models
:members:
:undoc-members:
:show-inheritance:

flask_mongoengine.wtf.orm module
--------------------------------

.. automodule:: flask_mongoengine.wtf.orm
:members:
:undoc-members:
:show-inheritance:

Module contents
---------------

.. automodule:: flask_mongoengine.wtf
:members:
:undoc-members:
:show-inheritance:
9 changes: 8 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,4 +252,11 @@
"fieldlist",
]
myst_heading_anchors = 3
suppress_warnings=["autodoc"]
suppress_warnings = ["autodoc"]
autodoc_default_options = {
"members": True,
"undoc-members": True,
"show-inheritance": True,
"ignore-module-all": True,
"private-members": True,
}
110 changes: 99 additions & 11 deletions docs/debug_toolbar.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,108 @@
# Debug Toolbar Panel
# Mongo Debug Toolbar Panel

```{eval-rst}
.. image:: _static/debugtoolbar.png
:target: #debug-toolbar-panel
.. versionchanged:: 2.0.0
```

If you use the Flask-DebugToolbar you can add
`'flask_mongoengine.panels.MongoDebugPanel'` to the `DEBUG_TB_PANELS` config
list and then it will automatically track your queries::
Mongo Debug Toolbar Panel was completely rewritten in version **2.0.0**. Before this
version Mongo Debug Toolbar Panel used patching of main [pymongo] create/update/delete
methods. This was not the best approach, as raised some compatibility issues during
[pymongo] project updates. Since version **2.0.0** we use [pymongo] monitoring functions
to track requests and timings. This approach completely removes patching of external
packages and more compatibility friendly.

New approach require some user side actions to proper panel installation. This is done
to exclude 'silent' registration of event loggers, to prevent performance degradation in
external projects and in projects, that do not require Mongo Debug Toolbar Panel
functional.

Described approach change brings several side effects, that user should be aware of:

1. Now Mongo Debug Toolbar Panel shows real database time, as reported by database
engine. Excluding time required for data delivery from database instance to Flask
instance.
2. Mongo Debug Toolbar Panel do not display and track tracebacks anymore. It only
monitors database requests. Nothing more.
3. Mongo Debug Toolbar Panel do not do anything, if monitoring engine not registered
before Flask application connection setup. Monitoring listener should be
registered before first database connection. This is external requirement.
4. Mongo Debug Toolbar Panel code is now covered by internal tests, raising overall
project code quality.
5. Mongo Debug Toolbar Panel can work without any usage of other
``flask_mongoengine`` functions.
6. Mongo Debug Toolbar Panel do not split requests types anymore, this is because
now it handle any requests, including aggregations, collection creating/deleting
and any other, reported by [pymongo] monitoring. Making splitting of incomming
events will bring high complexity to parsers, as there are a lot of mongoDb
commmands exist.

## Installation

To install and use Mongo Debug Toolbar Panel:

1. Add ``'flask_mongoengine.panels.MongoDebugPanel'`` to ``DEBUG_TB_PANELS`` of
[Flask Debug Toolbar].
2. Import ``mongo_command_logger`` in your Flask application initialization file.
3. Import ``monitoring`` from ``pymongo`` package in your Flask application
initialization file.
4. Register ``mongo_command_logger`` as event listener in ``pymongo``.
5. Init Flask app instance.

Example:

```python
from flask import Flask
import flask
from flask_debugtoolbar import DebugToolbarExtension
from pymongo import monitoring

from flask_mongoengine.panels import mongo_command_logger
from flask_mongoengine import MongoEngine


app = flask.Flask(__name__)
app.config.from_object(__name__)
app.config["MONGODB_SETTINGS"] = {"DB": "testing", "host": "mongo"}
app.config["TESTING"] = True
app.config["SECRET_KEY"] = "some_key"
app.debug = True
app.config["DEBUG_TB_PANELS"] = ("flask_mongoengine.panels.MongoDebugPanel",)
DebugToolbarExtension(app)
monitoring.register(mongo_command_logger)
db = MongoEngine()
db.init_app(app)
```

app = Flask(__name__)
app.config['DEBUG_TB_PANELS'] = ['flask_mongoengine.panels.MongoDebugPanel']
db = MongoEngine(app)
toolbar = DebugToolbarExtension(app)
```{note}
Working toolbar installation code can be found and tested in example_app, shipped with
project codebase.
```

## Configuration

You can add ``MONGO_DEBUG_PANEL_SLOW_QUERY_LIMIT`` variable to flask application
config, to set a limit for queries highlight in web interface. By default, 100 ms.

## Usage

```{eval-rst}
.. image:: _static/debug_toolbar.png
:target: _static/debug_toolbar.png
```

- Mongo Debug Toolbar Panel logs every mongoDb query, in executed order.
- You can expand ``Server command`` to check what command was send to server.
- You can expand ``Response data`` to check raw response from server side.

## Known issues

There is some HTML rendering related issues, that I cannot fix, as do not work with
front end at all. If you have a little HTML/CSS knowledge, please help.

- [#469] Mongo Debug Toolbar Panel: Update HTML view to use wide screens
- Objects sizes may be incorrect, as calculated in python. This part is copied from
previous version, and may be removed in the future, if there will be confirmation,
that this size data completely incorrect.

[Flask Debug Toolbar]: https://github.com/flask-debugtoolbar/flask-debugtoolbar
[#469]: https://github.com/MongoEngine/flask-mongoengine/issues/469
[pymongo]: https://pymongo.readthedocs.io/en/stable/
18 changes: 12 additions & 6 deletions example_app/app.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
import flask
from flask_debugtoolbar import DebugToolbarExtension
from models import db
from pymongo import monitoring
from views import index, pagination

from flask_mongoengine.panels import mongo_command_logger

app = flask.Flask(__name__)
app.config.from_object(__name__)
app.config["MONGODB_SETTINGS"] = {"DB": "testing", "host": "mongo"}
app.config["TESTING"] = True
app.config["SECRET_KEY"] = "flask+mongoengine=<3"
app.debug = True
app.config["DEBUG_TB_PANELS"] = (
"flask_debugtoolbar.panels.versions.VersionDebugPanel",
"flask_debugtoolbar.panels.timer.TimerDebugPanel",
"flask_debugtoolbar.panels.config_vars.ConfigVarsDebugPanel",
"flask_debugtoolbar.panels.g.GDebugPanel",
"flask_debugtoolbar.panels.headers.HeaderDebugPanel",
"flask_debugtoolbar.panels.logger.LoggingPanel",
"flask_debugtoolbar.panels.profiler.ProfilerDebugPanel",
"flask_debugtoolbar.panels.request_vars.RequestVarsDebugPanel",
"flask_debugtoolbar.panels.route_list.RouteListDebugPanel",
"flask_debugtoolbar.panels.template.TemplateDebugPanel",
"flask_debugtoolbar.panels.logger.LoggingPanel",
"flask_debugtoolbar.panels.timer.TimerDebugPanel",
"flask_debugtoolbar.panels.versions.VersionDebugPanel",
"flask_mongoengine.panels.MongoDebugPanel",
)
app.config["DEBUG_TB_INTERCEPT_REDIRECTS"] = False

db.init_app(app)

DebugToolbarExtension(app)
monitoring.register(mongo_command_logger)
db.init_app(app)


app.add_url_rule("/", view_func=index)
Expand Down
10 changes: 7 additions & 3 deletions example_app/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ def index():
Todo.objects().delete() # Removes
Todo(title="Simple todo A", text="12345678910").save() # Insert
Todo(title="Simple todo B", text="12345678910").save() # Insert
Todo(title="Simple todo C", text="12345678910").save() # Insert
# Bulk insert
bulk = (Todo(title="Bulk 1"), Todo(title="Bulk 2"))
Todo.objects().insert(bulk)
Todo.objects(title__contains="B").update(set__text="Hello world") # Update
todos = list(Todo.objects[:10])
todos = Todo.objects.all()
Todo.objects(title__contains="B").order_by("-title").update(
set__text="Hello world"
) # Update
Todo.objects(title__contains="C").order_by("-title").delete() # Removes
todos = list(Todo.objects.order_by("-title", "done")[2:10])
todos = Todo.objects.all().order_by("-title")
return flask.render_template("index.html", todos=todos)


Expand Down

0 comments on commit 12f837a

Please sign in to comment.