Как использовать pymongo.monitoring в проекте Flask с mongoengine

#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 с сообщениями мониторинга от этих слушателей…