Php логирование ошибок в файл
Для этого сделаем класс exceptionHandlerClass. В exceptionHandlerClass будут храниться настройки и статические методы — обработчики error, exception и assertion. Еще нам нужны методы setupHandlers и restoreHandlers. Первый метод настроит перехват ошибок. Error и assertion обработчики будут бросать ErrorException. Exception обработчик будет обрабатывать необработанные Exception и в зависимости от настроек выводить соответствующий ответ. restoreHandlers вернет все обработчики в изначальное состояние — это поможет при встраивании класса в код с существующим механизмом обработки ошибок. Подключение выглядит так:
- require 'exceptionHandler/exceptionHandlerClass.php' ;
- exceptionHandlerClass :: setupHandlers ( ) ;
Проще объяснить на примере: для вывода trace на веб странице я оберну его в таги pre и применю htmlspecialchars(), с другой стороны этот же trace при выводе в консоль будет не удобно читать, было бы проще, если бы это был plainText. Если нужно вывести ошибку как ответ SоapServer, то это должен быть правильно сформированный XML документ (SoapFault). Если скрипт выводит бинарные данные, например изображение, то удобней выводить ошибки через WildFire. Во всех этих ситуация нужно просто применить разные форматы вывода.
Для разных форматов будем создавать разные классы. Я для начала реализую два формата вывода exceptionHandlerOutputWeb(для веба) и exceptionHandlerOutputCli(для командной строки). Так же нам понадобиться класс фабрика (exceptionHandlerOutputFactory), в котором будет инкапсулирована логика, когда какой формат вывода применить.
- public function getExceptionHandlerOutput ( )
- if ( php_sapi_name ( ) == 'cli' )
- return new exceptionHandlerOutputCli ( ) ;
- >
- return new exceptionHandlerOutputWeb ( ) ;
- >
При вызове setupHandlers можно установить формат вывода, передав экземпляр класса exceptionHandlerOutput* или exceptionHandlerOutputFactory*.
- exceptionHandlerClass :: setupHandlers ( new exceptionHandlerOutputAjax ( ) ) ;
Благодаря такой архитектуре можно легко расширять форматы. Для создания нового формата достаточно создать класс, который будет наследоваться от абстрактного класса exceptionHandlerOutput и реализовать один метод (output).
Если нужна более сложная логика для автоматического выбора формата вывода, нужно создать класс, наследуемый от exceptionHandlerOutputFactory и реализовать метод getExceptionHandlerOutput.
Как я и сказал выше логирование можно включать по желанию. Для этого в exceptionHandlerClass создан метод exceptionLog
- public static function exceptionLog ( $exception , $logPriority = null )
- if ( ! is_null ( self :: $exceptionHandlerLog ) )
- self :: $exceptionHandlerLog -> log ( $exception , $logPriority ) ;
- >
- >
- exceptionHandlerClass :: $exceptionHandlerLog = new exceptionHandlerSimpleLog ( ) ;
Класс для логирования должен наследоваться от абстрактного exceptionHandlerLog и реализовывать метод log
- class exceptionHandlerSimpleLog extends exceptionHandlerLog
- public function log ( $exception , $logType )
- switch ( $logType )
- case self :: uncaughtException :
- error_log ( $exception -> getMessage ( ) ) ;
- break ;
- >
- >
- >
- const uncaughtException = 0 ; //необработанные исключения
- const caughtException = 1 ; //вызов метода логирования вне обработчиков ошибок
- const ignoredError = 2 ; //ошибки маскированные @, логируются если выключена опция scream
- const lowPriorityError = 3 ; //ошибки которые не превращаются exception
- const assertion = 4 ; //assertion
Имея logType и exception разработчик может сам решить какие искллючения и как логировать. Например, uncaughtException можно высылать по почте, ignoredError с severity E_ERROR логировать в файл итп.
- r: — resource
- fs: — function (callable string)
- fa: — function (callable array)
- i: — interface (string)
- c: — class (string)
- ∞/INF — infinity
- testClass() — object of type testClass
- ""(n) — string, в скобках указана длина, … — место где вырезана часть строки
- array(n) — array, в скобках указана длина
При нажатии на ссылку в IDE откроется соответствующий файл на соответствующей строке.
Для консольного режима (консоль NetBeans):
- exceptionHandlerOutputCli :: setFileLinkFormat ( ': in %f on line %l' ) ;
- exceptionHandlerOutputWeb :: setFileLinkFormat ( 'txmt://open/?file://%f&line=%l' ) ;
UPD: перенесено в блог PHP
UPD2: в продолжение темы работа с исключениями в PHP
Sends an error message to the web server's error log or to a file.
stuff
",1,"eat@joe.com","subject :lunch\nContent-Type: text/html; charset=ISO-8859-1");//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' ;
/*
User Errors.
*/
public function user ( $msg , $username )
<
$date = date ( 'd.m.Y h:i:s' );
$log = $msg . " | Date: " . $date . " | User: " . $username . "\n" ;
error_log ( $log , 3 , self :: USER_ERROR_DIR );
>
/*
General Errors.
*/
public function general ( $msg )
<
$date = date ( 'd.m.Y h:i:s' );
$log = $msg . " | Date: " . $date . "\n" ;
error_log ( $msg . " | Tarih: " . $date , 3 , self :: GENERAL_ERROR_DIR );
>
$log = new log ();
$log -> user ( $msg , $username ); //use for user errors
//$log->general($msg); //use for general errors
?>
Depending on the error, you may also want to add an error 500 header, and a message for the user:
$message = 'Description of the error.';
error_log($message);
header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
exit($message);
In the case of missing your entries in the error_log file:
When you use error_log in a script that does not produce any output, which means that you cannot see anything during the execution of the script, and when you wonder why there are no error_log entries produced in your error_log file, the reasons can be:
- you did not configure error_log output in php.ini
- the script has a syntax error and did therefore not execute
If you have a problem with log file permission *silently*
it's best to leave error_log directive unset so errors will be written in your Apache log file for current VirtualHost.
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:
It appears that error_log() only logs the first line of multi-line log messages. To log a multi-line message, either log each line individually or write the message to another file.
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:
1. Copy the PHP 5 binaries to "C:\php".
2. Right-click My Computer and select Properties to bring
up the Computer Properties dialog. Switch to the Advanced
tab and click Environment Variables. Find the system
environment variable PATH, edit it and add ";C:\php"
(without the quotes) to the end.
3. Make sure that the configuration file "php.ini" resides
in the directory "C:\php" and contains the correct path
settings.
4. DELETE any old "php.ini" files from "C:\WINDOWS"
and other directories.
5. Open REGEDIT, navigate to the key
"HKLM\SOFTWARE\PHP" and DELETE the string value
"IniFilePath" from there. It is outdated and no longer
necessary!
6. Modify NTFS security permissions of the directory
"C:\php" to give Read and Execute permissions to (1) the
IIS Guest Account and (2) the group IIS_WPG.
7. Modify NTFS security permissions of the directories
"C:\php\session" and "C:\php\upload" to give additional
Modify permissions to (1) the IIS Guest Account and (2)
the group IIS_WPG.
8. Navigate to the registry key
"HKLM\SYSTEM\CurrentControlSet\Services\Eventlog
\Application" and edit the value "CustomSD" there. Find
the substring "(D;;0xf0007;;;BG)" which Denies access to
the application event log for Builtin Guest accounts (like
the IIS Web User account) and replace this substring with
"(A;;0x3;;;BG)" which allows read and write access. Please
pay attention to leave the rest of the security string intact.
Damaging this value can have dangerous effects!
9. Create or update the registry key
"HKLM\SYSTEM\CurrentControlSet\Services\Eventlog\Application\
PHP-5.2.0" (adapt the last to your version part
if necessary) with the following values:
Although the root user writes to the files 'error_log' and 'access_log', the Apache user has to own the file referenced by 'error_log = filename' or no log entries will be written.
; From php.ini
; Log errors to specified file.
error_log = /usr/local/apache/logs/php.errors
[root@www logs]$ ls -l /usr/local/apache/logs/php.errors
-rw-r--r-- 1 nobody root 27K Jan 27 16:58 php.errors
I keep seeing qualification lists for error types/error-nums as arrays; In user notes and in the manual itself. For example, in this manual entry's example, when trying to seperate behavior for the variable trace in the error report:
// set of errors for which a var trace will be saved
$user_errors = array( E_USER_ERROR , E_USER_WARNING , E_USER_NOTICE );
if ( in_array ( $errno , $user_errors )) //. whatever
>
//. ?>
I was under the impression that PHP error code values where bitwise flag values. Wouldn't bitwise masking be better? So I propose a slightly better way:
$user_errors = E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE ;
if ( $errno & $user_errors ) //. whatever
>
//. ?>
Or for those of you who don't like the idea of using an integer as the condition in an if statement:
if (( $errno & $user_errors ) > 0 ) //. whatever
>
?>
I think that's much more efficient than using _yet another_ array() constuct and an in_array().
If I am wrong, and the E_* constants aren't supposed to be used in this fashion (ie, the constans aren't guaranteed to be bitwise, which would be odd since that's how they're setup in the php.ini file), then delete me. I just don't see why one should be using arrays when bitwise comparisons will work, considering the bitwise method should be MUCH more efficient.
PHP5 only (only tested with php5.0).
If you, for some reason, prefer exceptions over errors and have your custom error handler (set_error_handler) wrap the error into an exception you have to be careful with your script.
Because if you, instead of just calling the exception handler, throws the exception, and having a custom exception handler (set_exception_handler). And an error is being triggered inside that exception handler, you will get a weird error:
"Fatal error: Exception thrown without a stack frame in Unknown on line 0"
This error is not particulary informative, is it? :)
This example below will cause this error.
class PHPErrorException extends Exception
private $context = null ;
public function __construct
( $code , $message , $file , $line , $context = null )
parent :: __construct ( $message , $code );
$this -> file = $file ;
$this -> line = $line ;
$this -> context = $context ;
>
>;
function error_handler ( $code , $message , $file , $line ) throw new PHPErrorException ( $code , $message , $file , $line );
>
function exception_handler ( Exception $e )
<
$errors = array(
E_USER_ERROR => "User Error" ,
E_USER_WARNING => "User Warning" ,
E_USER_NOTICE => "User Notice" ,
);
echo $errors [ $e -> getCode ()]. ': ' . $e -> getMessage (). ' in ' . $e -> getFile ().
' on line ' . $e -> getLine (). "\n" ;
echo $e -> getTraceAsString ();
>
set_error_handler ( 'error_handler' );
set_exception_handler ( 'exception_handler' );
// Throw exception with an /unkown/ error code.
throw new Exception ( 'foo' , 0 );
?>
There are however, easy fix for this as it's only cause is sloppy code.
Like one, directly call exception_handler from error_handler instead of throwing an exception. Not only does it remedy this problem, but it's also faster. Though this will cause a `regular` unhandled exception being printed and if only "designed" error messages are intended, this is not the ultimate solution.
So, what is there to do? Make sure the code in exception_handlers doesn't cause any errors! In this case a simple isset() would have solved it.
If you are using PHP as an Apache module, your default behavior may be to write PHP error messages to Apache's error log. This is because the error_log .ini directive may be set equal to "error_log" which is also the name of Apache's error log. I think this is intentional.
However, you can separate Apache errors from PHP errors if you wish by simply setting a different value for error_log. I write mine in the /var/log folder.
Note the example code listed here calls date() every time this is called. If you have a complex source base which calls the custom error handler often, it can end up taking quite a bit of time. I ran a profiler on som code and discovered that 50% of the time was spent in the date function in this error handler.
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.
In some application development methodologies, there is the concept of an application root directory, indicated by "/" (even on Windows). However, PHP does not seem to have this concept, and using a "/" as the initial character in a log file path produces weird behavior on Windows.
If you are running on Windows and have set, in php.ini:
You will get some, but not all, error messages. The file will appear at
and contain internally generated error messages, making it appear that error logging is working. However, log messages requested by error_log() do NOT appear here, or anywhere else, making it appear that the code containing them did not get processed.
Apparently on Windows the internally generated errors will interpret "/" as "C:\" (or possibly a different drive if you have Windows installed elsewhere - I haven't tested this). However, the error_log process apparently can't find "/" - understandably enough - and the message is dropped silently.
It is totally possible to use debug_backtrace() inside an error handling function. Here, take a look:
function errorHandler ( $errno , $errstr , $errfile , $errline , $errcontext )
echo 'Into ' . __FUNCTION__ . '() at line ' . __LINE__ .
"\n\n---ERRNO---\n" . print_r ( $errno , true ).
"\n\n---ERRSTR---\n" . print_r ( $errstr , true ).
"\n\n---ERRFILE---\n" . print_r ( $errfile , true ).
"\n\n---ERRLINE---\n" . print_r ( $errline , true ).
"\n\n---ERRCONTEXT---\n" . print_r ( $errcontext , true ).
"\n\nBacktrace of errorHandler()\n" .
print_r ( debug_backtrace (), true );
>
function a ( )
//echo "a()'s backtrace\n".print_r( debug_backtrace(), true);
asdfasdf ; // oops
>
function b ()
//echo "b()'s backtrace\n".print_r( debug_backtrace(), true);
a ();
>
Into errorhandler() at line 9
---ERRSTR---
Use of undefined constant asdfasdf - assumed 'asdfasdf'
Backtrace of errorHandler()
Array
(
[0] => Array
(
[function] => errorhandler
[args] => Array
(
[0] => 8
[1] => Use of undefined constant asdfasdf - assumed 'asdfasdf'
[2] => /home/theotek/test-1.php
[3] => 23
[4] => Array
(
)
[1] => Array
(
[file] => /home/theotek/test-1.php
[line] => 23
[function] => a
)
[2] => Array
(
[file] => /home/theotek/test-1.php
[line] => 30
[function] => a
[args] => Array
(
)
[3] => Array
(
[file] => /home/theotek/test-1.php
[line] => 33
[function] => b
[args] => Array
(
)
So, the first member of the backtrace's array is not really surprising, except from the missing "file" and "line" members.
The second member of the backtrace seem the be a hook inside the zend engine that is used to trigger the error.
Другие публикации
Изображения нужно сжимать для ускорения скорости загрузки сайта, но как это сделать? На многих хостингах нет.
JSON (JavaScript Object Notation) – текстовый формат обмена данными, основанный на JavaScript, который представляет собой набор пар <ключ: значение>. Значение может быть массивом, числом, строкой и.ключ:>
phpQuery – это удобный HTML парсер взявший за основу селекторы, фильтры и методы jQuery, которые позволяют.
Комментарии 1
Пользовательские ошибки
PHP позволяет разработчику самому объявлять ошибки, которые выведутся в браузере или в логе. Для создания ошибки используется функция trigger_error() :
Результат:
Возвращаемые значения
Возвращает true в случае успешного выполнения или false в случае возникновения ошибки. Если message_type равен нулю, функция всегда возвращает true , независимо от того, может ли ошибка логироваться или нет.
Parameters
The error message that should be logged.
Says where the error should go. The possible message types are as follows:
0 | message is sent to PHP's system logger, using the Operating System's system logging mechanism or a file, depending on what the error_log configuration directive is set to. This is the default option. |
1 | message is sent by email to the address in the destination parameter. This is the only message type where the fourth parameter, additional_headers is used. |
2 | No longer an option. |
3 | message is appended to the file destination . A newline is not automatically added to the end of the message string. |
4 | message is sent directly to the SAPI logging handler. |
The destination. Its meaning depends on the message_type parameter as described above.
The extra headers. It's used when the message_type parameter is set to 1 . This message type uses the same internal function as mail() does.
Запись ошибок в лог файл
Файлы логов также не должны быть доступны из браузера, храните их в закрытой директории с файлом .htaccess:
Или запретить доступ к файлам по расширению .log (заодно и другие системные файлы и исходники):
Список параметров
Определяет куда отправлять ошибку. Возможны следующие значения:
Назначение. Устанавливается в зависимости от параметра message_type .
Parameters
The error message that should be logged.
Says where the error should go. The possible message types are as follows:
0 | message is sent to PHP's system logger, using the Operating System's system logging mechanism or a file, depending on what the error_log configuration directive is set to. This is the default option. |
1 | message is sent by email to the address in the destination parameter. This is the only message type where the fourth parameter, additional_headers is used. |
2 | No longer an option. |
3 | message is appended to the file destination . A newline is not automatically added to the end of the message string. |
4 | message is sent directly to the SAPI logging handler. |
The destination. Its meaning depends on the message_type parameter as described above.
The extra headers. It's used when the message_type parameter is set to 1 . This message type uses the same internal function as mail() does.
Changelog
Version | Description |
---|---|
8.0.0 | destination and additional_headers are now nullable. |
Отправка ошибок на e-mail
Ошибки можно отправлять на е-mail разработчика, но приведенные методы не работает при критических ошибках.
Первый – register_shutdown_function() регистрирует функцию, которая выполнится при завершении работы скрипта, error_get_last() получает последнюю ошибку.
Стоит учесть что оператор управления ошибками (знак @) работать в данном случаи не будет и письмо будет отправляться при каждой ошибке.
Второй метод использует «пользовательский обработчик ошибок», поэтому в браузер ошибки выводится не будут.
Return Values
Returns true on success or false on failure. If message_type is zero, this function always returns true , regardless of whether the error could be logged or not.
Примеры
// Отправляет уведомление посредством серверного лога, если мы не можем
// подключиться к базе данных.
if (! Ora_Logon ( $username , $password )) error_log ( "База данных Oracle недоступна!" , 0 );
>
// Уведомить администратора по электронной почте, если невозможно выделить ресурсы для FOO
if (!( $foo = allocate_new_foo ())) error_log ( "Большая проблема, мы выпали из FOO!" , 1 ,
"operator@example.com" );
>
// другой способ вызвать error_log():
error_log ( "Вы ошиблись!" , 3 , "/var/tmp/my-errors.log" );
?>
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();
I had this problem when I tried to debug a response from a wp_remote_get(); all of my error_log() worked as they should, except for ONE of them. (-_-)
After about a day of debugging I finally found out why & that's why I type this.
Apparently the response contained a body with over 1.6 million chars (or bytes? (whatever strlen() returns)).
If you have a string of unknown length, use this:
$start_index = 0;
$end_index = 8000;
error_log( substr( $output_text , $start_index , $end_index ) );
There is a limit on the maximum length that you can pass as the $message.
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":
error_log("DevSys1 - FirstName: $FirstName - LastName: $Lastname");
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".
Be carefull. Unexpected PHP dies when 2GByte of file log reached (on systems having upper file size limit).
A work aorund is rotate logs :)
It appears that the system log = stderr if you are running PHP from the command line, and that often stderr = stdout. This means that if you are using a custom error to both display the error and log it to syslog, then a command-line user will see the same error reported twice.
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.
error_log ( "sometext" , 1 , "zigzag@my.domain" ,
"Subject: Foo\nFrom: Rizzlas@my.domain\n" );
?>
---------------%To: zigzag@my.domain
Envelope-to: zigzag@my.domain
Date: Fri, 28 Mar 2003 13:29:02 -0500
From: Rizzlas@my.domain
Subject: PHP error_log message
Subject: Foo
Delivery-date: Fri, 28 Mar 2003 13:29:03 -0500
quoth the docs: "This message type uses the same internal function as mail() does."
mail() will also fail to set a Subject field based on extra_header data - instead it takes a seperate argument to specify a "Subject: " string.
php v.4.2.3, SunOS 5.8
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);
>
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.
"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.
EG: Error_log("
Примечания
error_log() не является бинарно-безопасной функцией. message обрезается по null-символу.
message не должен содержать null-символ. Учтите, что message может передаваться в файл, по почте, в syslog и т.д. Используйте подходящую преобразующую или экранирующую функцию, base64_encode() , rawurlencode() или addslashes() перед вызовом error_log() .
Examples
// Send notification through the server log if we can not
// connect to the database.
if (! Ora_Logon ( $username , $password )) error_log ( "Oracle database not available!" , 0 );
>
// Notify administrator by email if we run out of FOO
if (!( $foo = allocate_new_foo ())) error_log ( "Big trouble, we're all out of FOOs!" , 1 ,
"operator@example.com" );
>
// another way to call error_log():
error_log ( "You messed up!" , 3 , "/var/tmp/my-errors.log" );
?>
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();
I had this problem when I tried to debug a response from a wp_remote_get(); all of my error_log() worked as they should, except for ONE of them. (-_-)
After about a day of debugging I finally found out why & that's why I type this.
Apparently the response contained a body with over 1.6 million chars (or bytes? (whatever strlen() returns)).
If you have a string of unknown length, use this:
$start_index = 0;
$end_index = 8000;
error_log( substr( $output_text , $start_index , $end_index ) );
There is a limit on the maximum length that you can pass as the $message.
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":
error_log("DevSys1 - FirstName: $FirstName - LastName: $Lastname");
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".
Be carefull. Unexpected PHP dies when 2GByte of file log reached (on systems having upper file size limit).
A work aorund is rotate logs :)
It appears that the system log = stderr if you are running PHP from the command line, and that often stderr = stdout. This means that if you are using a custom error to both display the error and log it to syslog, then a command-line user will see the same error reported twice.
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.
error_log ( "sometext" , 1 , "zigzag@my.domain" ,
"Subject: Foo\nFrom: Rizzlas@my.domain\n" );
?>
---------------%To: zigzag@my.domain
Envelope-to: zigzag@my.domain
Date: Fri, 28 Mar 2003 13:29:02 -0500
From: Rizzlas@my.domain
Subject: PHP error_log message
Subject: Foo
Delivery-date: Fri, 28 Mar 2003 13:29:03 -0500
quoth the docs: "This message type uses the same internal function as mail() does."
mail() will also fail to set a Subject field based on extra_header data - instead it takes a seperate argument to specify a "Subject: " string.
php v.4.2.3, SunOS 5.8
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);
>
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.
"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.
EG: Error_log("
stuff
",1,"eat@joe.com","subject :lunch\nContent-Type: text/html; charset=ISO-8859-1");//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' ;
/*
User Errors.
*/
public function user ( $msg , $username )
<
$date = date ( 'd.m.Y h:i:s' );
$log = $msg . " | Date: " . $date . " | User: " . $username . "\n" ;
error_log ( $log , 3 , self :: USER_ERROR_DIR );
>
/*
General Errors.
*/
public function general ( $msg )
<
$date = date ( 'd.m.Y h:i:s' );
$log = $msg . " | Date: " . $date . "\n" ;
error_log ( $msg . " | Tarih: " . $date , 3 , self :: GENERAL_ERROR_DIR );
>
$log = new log ();
$log -> user ( $msg , $username ); //use for user errors
//$log->general($msg); //use for general errors
?>
Depending on the error, you may also want to add an error 500 header, and a message for the user:
$message = 'Description of the error.';
error_log($message);
header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
exit($message);
In the case of missing your entries in the error_log file:
When you use error_log in a script that does not produce any output, which means that you cannot see anything during the execution of the script, and when you wonder why there are no error_log entries produced in your error_log file, the reasons can be:
- you did not configure error_log output in php.ini
- the script has a syntax error and did therefore not execute
If you have a problem with log file permission *silently*
it's best to leave error_log directive unset so errors will be written in your Apache log file for current VirtualHost.
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:
It appears that error_log() only logs the first line of multi-line log messages. To log a multi-line message, either log each line individually or write the message to another file.
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:
1. Copy the PHP 5 binaries to "C:\php".
2. Right-click My Computer and select Properties to bring
up the Computer Properties dialog. Switch to the Advanced
tab and click Environment Variables. Find the system
environment variable PATH, edit it and add ";C:\php"
(without the quotes) to the end.
3. Make sure that the configuration file "php.ini" resides
in the directory "C:\php" and contains the correct path
settings.
4. DELETE any old "php.ini" files from "C:\WINDOWS"
and other directories.
5. Open REGEDIT, navigate to the key
"HKLM\SOFTWARE\PHP" and DELETE the string value
"IniFilePath" from there. It is outdated and no longer
necessary!
6. Modify NTFS security permissions of the directory
"C:\php" to give Read and Execute permissions to (1) the
IIS Guest Account and (2) the group IIS_WPG.
7. Modify NTFS security permissions of the directories
"C:\php\session" and "C:\php\upload" to give additional
Modify permissions to (1) the IIS Guest Account and (2)
the group IIS_WPG.
8. Navigate to the registry key
"HKLM\SYSTEM\CurrentControlSet\Services\Eventlog
\Application" and edit the value "CustomSD" there. Find
the substring "(D;;0xf0007;;;BG)" which Denies access to
the application event log for Builtin Guest accounts (like
the IIS Web User account) and replace this substring with
"(A;;0x3;;;BG)" which allows read and write access. Please
pay attention to leave the rest of the security string intact.
Damaging this value can have dangerous effects!
9. Create or update the registry key
"HKLM\SYSTEM\CurrentControlSet\Services\Eventlog\Application\
PHP-5.2.0" (adapt the last to your version part
if necessary) with the following values:
PHP предлагает гибкие настройки вывода ошибок, среди которых функия error_reporting($level) – задает, какие ошибки PHP попадут в отчет, могут быть значения:
- E_ALL – все ошибки,
- E_ERROR – критические ошибки,
- E_WARNING – предупреждения,
- E_PARSE – ошибки синтаксиса,
- E_NOTICE – замечания,
- E_CORE_ERROR – ошибки обработчика,
- E_CORE_WARNING – предупреждения обработчика,
- E_COMPILE_ERROR – ошибки компилятора,
- E_COMPILE_WARNING – предупреждения компилятора,
- E_USER_ERROR – ошибки пользователей,
- E_USER_WARNING – предупреждения пользователей,
- E_USER_NOTICE – уведомления пользователей.
Вывод ошибок в браузере
В htaccess
На рабочем проекте вывод ошибок лучше сделать только у авторизированного пользователя или в крайнем случаи по IP.
Список изменений
Версия | Описание |
---|---|
8.0.0 | Параметр destination и additional_headers теперь допускают значение null. |
Notes
error_log() is not binary safe. message will be truncated by null character.
message should not contain null character. Note that message may be sent to file, mail, syslog, etc. Use appropriate conversion/escape function, base64_encode() , rawurlencode() or addslashes() before calling error_log() .
Читайте также: