Джанго Рэйвен очень медленный

Я регистрирую сообщения в django, используя raven и getentry, но регистрация, похоже, задерживает выполнение кода. Например:

# ...view code
tic = datetime.datetime.now()
logging.warning('foo warning')
toc = datetime.datetime.now()
print "log time %s, %s, %s" % (tic, toc, (toc - tic).total_seconds())
# more view code...

дает вывод:

log time 2013-09-25 12:03:56.541091, 2013-09-25 12:03:57.139420, 0.598329

т.е. в данном случае это задерживает выполнение кода на 600 мс. Этого стоит ожидать? Я бы подумал, что сообщение будет отправлено асинхронно в отдельном потоке, чтобы основной код не задерживался. Кроме того, время моего пинга до app.getsentry.com составляет 125 мс, поэтому 600 мс по-прежнему кажутся странно большими, даже если сообщение отправляется синхронно. Есть ли какой-то конфиг, который я могу изменить, чтобы ускорить работу?

файл настроек:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'handlers': {
        'sentry': {
            'level': 'INFO',
            'class': 'raven.contrib.django.raven_compat.handlers.SentryHandler',
        },
    },
    'loggers': {
        '': {
            'handlers': ['sentry'],
            'level': 'INFO',
            'propagate': True,
        },
    }
}    

=== РЕДАКТИРОВАТЬ ===

Спасибо Филипу Дупановичу за указание на протоколы threading+. К сожалению, у меня они не работали в gunicorn из-за того, что потоки копировались при загрузке рабочих процессов. Я исправил это, добавив хук post_fork в конфигурационный файл gunicorn следующим образом:

import logging
from raven.contrib.django.handlers import SentryHandler
from raven.transport.threaded import ThreadedHTTPTransport


def post_fork(server, worker):
    LOG = logging.getLogger()
    for handler in LOG.handlers:
        if isinstance(handler, SentryHandler):
            for url, transport in handler.client._registry._transports.items():
                if isinstance(transport, ThreadedHTTPTransport):
                    if hasattr(transport, '_worker'):
                        server.log.info("deleting sentry thread worker attribute")
                        delattr(transport, '_worker')
                    else:
                        server.log.info("sentry thread worker not present, nothing to do.")

Очевидно, это хак, и хотя он работает у меня, я понятия не имею, будет ли он работать где-либо еще.


person acrophobia    schedule 25.09.2013    source источник


Ответы (1)


Если вы используете размещенную службу Sentry, вам может быть полезно переключиться на транспорт threaded+http, который Raven полностью поддерживает. Ознакомьтесь с документацией Raven, чтобы узнать, как правильно настроить транспорта в названии службы.

Вы также можете попробовать переключиться на другой специализированный параллельный транспорт или протокол UDP. Хотя вы не можете сравнить задержку ICMP-запроса с TCP, да, дополнительные накладные расходы просто ужасны, и с ними можно обойти, так что не бойтесь!

person Filip Dupanović    schedule 25.09.2013