Комментарии 14
Вообще держать лог открытым – плохая практика. Открыл – дописал строчку – закрыл.
Не соглашусь с вами. Открытие-закрытие - это накладные расходы. Писать мы можем часто - 100 строк в секунду или даже чаще, из разных потоков.
А ещё это может быть не просто текстовый лог, а, например, WAL-файл базы данных, который всё время открыт.
Если вы пишете телеметрию 100 раз в секунду, то для этого лучше воспользоваться каким-нибудь специализированным средством, а не текстовым логом. Текстовый лог такого объёма не имеет практического смысла.
На мой взгляд, текстовый лог осмыслен тогда, когда его можно читать с консоли в реальном времени.
Снова не соглашусь с вами. И nginx тоже не согласится.
По счастью, я далёк от веба, но если вы дисковый кеш будете синхронизировать 100 раз в секунду, то об эффективности вы можете забыть гораздо быстрее, чем при простом переоткрытии файла.
Я возражал, в первую очередь, на ваши замечания о целесообразности таких логов и необходимости постоянно открывать-закрывать.
Синхронизация - да, это отдельная проблема, и это проблема. Надо выбирать - либо скорость, либо консистентность. nginx не очень заботится о том что потеряется пара секунд логов, это проблема админов.
А вот с базой данных все сложнее. Помню как на меня наорал DBA, когда я спросил почему нельзя ставить Oracle на виртуалку хотя бы в тестовых окружениях.
Любая система виртуализации имеет настройки кэширования, и они безопасны. Небезопасные режимы надо включать руками с приседаниями. Сделано специально с учетом среднего уровня специалистов :-)
Про logrotate - проблема описана правильная, но среди решений нет варианта "наорать на администратора и рассказать ему оcopytruncate
", хотя в голосовании видно что автор знает об этом.
Если на сервере включено write caching на уровне диска/SSD, то fsync() может завершиться успешно, а данные — остаться в кэше контроллера и быть утеряны при сбое питания
Неверно. Этот os.fsync() это вызов функции операционной системы, а та при флашинге кэша активно отправляет записи с флагами PRE_FLUSH и FUA (force unit access) который соответственно сбрасывают кэши и пишут мимо кэша. То, что вы написали, бывает только если администратор умышленно стреляет себе в голову.
У нас было примерно два сервиса, один из которых управлял записью по nfs от одной железки, потом нотифицировал второй, который читал заголовок файла и логгировал его в базу. Пока не ввели пуллинг на консистентность заголовка на неск. десятков секунд - постоянно были ошибки валидации. И ничего кроме пуллинга было сделать нельзя
Как отследить это?
Проверяйте
os.stat()
иos.fstat()
— еслиinode
у файла изменился, лог был заменён.Или используйте
watchdog
/inotify
для мониторинга.
Зачем что-то проверять периодически внутри сервиса если есть механизм сигналов. Просто сделайте обработчик сгнала и в нем переоткрывайте логи. Так что если админ в какой-то момент переименует лог-файл то он же и пошлет сигнал на переоткрытие.
а где картинки...
Я предлагаю не просто писать огромные логи с огромной скоростью в текстовые файлы, а еще их распечатывать мелко-мелко и отправлять голубем админу. А потом писать статьи как голуби, иногда, не долетают и что с этим делать.
ЗЫ: непонятно почему нельзя их писать в редис какой-нибудь...
Подводные камни при работе с файлами в Linux с примерами на Python