Ведение журнала Flask Запросы отдельно: как удалить Python Обработчик ведения журнала по идентификатору - PullRequest
0 голосов
/ 08 апреля 2020

Итак, у меня следующая проблема:

Я использую Flask и хочу создать два разных типа файлов журнала: один общий файл журнала, в котором все записывается в один файл, и один Logger / Handler , который регистрирует только входящий запрос и соответствующий исходящий ответ, с отдельным файлом для каждого запроса. На практике я использую собственный класс журнала с пользовательскими уровнями и легко вызываемыми функциями. Но я попытался разобрать его до его основ:

app = Flask(__name__)
general_logger = logging.getLogger(__name__)
# add_handlers_to_general_logger()

@app.before_request
def log_incoming_request():
    request_id = get_current_request_id()
    unique_logger = logging.getLogger("{0}.{1}".format(__name__, request_id))
    # add_handler_to_unique_logger()
    unique_logger.info("INCOMING REQUEST")


@app.route('/')
def index():
    general_logger.info("Index called!")
    file_A.do_something_A()  # this function takes X seconds to process, general_logger is also used in there
    return "Hello World"


@app.after_request
def log_outgoing_response(response):
    request_id = get_current_request_id()  # same id as in before_request
    unique_logger = logging.getLogger("{0}.{1}".format(__name__, request_id))
    unique_logger.info("OUTGOING RESPONSE")
    return response

Теперь проблема в том, что, хотя это работает, я думаю, что это не очень хорошая идея - создавать столько разных регистраторов. Функция, вызываемая в index (), обрабатывает неизвестное количество секунд, в зависимости от данных отправленного запроса, и несколько запросов должны обрабатываться одновременно. Моя идея заключается в том, чтобы просто удалить соответствующий обработчик в @ app.after_request.

Итак, вопрос в том, как я могу, после добавления указанного обработчика c в @ app.before_request, правильно удалить правую обработчик по имени в @ app.after_request, например:

@app.before_request
def log_incoming_request():
    request_id = get_current_request_id()
    unique_logger = logging.getLogger("unique")

    add_handler_to_unique_logger(request_id)

    unique_logger.info("INCOMING REQUEST")

@app.after_request
def log_outgoing_response(response):
    request_id = get_current_request_id()  # same id as in before_request
    unique_logger = logging.getLogger("{0}.{1}".format(__name__, request_id))
    unique_logger.info("OUTGOING RESPONSE")

    unique_logger.removeHandler(request_id)

    return response

Или есть ли другой способ правильно зарегистрировать отдельные файлы журнала запросов (с request_id в их имени файла)?

Спасибо!

1 Ответ

0 голосов
/ 08 апреля 2020

Я бы не стал беспокоиться об управлении памятью, пока это не станет проблемой. В любом случае вы можете удалить ссылку, которую содержит модуль журналирования:

del logging.root.manager.loggerDict[unique_logger_id]

Сам объект логгера, конечно, только перестанет существовать, если все другие ссылки на него, которые у вас есть в вашем коде, также будут удалены. Если вы также используете уникальные обработчики, я также рекомендую вызывать close() для них, чтобы очистить использованные файловые ресурсы.

...