Почему Rspamd в mailcow помнит только последние письма и как увеличить глубину истории
Клиент присылает жалобу на письмо, отправленное вчера, а в истории Rspamd его уже нет — хотя вы точно ничего не чистили руками. Дело не в поломке: по умолчанию Rspamd в mailcow хранит только 1000 последних событий. Разбираю, где живёт этот параметр, как его увеличить и почему после правки экран журналов mailcow иногда продолжает показывать старую цифру.
Почему письмо исчезает из истории Rspamd раньше, чем ожидаешь
История в Rspamd — это не журнал за период, а кольцевой буфер на фиксированное число записей. По документации mailcow, значение по умолчанию — nrows = 1000, и считается оно не по дням и не по часам, а по количеству обработанных сообщений. На спокойном домене на 15–20 ящиков 1000 писем может хватать на неделю с запасом, а на домене, который принимает рассылки, автоуведомления и почту от внешних клиентов, тысяча событий иногда проходит за сутки — и вчерашнее письмо, на которое жалуется клиент, к моменту разбора уже вытеснено новыми.
Я регулярно вижу эту ошибку интерпретации: администратор открывает корпоративную почту в mailcow, видит в истории Rspamd только последние записи и делает вывод, что письмо вообще не доходило до сервера. На деле оно вполне могло пройти через Rspamd штатно, просто запись об этом уже вытеснена из буфера более свежими событиями. Первое, что я делаю в такой ситуации — смотрю не UI, а сырой лог Postfix и Rspamd напрямую, потому что там глубина ограничена только ротацией логов, а не числом nrows.
Разница между «письма не было» и «запись о письме вытеснена» критична, когда речь идёт о разборе жалобы клиента на пропавшее письмо: в первом случае проблема в доставке или в фильтрации, во втором — вообще нет никакой проблемы, кроме короткой истории. Путать эти два случая дорого: администратор может часами разбирать несуществующий инцидент с доставкой, хотя письмо благополучно ушло получателю ещё вчера, просто запись об этом решении Rspamd уже не помещается в текущий буфер истории.
Где живёт nrows и как его увеличить правильно
Параметр задаётся в файле data/conf/rspamd/local.d/history_redis.conf на хосте с mailcow — это override-файл, который Rspamd подхватывает поверх дефолтных настроек модуля history_redis, не трогая исходные конфиги внутри контейнера. Документация mailcow прямо рекомендует не бросаться сразу на десятки тысяч записей, а сначала попробовать значение в районе 5000 или 10000 и понаблюдать за нагрузкой: история хранится в Redis в сжатом виде, но чем больше записей, тем больше памяти уходит на них и на индексацию при отображении.
После изменения файла конфигурации Rspamd нужно перезапустить контейнер, который его читает:
# правим глубину истории
nano data/conf/rspamd/local.d/history_redis.conf
# содержимое, например:
# nrows = 5000;
# применяем изменение
docker compose restart rspamd-mailcowБез рестарта контейнера изменение в файле никак не подействует — Rspamd читает history_redis.conf при старте воркера, а не при каждом запросе.
Такие override-файлы — общий паттерн донастройки mailcow после базовой установки: когда я веду клиента через пошаговое развёртывание mailcow, сразу показываю, где лежат local.d-каталоги для Postfix, Dovecot и Rspamd, чтобы не редактировать файлы внутри образов напрямую. Важно не путать data/conf/rspamd/local.d/history_redis.conf с override-файлами других модулей Rspamd в том же каталоге local.d — у каждого модуля свой файл, и правка не того файла просто не даст эффекта, а бросающейся в глаза ошибки в интерфейсе вы при этом не увидите. Я всегда проверяю итоговое значение уже после рестарта, а не полагаюсь на то, что файл сохранился правильно.
Почему у Rspamd дефолт nrows 200, а у mailcow 1000
Здесь есть тонкость, которая путает даже опытных администраторов: в самой документации модуля history_redis у проекта Rspamd по умолчанию для nrows указано значение 200, а не 1000. Значение 1000 — это не дефолт апстрима, а override, который команда mailcow специально положила в свою поставку, чтобы из коробки история была заметно глубже, чем у чистого Rspamd. Если вы когда-нибудь сравнивали конфиг mailcow с конфигом Rspamd для другого дистрибутива и видели разные цифры — теперь понятно, откуда расхождение.
Отдельный параметр expire в том же модуле отвечает не за число записей, а за время жизни ключа в Redis: по документации Rspamd у expire нет значения по умолчанию, и если он не задан явно, ключи хранятся бессрочно (цифра 432000 в примере документации — только пример). Если в вашем history_redis.conf expire тоже не задан, предел истории упирается именно в число последних событий, а не в календарную давность. И обратное предупреждение из той же документации: если однажды уменьшить expire, возможна разовая дыра в середине истории — более новые записи удалятся раньше старых.
Формат ключа истории тоже стоит знать, если приходится диагностировать проблему на уровне Redis напрямую: по документации модуля, ключ строится по шаблону rs_history{{HOSTNAME}}{{COMPRESS}}: к префиксу подставляются имя хоста и признак сжатия. То есть в контейнере redis-mailcow командой redis-cli --scan --pattern 'rs_history*' можно найти нужный ключ, а через LLEN посмотреть, сколько записей в нём реально лежит (в свежих версиях mailcow Redis закрыт паролем — возьмите его из mailcow.conf, проверьте в своей версии). Это полезно, когда нужно понять, действительно ли увеличенный nrows начал давать эффект, ещё до того как это стало видно в интерфейсе.
Почему после правки nrows в UI mailcow всё ещё видно 1000 писем
В одном из обсуждений на форуме сообщества mailcow администратор поднял nrows до 5000, перезапустил rspamd-mailcow, но история Rspamd на странице журналов в админке mailcow продолжала обрываться на прежней тысяче записей (речь шла о версии mailcow 2023-10a). Разгадка простая: страница журналов в UI mailcow и родной веб-интерфейс Rspamd по адресу /rspamd — это два разных экрана с разным поведением рендера, и после изменения nrows расширенную историю участники обсуждения находили именно во втором, а не в первом.
У меня в практике то же самое: если клиент говорит «я поднял историю, но в mailcow всё равно старые записи», первым делом прошу открыть отдельный интерфейс Rspamd, а не встроенный список писем в mailcow. Родной UI Rspamd показывает то, что реально лежит в Redis по ключу истории, а у встроенной страницы mailcow свой предел вывода, который с nrows напрямую не связан, — именно так это и проявилось в обсуждении на форуме.
Открывается родной интерфейс Rspamd через тот же веб-сервер mailcow по адресу https://<hostname>/rspamd. Пароль у него свой, не от учётки администратора mailcow: при установке ставится случайный, а задать рабочий нужно в админке mailcow в разделе System → Configuration → Access → Rspamd UI. Так что это не публичная страница, а такой же защищённый инструмент диагностики, как и панель управления. Я советую держать ссылку на этот интерфейс в закладках у всех, кто отвечает за поддержку почты, а не только у главного администратора — это единственное место, где сразу видно, применилось ли изменение nrows на самом деле, без гадания по кэшу основного UI.
Кейс: интернет-магазин «Клик и покупка» терял след писем при разборе жалоб
У клиента — интернет-магазина «Клик и покупка», 18 рабочих мест — служба поддержки получала по 5–10 жалоб в день вида «письмо с трек-номером не дошло», и на каждую пятую-шестую жалобу оператор технической поддержки уже не мог найти запись в истории Rspamd: магазин рассылает подтверждения заказов, трек-номера, уведомления о статусе доставки, и поток легко превышал тысячу писем за смену в пиковые дни распродаж. Разбор каждой такой жалобы превращался в гадание: то ли письмо реально потерялось, то ли просто вытеснилось из буфера прежде, чем оператор успел проверить.
Мы подняли nrows до 8000 — по документации это в пределах рекомендованного диапазона, а для потока клиента этого хватает на трое-четверо суток истории с запасом. Дополнительно я настроил для оператора поддержки отдельную закладку на /rspamd вместо встроенной страницы журналов mailcow, потому что именно там видна полная и актуальная глубина после увеличения nrows. Через месяц эксплуатации доля жалоб «не могу найти письмо в истории» упала почти до нуля — не потому что писем стало меньше теряться, а потому что стало на порядок проще проверить их фактическую судьбу.
Заодно мы навели порядок в самой процедуре разбора: раньше оператор поддержки заводил тикет на почтового администратора при любой жалобе на пропавшее письмо, включая случаи, когда письмо просто уже уехало получателю. После обучения оператора искать в /rspamd самостоятельно число таких тикетов сократилось примерно втрое — большинство вопросов операторы теперь закрывают сами за пару минут, не дожидаясь очереди на администратора.
Сколько истории реально нужно и когда останавливаться
Я подбираю nrows не по формуле, а по объёму почты конкретного клиента: беру среднее число писем в сутки, умножаю на количество дней, за которые обычно приходят жалобы или запросы на разбор (у большинства клиентов — трое-пятеро суток), и добавляю запас на пиковые дни вроде рассылок или распродаж. Для домена на 15–20 ящиков без активных рассылок хватает и дефолтных 1000–2000 записей, для магазина или сервиса с автоматическими уведомлениями разумный диапазон — 5000–15000.
Двигаться сильно выше десятков тысяч я не советую без явной необходимости: документация mailcow отдельно предупреждает не устанавливать непропорционально высокое значение, и хотя история хранится в Redis сжато, чем больше записей, тем ощутимее нагрузка на память и на время отрисовки страницы. Если объём почты такой большой, что штатной истории Rspamd систематически не хватает, я обычно советую параллельно смотреть на агрегированные метрики через эксплуатационный регламент mailcow, а не бесконечно раздувать один буфер истории под задачи, для которых он не предназначен.
Ещё один практический ориентир: если для расследования нужна история старше пары недель или сверка по конкретному отправителю за длительный период, лучше сразу смотреть в сторону выгрузки логов Postfix в отдельное хранилище или систему мониторинга, а не тюнинговать nrows до неадекватных значений. История Rspamd хорошо решает задачу «разобраться с недавним письмом за пару минут», но плохо подходит на роль архива переписки или юридически значимого журнала — для этого в mailcow есть совсем другие механизмы.
Чек-лист: как проверить и изменить глубину истории
Короткая последовательность, которую я прохожу на новом клиентском mailcow, если стоит задача расширить историю или разобраться, куда пропало письмо:
1. Проверить текущее значение: cat data/conf/rspamd/local.d/history_redis.conf на хосте, а применённое — через docker compose exec rspamd-mailcow rspamadm configdump history_redis. 2. Оценить суточный объём писем через лог Postfix, чтобы понять реальную потребность в глубине. 3. Установить nrows в диапазоне 5000–15000 в зависимости от объёма и перезапустить контейнер командой docker compose restart rspamd-mailcow. 4. Проверять результат через родной интерфейс Rspamd по адресу /rspamd, а не только через встроенную страницу журналов mailcow. 5. Раз в квартал сверять, не деградировала ли отрисовка страницы истории при текущем значении nrows на пиковой нагрузке. Заодно в тот же регламент попадает и проверка бэкапов — история Rspamd в архив не входит, а вот резервные копии mailcow стоит проверять отдельной строкой, потому что молчаливо сломанный бэкап обнаруживается обычно тогда, когда он уже нужен. Этот пятиминутный ритуал я включаю в регламент обслуживания каждого клиентского mailcow — он дешевле, чем разбор одной запутанной жалобы на «пропавшее» письмо.
Частые вопросы
Какое значение nrows по умолчанию в mailcow?
1000 записей. Это override, который команда mailcow задаёт поверх дефолта самого Rspamd — у чистого Rspamd nrows по умолчанию равен 200.
Нужно ли перезапускать весь mailcow после изменения nrows?
Нет, достаточно перезапустить один контейнер: docker compose restart rspamd-mailcow. Остальные сервисы эту настройку не используют.
Почему в UI mailcow история короче, чем я задал в nrows?
Встроенная страница журналов mailcow и родной интерфейс Rspamd на /rspamd — разные экраны. Полную актуальную историю после изменения nrows проверяйте именно через /rspamd.
Есть ли у истории Rspamd срок хранения по времени?
У Rspamd у параметра expire нет значения по умолчанию: пока он не задан в history_redis.conf, ключи в Redis хранятся бессрочно, и ограничение работает только по числу записей (nrows). Проверьте, не задан ли expire в вашем файле.
Можно ли выгрузить историю Rspamd за произвольный период для отчёта?
Штатного экспорта по датам нет — это буфер на N последних событий, а не журнал с фильтром по времени. Для долгосрочной аналитики нужно параллельно собирать данные из логов Postfix или внешней системы мониторинга.
Источники
- docs.mailcow.email: Rspamd General Settings — Increase history retention — Проверено: доступ к UI Rspamd по /rspamd с отдельным паролем (System → Configuration → Access → Rspamd UI); nrows по умолчанию 1000, путь data/conf/rspamd/local.d/history_redis.conf, рекомендация пробовать 5000 или 10000, команда docker compose restart rspamd-mailcow. https://docs.mailcow.email/manual-guides/Rspamd/u_e-rspamd-general/#increase-history-retention
- docs.rspamd.com: History Redis module — Проверено: дефолт nrows в самом Rspamd равен 200 (mailcow переопределяет на 1000), параметр expire отвечает за TTL ключа и по умолчанию не задан — ключи хранятся бессрочно, формат ключа rs_history{{HOSTNAME}}{{COMPRESS}}. https://docs.rspamd.com/modules/history_redis/
- community.mailcow.email: Veränderung Länge Log-Historie rspamd wird ignoriert — Проверено как контекст: после увеличения nrows расширенная история отображалась в отдельном интерфейсе /rspamd, а не на встроенной странице журналов mailcow. https://community.mailcow.email/d/2883-veranderung-lange-log-historie-rspamd-wird-ignoriert



