Вопрос

У меня есть сайт, работающий в Django. Фронтенд - lighttpd и использует fcgi для размещения django.

Я запускаю процессы fcgi следующим образом:

python2.6 /<snip>/manage.py runfcgi maxrequests=10 host=127.0.0.1 port=8000 pidfile=django.pid

Для ведения журнала у меня есть RotatingFileHandler, определенный следующим образом:

file_handler = RotatingFileHandler(filename, maxBytes=10*1024*1024, backupCount=5,encoding='utf-8')

Ведение журнала работает. Тем не менее, похоже, что файлы вращаются, когда они даже не получают до 10 КБ, не говоря уже о 10 МБ. Я предполагаю, что каждый экземпляр fcgi обрабатывает только 10 запросов, а затем вновь порождает их. Каждое возрождение fcgi создает новый файл. Я подтверждаю, что fcgi запускается с новым идентификатором процесса очень часто (трудно сказать точное время, но меньше минуты).

Есть ли способ обойти эту проблему? Мне бы хотелось, чтобы все экземпляры fcgi регистрировались в одном файле, пока он не достигнет предела размера, после чего произойдет ротация файла журнала.

Это было полезно?

Решение

Как сказал Алекс, ведение журнала является поточно-ориентированным, но стандартные обработчики нельзя безопасно использовать для входа из нескольких процессов в один файл.

ConcurrentLogHandler использует блокировку файлов для регистрации в нескольких процессах.

Другие советы

На вашем месте я бы переключился на TimedRotatingFileHandler - - Я удивлен, что основанные на размере дескрипторы вращающихся файлов создают эту проблему (поскольку она не должна учитывать, какие процессы генерируют записи журнала), но временная версия (хотя и не контролируется с помощью именно того параметра, который вы предпочитаете) должна решить Это. Или напишите собственный, более надежный, вращающийся обработчик файлов (вы можете многое почерпнуть из стандартных библиотечных источников), который гарантирует, что различные процессы не являются проблемой (как они никогда не должны быть).

Поскольку вы, по-видимому, используете режим открытия файла по умолчанию для добавления (" a "), а не для записи (" w "), если процесс повторно запускается, он должен добавить к существующему файлу, а затем, когда предел размера достигнут. Поэтому я не уверен, что то, что вы видите, вызвано повторным порождением процессов CGI. (Это, конечно, предполагает, что имя файла остается тем же, когда процесс запускается заново).

Хотя пакет ведения журнала является поточно-ориентированным, он не обрабатывает одновременный доступ к одному и тому же файлу от нескольких процессов - потому что в stdlib нет стандартного способа сделать это. Мой обычный совет - настроить отдельный процесс-демон, который реализует сервер сокетов и регистрирует события, полученные через него, в файл - другие процессы затем просто реализуют SocketHandler для связи с демоном ведения журнала. Тогда все события будут правильно сериализованы на диск. Документация Python содержит рабочий сервер сокетов , который может послужить основой для этой необходимости.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top