Недавно поймал себя на мысле, что мне в PHP не хватает удобной работы с ошибками, как при разработке, так и в продакшене.
Действительно, держать tail -f /var/log/php_error.log
в консоле можно, но переключаться в нее и назад мне показалось неудобным. К тому же, ошибки в продакшене — каждая из них это потерянный клиент, человек, которого мы не порадовали и с этим нужно бороться.
Ранее, на хабре писали о том, как можно сливать логи централизованно на сервер, заливать их в MySQL базу и обрабатывать их логодробилками. Это все круто, но мне такая тяжелая артиллерия пока не нужна. Мне хочется видеть ошибки как только они появляются, и сразу же их править. Для этого мне надо настроить пересылку их на почту, а далее мой телефон по IMAP сольет и покажет их практически мгновенно.
Что есть под рукой:
- Ubuntu 13.04 server
- Php5-fpm & Nginx
- Настроенный как релей smtp-сервер (в моем случае, exim4)
- Штатный rsyslog из убунты
Настройка PHP
Прежде всего, нужно настроить вывод ошибок в syslog
Для этого, правим файл /etc/php5/fpm/php.ini
и устанавливаем
error_log = syslog
log_errors = On
display_errors = Off
Грабли №1. К сожалению, установить значение для pool'a отдельно с помощью php_value[error_log] = syslog
не получается. Php, видимо, воспринимает это как имя файла, а не специальное значение, не может его открыть и начинает выдавать ошибки в stderr, что можно увидеть в вашем /var/log/nginx/error.log файле
Перезапустим php-fpm: service php5-fpm restart
Далее попробуем запустить скрипт с преднамеренной ошибкой,
<?php
zzz
?>
и если все правильно, увидим ее в файле /var/log/syslog
May 4 23:42:07 ow ool main: PHP Notice: Use of undefined constant zzz - assumed 'zzz' in /var/www/petproject/webroot/makeError.php on line 4
Грабли №2. Как видно в моей версии php, имя берется как pool имя_пула с отсеченной первой буквой. Это не красиво, и хотелось бы поменять эти настройки через
,
syslog.facility = daemon
syslog.ident = php-fpm
но в моей версии эти настройки не заработали. Не проблема, работаем с тем, что есть.
Настройка RSyslogd
В убунте идет штатный Rsyslogd с установленным модулем ommail, и он нам подходит своим умением отправлять почту и фильтровать сообщения.
Предполагаем также, что на localhost установлен smtp-сервер, который корректно релеит почту.
Сделаем файл /etc/rsyslog.d/40-php.conf
со следующим содержанием:
$ModLoad ommail
$ActionMailFrom bot@example.com
$ActionMailTo me@example.com
$template mailSubject,"PHP error %hostname%"
$template mailBody,"RSYSLOG Alertrnmsg='%msg%', program='%programname%'"
$ActionMailSubject mailSubject
if $programname contains 'ool' then :ommail:;mailBody
И перезапустим демона сислог: service rsyslog restart
Вот и все, теперь все ошибки будут валиться на почту. И вам очень захочется, чтобы их никогда больше не было
Что делать, если что то не получилось?
1. Проверьте programname. У меня оно «ool», у вас может быть иным — посмотрите, что пишется в /var/log/syslog
2. У вас точно работает smtp на localhost? Пошлите тестовое письмо, если нужно смените адрес на ваш smtp-сервер через "$ActionMailSMTPServer"
3. И незабудьте подстроить конфиги под себя, указав свои адреса почты
Удачи в борьбе с ошибками!
Автор: mentatxx
это убьет почту
если ошибки посыпались, то письма будут слаться со скоростью 20 в секунду
Как в письмо добавить урл где произошла ошибка?