php log php errors
error_log
(PHP 4, PHP 5, PHP 7, PHP 8)
error_log — Отправляет сообщение об ошибке заданному обработчику ошибок
Описание
Отправляет сообщение об ошибке в лог веб-сервера или в пользовательский файл.
Список параметров
Сообщение об ошибке, которое должно быть логировано.
Определяет куда отправлять ошибку. Возможны следующие значения:
Возвращаемые значения
Примеры
Пример #1 Примеры использования error_log()
Примечания
error_log() не является бинарно-безопасной функцией. message обрезается по null-символу.
User Contributed Notes 20 notes
Advice to novices: This function works great along with «tail» which is a unix command to watch a log file live. There are versions of Tail for Windows too, like Tail for Win32 or Kiwi Log Viewer.
Using both error_log() and tail to view the php_error.log you can debug code without having to worry so much about printing debug messages to the screen and who they might be seen by.
Further Note: This works even better when you have two monitors setup. One for your browser and IDE and the other for viewing the log files update live as you go.
DO NOT try to output TOO LARGE texts in the error_log();
if you try to output massive amounts of texts it will either cut of the text at about 8ooo characters (for reasonable massive strings,
The default seem to be 1024 but can be changed by adjusting the value of the runtime configuration value of ‘log_errors_max_len’.
Beware! If multiple scripts share the same log file, but run as different users, whichever script logs an error first owns the file, and calls to error_log() run as a different user will fail *silently*!
Nothing more frustrating than trying to figure out why all your error_log calls aren’t actually writing, than to find it was due to a *silent* permission denied error!
You can easily filter messages sent to error_log() using «tail» and «grep» on *nix systems. This makes monitoring debug messages easy to see during development.
Be sure to «tag» your error message with a unique string so you can filter it using «grep»:
On your command line:
In this example, we pipe apache log output to grep (STDIN) which filters it for you only showing messages that contain «DevSys1».
The «-f» option means «follow» which streams all new log entries to your terminal or to any piped command that follows, in this case «grep».
Relative paths are accepted as the destination of message_type 3, but beware that the root directory is determined by the context of the call to error_log(), which can change, so that one instance of error_log () in your code can lead to the creation of multiple log files in different locations.
In a WordPress context, the root directory will be the site’s root in many cases, but it will be /wp-admin/ for AJAX calls, and a plugin’s directory in other cases. If you want all your output to go to one file, use an absolute path.
when using error_log to send email, not all elements of an extra_headers string are handled the same way. «From: » and «Reply-To: » header values will replace the default header values. «Subject: » header values won’t: they are *added* to the mail header but don’t replace the default, leading to mail messages with two Subject fields.
When logging to apache on windows, both error_log and also trigger_error result in an apache status of error on the front of the message. This is bad if all you want to do is log information. However you can simply log to stderr however you will have to do all message assembly:
LogToApache($Message) <
$stderr = fopen(‘php://stderr’, ‘w’);
fwrite($stderr,$Message);
fclose($stderr);
>
«It appears that the system log = stderr if you are running PHP from the command line»
Actually, it seems that PHP logs to stderr if it can’t write to the log file. Command line PHP falls back to stderr because the log file is (usually) only writable by the webserver.
Note that since typical email is unencrypted, sending data about your errors over email using this function could be considered a security risk. How much of a risk it is depends on how much and what type of information you are sending, but the mere act of sending an email when something happens (even if it cannot be read) could itself imply to a sophisticated hacker observing your site over time that they have managed to cause an error.
Of course, security through obscurity is the weakest kind of security, as most open source supporters will agree. This is just something that you should keep in mind.
And of course, whatever you do, make sure that such emails don’t contain sensitive user data.
Another trick to post «HTML» mail body. Just add «Content-Type: text/html; charset=ISO-8859-1» into extra_header string. Of course you can set charset according to your country or Env or content.
stuff
«,1,»eat@joe.com»,»subject :lunch\nContent-Type: text/html; charset=ISO-8859-1″);
Depending on the error, you may also want to add an error 500 header, and a message for the user:
//Multiline error log class
// ersin güvenç 2008 eguvenc@gmail.com
//For break use «\n» instead ‘\n’
Class log <
//
const USER_ERROR_DIR = ‘/home/site/error_log/Site_User_errors.log’ ;
const GENERAL_ERROR_DIR = ‘/home/site/error_log/Site_General_errors.log’ ;
When error_log() unexpectedly uses stdout, you should check if the php.ini value for error_log is empty in your CLI environment. Something as simple as this might restore expected behavior:
After scouring the internet for getting event logging to
work in syslog on Windows 2003, I found the following
from this post and was able to successfully get Windows
Event Viewer to log PHP errors/notices:
How do I log errors and warnings into a file?
How do I turn on all error and warnings and log them to a file, but to set up all of that within the script (not changing anything in php.ini)?
I want to define a file name and so that all errors and warnings get logged into it.
7 Answers 7
Use the following code:
Then watch the file:
Or update php.ini as described in this blog entry from 2008.
You can customize error handling with your own error handlers to call this function for you whenever an error or warning or whatever you need to log occurs. For additional information, please refer to the Chapter Error Handling in the PHP Manual
Simply put these codes at top of your PHP/index file:
Add this code in file .htaccess (as an alternative to file php.ini or the ini_set function):
That’s my personal short function
Take a look at the log_errors configuration option in php.ini. It seems to do just what you want to. I think you can use the error_log option to set your own logging file too.
Логирование в распределенном php-приложении
В статье пойдет речь о том, какую пользу оказывает логирование. Расскажу о логах по PSR. Добавлю немного личных рекомендаций по работе с уровнем, сообщением и контекстом логируемого события. Будет приведен пример, как можно организовать логирование и мониторинг с помощью ELK в приложении, написанном на Laravel и запущенном через Docker на нескольких инстансах. Распишу важное правило системы оповещения. Приведу пример скрипта, который поднимает одной командой весь стек мониторинга.
Польза логирования
Хорошо организованное логирование позволяет, как минимум, следующее:
Сама по себе запись в лог вам всего этого не скажет, но с помощью логов будет возможность самостоятельно узнать подробности событий, либо настроить систему мониторинга логов, которая будет иметь возможность оповещать о проблемах. Если сообщения в логах сопровождаются достаточным объемом контекста, то это значительно упрощает отладку, потому что вам будет доступно больше данных о ситуации, в которой произошло событие.
Чем писать и что писать
Частью php-сообщества разработаны рекомендации по некоторым задачам написания кода. Одна из таких рекомендаций PSR-3 Logger Interface. Она как раз описывает то, чем нужно логировать. Для этого разработан интерфейс Psr\Log\LoggerInterface пакета «psr/log». При его использовании нужно знать о трёх составляющих события:
Уровни события по PSR-3
Уровни заимствованы из RFC 5424 — The Syslog Protocol, примерное описание их следующее:
Описание есть, но следовать им не всегда получается легко, из-за сложности определения важности некоторых событий. Например, в контексте одного запроса не удалось выполнить обращение к подключаемому ресурсу. При записи этого события мы не знаем, один ли такой запрос завершился неудачей, а может только у одного пользователя такие запросы завершаются неудачей. От этого зависит, требуется безотлагательное вмешательство или это редкий случай, может подождать или даже его можно проигнорировать. Такие вопросы решаются в рамках мониторинга логов. Но уровень определить всё равно надо. Поэтому об уровнях логирования в команде можно договориться. Пример:
Сообщение события
Контекст события
В Laravel можно для событий автоматически вписывать в контекст данные. Это можно сделать через Global Log Context (только для непойманных исключений или через report() ), либо через LogFormatter (для всех событий). Обычно, добавляется информация с id текущего пользователя, request URI, IP, request UUID и подобное.
При использовании Elasticsearch в качестве хранилища логов следует помнить, что в нём используются фиксированные типы данных. То есть, если вы передавали в контексте customer_id числом, то при попытке сохранить событие с другим типом, например строкой (uuid), то такое сообщение не запишется. Типы в индексе фиксируются при первом получении значения. Если индексы создаются каждый день, то новый тип запишется только на следующий день. Но даже это не избавит от всех проблем, потому что для Kibana типы будут смешанными и часть операций, привязанных к типу, будет недоступна пока будут смешанные индексы.
Для предотвращения этой проблемы рекомендую придерживаться правил:
Вызов логгера из кода
Для быстрой записи события в лог можно придумать несколько вариантов. Рассмотрим некоторые из них.
Где в коде вызывать логгер
При организации кода в проекте может возникнуть вопрос, в каком классе мне следует писать в лог. Должен ли это быть сервис? Или это нужно делать там, откуда сервис вызываем: контроллер, фоновая задача, консольная команда? Или каждое исключение само должно решать, что ему писать в лог с помощью его метода report (Laravel)? Простого ответа сразу на все вопросы нет.
Может показаться, что мы всегда можем логировать только в сервисах. Действительно, в некоторых сервисах можно сделать логирование. Но рассмотрим сервис, который не зависит от проекта и, вообще, мы планируем вынести его в отдельный пакет. Тогда этот сервис не знает о своей важности в проекте, а, значит, не сможет определить уровень логирования. Например, сервис интеграции с конкретным SMS-шлюзом. Если мы получили сетевую ошибку, то это ещё не значит, что она достаточно серьезная. Возможно, в системе есть сервис интеграции с другим SMS-шлюзом, через который будет вторая попытка отправки, тогда ошибку от первого можно репортить как warning, а ошибку второго как error. Только вот все эти интеграции должны быть вызваны из другого сервиса, который как раз и будет логировать. Получается, что ошибка в одном сервисе, а логируем в другом. Но иногда у нас нет сервиса-обёртки над другим сервисом — мы вызываем сразу из контроллера. В этом случае я считаю допустимым писать в лог в контроллере вместо того, чтобы писать сервис-декоратор для логирования.
Пример, показывающий использование зависимости и передачу контекста:
Куда писать
Рассмотрим следующие варианты.
* В php-fpm 7.2 при записи логов в stdout получаем «WARNING: [pool www] child X said into stdout. «, и длинные сообщения обрезаются. Одно из решений этой проблемы здесь. В php-fpm 7.3 такой проблемы нет.
Варианты формата записи:
Любой из вариантов предполагает, что логи подвергаются маршрутизации — как минимум, отправке в единую систему обработки (хранения) логов по следующим причинам:
Какую комбинацию всех возможностей мест назначений и форматов записи выбрать вы можете решить для вашего проекта самостоятельно.
Использование Filebeat + ELK + Elastalert
Кратко роль каждого сервиса можно описать так:
Дополнительно можно: zabbix, metricbeat, grafana и прочее.
Теперь подробнее о каждом.
Filebeat
Logstash
Умеет принимать события от многих источников, но здесь мы рассматриваем Filebeat.
В каждом событии кроме самого события из stdout/stderr есть метаданные (хост, контейнер и т. п.). Много встроенных фильтров обработки: парсить по регуляркам, разбирать json, изменять, добавлять, удалять поля и т. п. Подходит для парсинга как логов приложения, так и nginx access.log в произвольном формате. Умеет передавать данные в разные хранилища, но здесь рассматриваем Elasticsearch.
Elasticsearch
Elasticsearch очень мощный инструмент для большого спектра задач, но с целью мониторинга логов его можно использовать зная лишь некоторый минимум.
Сохраненные события — это документ, документы хранятся в индексах.
Каждый индекс — это схема, в которой определен тип для каждого поля документа. Нельзя сохранить событие в индексе, если хотя бы у одного поля неподходящий тип.
Разные типы позволяют делать разные операции над группой документов (для чисел — sum, min, max, avg и т. п., для строк — нечеткий поиск и так далее).
Для логов руководства обычно рекомендуют использовать дневные индексы — каждый день новый индекс.
Обеспечение стабильной работы Elasticsearch с ростом объема данных — задача, требующая более глубоких знаний об этом инструменте. Но быстрым решением проблемы стабильности можно выбрать автоматическое удаление устаревших данных. Для этого я предлагаю разбивать в logstash уровни событий по разным индексам. Это позволит дольше хранить редкие, но более важные события.
Для автоматического удаления устаревших индексов предлагаю использовать программу от Elastic Curator. Запуск программы добавляется в расписание Cron, сама конфигурация может храниться в отдельном файле.
Для долговечного хранения событий предлагаю использовать альтернативные системы хранения, которые могут быть подключены как сервисы приёма от Filebeat или Logstash, либо полностью отдельно. В недавних версиях Elasticsearch ввели разбиение на горячие-теплые-холодные индексы, возможно, их следует вам рассмотреть.
Kibana
Kibana здесь используется как инструмент для чтения журнала событий. Это веб-приложение, которое выполняет запросы к Elasticsearch. Позволяет строить дашборды с разными визуализациями показателей.
Типичное использование Kibana — это ежедневный просмотр списка недавних событий в разделе Discovery с некоторыми фильтрами. Например, отдельная страница Discovery с отображением списка недавних событий из app с уровнем warning и выше, где выводятся столбцы time, message, exception class, host, client_id.
Другой пример, страница Discovery с отображением списка недавних событий из nginx, у которых неуспешные статусы и не 404 с отображением столбцов time, message, request, status.
Кроме того Kibana используется для дебага, так как в ней можно быстро отфильтровать события: по сообщению, по уровню, по любому значению из контекста. Например, выбрать все события по конкретному клиенту (делается в один клик по одному событию нужного клиента).
Elastalert
Elastalert используется для выполнения запросов к Elasticsearch и оповещению на основе их результатов. Другими словами, алертинг. Есть широкий набор типов правил, с помощью которых можно построить эффективную систему оповещения об отклонениях.
Для каждого правила можно указать расписание запуска, интервал для повторной отправки по тому же условию (реалерт), список сервисов для оповещения и многое другое.
Некоторые примеры правил:
При подключении автоматических оповещений о событиях следует не допустить очень серьезную ошибку — слишком частое оповещение. Я рекомендую настраивать автоматическое оповещение таким образом, чтобы уведомления шли только по событиям, требующим безотлагательного вмешательства. Всё остальное нужно привыкать смотреть самостоятельно используя Kibana.
Если вы настроили правило, например, что успешных http-кодов должно быть не менее 75% за час, затем получили оповещение об отклонении, проверили и обнаружили, что ничего страшного не произошло, то правило нужно менять. Если какое-то правило постоянно срабатывает, но ничего критичного не происходит, и уже нечего менять в правиле, то лучше его отключить совсем.
Если ваша система постоянно дает сбой неделю за неделей, то, скорее всего, вы и сами уже знаете, чего ждать в списке событий в Kibana, поэтому отключите автоматические уведомления и проверяйте состояние вручную.
Рекомендую границу в 5 уведомлений в неделю в среднем. Если их получается больше, значит, это уже не внезапные отклонения, а ожидаемые, а значит, уведомления по ним не нужны.
Я уделил особое внимание частоте оповещений, потому что нарушение этого правила приводит к полному игнорированию оповещений. Это сводит пользу автоматических уведомлений на нет.
При получении оповещения хорошей привычкой может стать обзор ситуации через просмотр Kibana по всем недавним событиям. Это позволит точнее оценить ситуацию и корректно расставить приоритеты при решении проблемы.
Всё вместе
Всё описанное можно запускать в docker-контейнерах. Причём всё конфигурируется таким образом, что всем стеком можно пользоваться как локально при разработке, так и в staging- и production-окружениях, где переменными остаются только переменные окружения.
Все описанные сервисы, за исключением Elastalert, позволяют использовать переменные окружения в конфигурациях. Проблему Elastalert удалось разрешить, используя команду вида
envsubst /opt/elastalert/config.yaml в entrypoint-скрипте и доустановкой зависимостей, чтобы это работало.
Конфигурации каких сервисов стека оставлять в репозитории проекта, а какие выносить в отдельный репозиторий мониторинга, зависит от наличия других проектов и того, как они будут переиспользовать стек.
Такой вариант стека имеет следующие преимущества:
Стоит заметить, что в данном подходе не используется ни один из xpack-плагинов.
Допустим вариант использования docker-compose. Главное, что основная конфигурация, состоящая из Dockerfile-ов, конфига Filebeat, конфигов Logstash, правил оповещения, правил автоудаления индексов, находится под системой контроля версий, получая возможность быстрого переразвертывания, хранения истории изменений и всех других преимуществ VCS.
Важно уделять внимание автоматической проверки работоспособности стека. Я предлагаю организовать проверку следующим образом. В самом приложении создается задача, исполняемая по расписанию (в Laravel для этого есть scheduler), скажем, раз в неделю за 5 минут до дейлимитинга. Сама задача вызывает логгер и записывает сообщение с уровнем ALERT. Если весь стек функционирует нормально, то вы получите оповещение. Если такого оповещения нет, а вы к нему привыкли, то это станет сигналом для разбирательств.
Заключение
Я описал, какую пользу можно извлечь из логирования, рассказал о некоторых вариантах, которые можно выбирать на каждом шаге построения стека логирования и мониторинга. Привёл пример стека с описанием каждого компонента. Надеюсь, вы нашли что-то полезное для себя в этом материале. Данные мной рекомендации были опробованы на нескольких проектах и хорошо себя показали в бою. Но следует помнить, что всегда есть, что улучшить.
Where does PHP store the error log? (php5, apache, fastcgi, cpanel)
I am on shared hosting and have cPanel, Apache, and PHP is run by FastCGI. Where does PHP store the error log?
Is there another way I can find the error log on a shared hosting environment instead of having to go through entire site structure to look for error_log files?
I have access to the php.ini file (I am using PHP version 5.2.16).
26 Answers 26
PHP stores error logs in /var/log/apache2 if PHP is an apache2 module. Shared hosts are often storing log files in your root directory /log subfolder. But. if you have access to a php.ini file you can do this:
According to rinogo‘s comment: If you’re using cPanel, the master log file you’re probably looking for is stored (by default) at
If all else fails you can check the location of the log file using
Try phpinfo() and check for «error_log»
Linux
The terminal will output the error log location.
Windows
The command prompt will output the error log location
To set the log location
Open your php.ini and add the following line:
Thanks @chelmertez, @Boom for these (comments on the question).
On a LAMP environment the php errors are default directed to this below file.
All access logs come under:
How do find your PHP error log on Linux:
Another equivalent way:
It appears that by default php does not log errors anywhere, the error_log key in php.ini is commented out in all the install’s I’ve seen.
Search these files for the error_reporting value;
Which should be set to whatever amalgamation of php log levels are enough for you.,
Check the error_log value to make sure it points to an actual place and is not commented out.
It can also be /var/log/apache2/error.log if you are in google compute engine.
And you can view tail like this:
You should use absolute path when setting error_log variable in your php.ini file, otherwise, error logs will be stored according to your relative path.
Other solution would be writing simple script which would list all error logs files from directory tree.
This is helpful. commented by sjas on question. so i included it as a answer.
NGINX usually stores it in /var/log/nginx/error.log or access.log. (On Ubuntu in any case)
When configuring your error log file in php.ini, you can use an absolute path or a relative path. A relative path will be resolved based on the location of the generating script, and you’ll get a log file in each directory you have scripts in. If you want all your error messages to go to the same file, use an absolute path to the file.
If You use php5-fpm log default should be under
Search the httpd.conf file for ErrorLog by running cat | grep ErrorLog on the command line. For example:
Find the line that starts with ErrorLog and there’s your answer.
Note: For virtual hosts, you can edit the virtual hosts file httpd-vhosts.conf to specify a different log file location.
cPanel Error logs are located in:
By default Apche logs are located inside:
If anyone is using custom log location then you can check it by running this command:
cat /etc/apache2/conf/httpd.conf | grep ErrorLog
If you are getting error that apache2 directory does not exist then you can run this command to find correct location by:
something like this :
On cPanel search bar, search Error, it will show Error Pages which are basically lists of different http error pages and other Error is where the error logs are displayed.
Other places to look on shared environment: /home/yourusername/logs /home/yourusername/public_html/error_log
for centos 8 var/log/httpd/error_log
WordPress
WordPress will direct error_log() messages to /wp-content/debug.log when WP_DEBUG_LOG is set to true.
For PHP-FPM just search config file for error_log :
A bit late and a lot of great answers were given, but mine for some reason stored it in:
I’m using Ubuntu Server 16.04 and PHP 7.1.28.
On shared cPanel environment you cannot find error log, if your hosting provider don’t provide any option in cPanel Dashboard. You can search «error» and see if your provider have any.
Otherwise normally you will find a file called «error_log» on your public_html file, which have all the php error recorded.
I can guarantee you, I am not the only person who has been driven to madness at least once in a frustrating search for a log file. It seems like it should be the easiest thing to find in the whole system.
A definitive guide on where php error log is stored would be a complicated bit of work. The official php manual does not even try to address the whole topic, because there are dependencies on systems outside php, such as the operating system (linux vs. Windows, which distro of linux), including settings within Windows and linux that affect name and location of the php error log.
Until someone takes the time to write a complete, cross-system guide, the best you are going to get is general directions where you can inquire. Every php developer has had to endure agony in this pursuit, with one exception. If you work in one place and the information is provided when you first need it, then you have the information need forever, that is, until you find yourself in a new working environment. There are such fortunate people.
If the information is not given to you on a silver platter, so to speak, you have some hunting to do. The hunt is not the longest you will face in your career, but it is not the simplest either.
As is evident from the many answers already posted, a smart place to begin is the output of phpinfo(). To view it, create a php file containing this:
Either browse to that file or run it from the command line. If you do both, you likely will find the error_log is in different places, depending on command line vs. web server use of php. That is because the php that runs on a webserver is not the same php that runs from the command line, even when the command line is on the same machine as the web server. The answers already posted in this thread mostly are making an unstated assumption that php is running as part of a web server.
`
The default for error_log is no value
Whatever the value is, it comes from the php.ini files used to configure php. There can be many php.ini files. Finding your way among them is confusing at first, but you do not need to deal with this to find your php log.
If the output from phpinfo() shows a full path to a file, that is where the log is. You are lucky.
The trick is there usually is not a full path indicated in phpinfo(). When there is not a full path, the location depends on:
Whether error_log is no value. If it is, the log file location will depend on the operating system and the mode php is running. If php is running as an apache module, on linux the log often is in /var/log/apache2/error.log Another likely spot is in a logs directory in your account home directory,
If there is a file name without a path, the location depends on whether the file name has the value syslog. If it syslog, then the php error log is injected into the syslog for the server, which varies by linux distro. A common location is /var/log/syslog, but it can be anywhere. Even the name of the syslog varies by distro.
If the name without a path is not syslog, a frequent home for the file is is the document root of the website (a.k.a., website home directory, not to be confused with the home directory for your account).
This cheat sheet has been helpful in some situations, but I regret to have to admit it is not nearly universal. You have my condolences.