#python #flask #pymongo #mongoengine
#python #flask #pymongo #mongoengine
Вопрос:
Я пытаюсь добавить некоторый мониторинг к простому веб-сервису REST с помощью flask и mongoengine и столкнулся с тем, что, по моему мнению, является непониманием с моей стороны того, как imports и mongoengine работают в приложениях flask. Я следую документации pymongo по мониторингу: https://pymongo.readthedocs.io/en/3.7.2/api/pymongo/monitoring.html
Я определил следующий список команд в отдельном файле:
import logging
from pymongo import monitoring
log = logging.getLogger('my_logger')
class CommandLogger(monitoring.CommandListener):
def started(self, event):
log.debug("Command {0.command_name} with request id "
"{0.request_id} started on server "
"{0.connection_id}".format(event))
monitoring.register(CommandLogger())
Я сделал application_builder.py файл для создания моего приложения flask, код выглядит примерно так:
from flask_restful import Api
from flask import Flask
from command_logger import CommandLogger # <----
from db import initialize_db
from routes import initialize_routes
def create_app():
app = Flask(__name__)
api = Api(app)
initialize_db(app)
initialize_routes(api)
return app
Мониторинг, похоже, работает, только если я импортирую: CommandLogger
в application_builder.py . Я хотел бы понять, что здесь происходит, как импорт влияет на регистрацию мониторинга?
Также я хотел бы извлечь monitoring.register(CommandLogger())
как функцию и вызвать ее на последнем этапе в моем коде что-то вроде def register(): monitoring.register(CommandLogger())
, но это, похоже, не работает, «регистрация» работает только тогда, когда она находится в том же файле, CommandLogger
что и класс…
Комментарии:
1. Пожалуйста, обратитесь к соответствующей документации драйвера из вопроса.
2. @D. SM спасибо за ваш комментарий, я работаю на основе этой ссылки на документацию
3. Итак, вы спрашиваете, почему ваш код запускается только при его импорте? Потому что python выполняет код только в импортированных модулях.
4. Для вашего второго вопроса добавьте к вопросу фактический результат и ожидаемый результат.
5. Ваши комментарии только что напомнили мне, что вам нужно `if name == » main «:`, чтобы предотвратить выполнение фрагментов кода во время импорта. Еще не совсем привык к этому. И это в основном отвечает на половину моей проблемы, которая на самом деле была действительно тривиальной… Спасибо
Ответ №1:
Из документа MongoEngine кажется важным, чтобы слушатель был зарегистрирован перед подключением mongoengine
Чтобы использовать pymongo.monitoring с MongoEngine, вам необходимо убедиться, что вы регистрируете слушателей, прежде чем устанавливать соединение с базой данных (т.е. Вызывать connect)
Ответ №2:
Это сработало для меня. Я просто инициализирую / регистрирую его так же, как и другие модули, чтобы избежать циклического импорта.
# admin/logger.py
import logging
from pymongo import monitoring
log = logging.getLogger()
log.setLevel(logging.DEBUG)
logging.basicConfig(level=logging.DEBUG)
class CommandLogger(monitoring.CommandListener):
# def methods...
class ServerLogger(monitoring.ServerListener):
# def methods
class HeartbeatLogger(monitoring.ServerHeartbeatListener):
# def methods
def initialize_logger():
monitoring.register(CommandLogger())
monitoring.register(ServerLogger())
monitoring.register(HeartbeatLogger())
monitoring.register(TopologyLogger())
# /app.py
from flask import Flask
from admin.toolbar import initialize_debugtoolbar
from admin.admin import initialize_admin
from admin.views import initialize_views
from admin.logger import initialize_logger
from database.db import initialize_db
from flask_restful import Api
from resources.errors import errors
app = Flask(__name__)
# imports requiring app
from resources.routes import initialize_routes
api = Api(app, errors=errors)
# Logger before db
initialize_logger()
# Database and Routes
initialize_db(app)
initialize_routes(api)
# Admin and Development
initialize_admin(app)
initialize_views()
initialize_debugtoolbar(app)
# /run.py
from app import app
app.run(debug=True)
затем в любом модуле…
from admin.logger import log
from db.models import User
# inside some class/view/queryset or however your objects are written...
log.info('Saving an item through MongoEngine...')
User(name='Foo').save()
Сейчас я пытаюсь понять, как интегрировать панель ведения журнала Flask DebuggerToolbar с сообщениями мониторинга от этих слушателей…