Ведение журнала ошибок пользователей


Я создал этот код для регистрации Пользователя об ошибке, и я интересно, если есть что-то, что можно улучшить. Дело в том, что этот обработчик ошибок будет только ловить ошибки пользователя, созданного в-код по trigger_error(), и будет отображать, журнала, и/или электронной почты об ошибке, в зависимости от настроек конфигурации. Класс ведение журнала ошибок загружается функции автозагрузчика. Для производства всех уровнях ошибки будет равен 0, и обработчик ошибок пользователя не будет установлен, и класс никогда не будет загружен.

Файл конфигурации:

 // user error display level (change for production)
 define('LEV_USER_ERROR_DISPLAY_LEVEL', E_USER_ERROR);

 // user error logging level (change for production)
 define('LEV_USER_ERROR_LOG_LEVEL', E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE);

 // user error email alert level
 define('LEV_USER_ERROR_EMAIL_LEVEL', 0);

 // user error email address list (e.g. 'someone1@somewhere.com, someone2@somewhere.com')
 define('LEV_USER_ERROR_EMAIL_ADDRESSES', '');

Файл init:

   // set user error handler
   if (LEV_USER_ERROR_LOG_LEVEL | LEV_USER_ERROR_DISPLAY_LEVEL | LEV_USER_ERROR_EMAIL_LEVEL) {
    set_error_handler('lev_user_error_handler::user_error_handler', LEV_USER_ERROR_LOG_LEVEL | LEV_USER_ERROR_DISPLAY_LEVEL | LEV_USER_ERROR_EMAIL_LEVEL);
   }

Файл журнала класса ошибок:

<?php

 // user error handler
 class lev_user_error_handler {

  // user error handler
  public static function user_error_handler($error_level, $message, $file_name, $line_number) {
   if ((LEV_USER_ERROR_LOG_LEVEL | LEV_USER_ERROR_DISPLAY_LEVEL) == 0) return true;
   switch ($error_level) {
    case E_USER_ERROR:
     if (LEV_USER_ERROR_DISPLAY_LEVEL & E_USER_ERROR) {
      echo '[' . date('Y-m-d h:i:s') . '] User Level Error: "' . $message . '", File: "'.$file_name.'", Line: '.$line_number.'<br />';
     }
     if (LEV_USER_ERROR_LOG_LEVEL & E_USER_ERROR) {
      error_log('[' . date('Y-m-d h:i:s') . '] User Error: "' . $message . '", File: "'.$file_name.'", Line: '.$line_number.', Request: "' . $_SERVER['ORIG_PATH_INFO'] . "\"\n", 3, 'application/logs/user_error_log.txt');
     }
     if (LEV_USER_ERROR_EMAIL_LEVEL & E_USER_ERROR) {
      error_log('[' . date('Y-m-d h:i:s') . '] User Error: "' . $message . '", File: "'.$file_name.'", Line: '.$line_number.', Request: "' . $_SERVER['ORIG_PATH_INFO'] . '"', 1, LEV_USER_ERROR_EMAIL_ADDRESSES, 'From: no-reply@' . preg_replace('/^.+?\./i', '', $_SERVER['SERVER_NAME']));
     }
     die;
     break;
    case E_USER_WARNING:
     if (LEV_USER_ERROR_DISPLAY_LEVEL & E_USER_WARNING) {
      echo '[' . date('Y-m-d h:i:s') . '] User Level Warning: "' . $message . '", File: "'.$file_name.'", Line: '.$line_number.'<br />';
     }
     if (LEV_USER_ERROR_LOG_LEVEL & E_USER_WARNING) {
      error_log('[' . date('Y-m-d h:i:s') . '] User Warning: "' . $message . '", File: "'.$file_name.'", Line: '.$line_number.', Request: "' . $_SERVER['ORIG_PATH_INFO'] . "\"\n", 3, 'application/logs/user_error_log.txt');
     }
     if (LEV_USER_ERROR_EMAIL_LEVEL & E_USER_WARNING) {
      error_log('[' . date('Y-m-d h:i:s') . '] User Error: "' . $message . '", File: "'.$file_name.'", Line: '.$line_number.', Request: "' . $_SERVER['ORIG_PATH_INFO'] . '"', 1, LEV_USER_ERROR_EMAIL_ADDRESSES, 'From: no-reply@' . preg_replace('/^.+?\./i', '', $_SERVER['SERVER_NAME']));
     }
     break;
    case E_USER_NOTICE:
     if (LEV_USER_ERROR_DISPLAY_LEVEL & E_USER_NOTICE) {
      echo '[' . date('Y-m-d h:i:s') . '] User Level Notice: "' . $message . '", File: "'.$file_name.'", Line: '.$line_number.'<br />';
     }
     if (LEV_USER_ERROR_LOG_LEVEL & E_USER_NOTICE) {
      error_log('[' . date('Y-m-d h:i:s') . '] User Notice: "' . $message . '", File: "'.$file_name.'", Line: '.$line_number.', Request: "' . $_SERVER['ORIG_PATH_INFO'] . "\"\n", 3, 'application/logs/user_error_log.txt');
     }
     if (LEV_USER_ERROR_EMAIL_LEVEL & E_USER_NOTICE) {
      error_log('[' . date('Y-m-d h:i:s') . '] User Error: "' . $message . '", File: "'.$file_name.'", Line: '.$line_number.', Request: "' . $_SERVER['ORIG_PATH_INFO'] . '"', 1, LEV_USER_ERROR_EMAIL_ADDRESSES, 'From: no-reply@' . preg_replace('/^.+?\./i', '', $_SERVER['SERVER_NAME']));
     }
     break;
    default:
     // call PHP internal error handler
     return false;
   }
   // do not call PHP internal error handler
   return true;
  }
 }
?>


516
5
задан 27 января 2011 в 04:01 Источник Поделиться
Комментарии
2 ответа

Лично я думаю, что работа с 50% собственного и 50% код не очень хорошо, из-за таких вещей, как trigger_error не позволяет пользовательские биты для отправки.

Это, как говорится, если вы назвали свой класс ошибки и создали, чтобы оно было абстрактным, который реализует интерфейс регистратора (опционально) вы могли бы сделать больше с ним.

Создание пользовательских констант, таких как журнал,SHOW_ERROR,SEND_MAIL в сочетании с пользовательской статической функции будет лучшим вариантом, как делать вещи, такие как:

Error::Trigger("Cannot divide by 0", Error::LOG | Error::SHOW_ERROR);

делает больше смысла, чтобы иметь определенный контроль над ошибками.

Вот небольшой пример, как я хотел бы улучшить

abstract class Error
{
public const LOG = 0;
public const SEND_MAIL = 1;
public const SHOW_ERROR = 2;
/*...*/

public static function Monitor(){}; /*Used for set_error_handler*/

public static function Trigger($Message,$bits = Error::LOG | Error::SEND_MAIL,$Context = false)
{
if($bits & Error:LOG)
{
//Log it
}

if($bits & Error:SEND_MAIL)
{
//Send it
}

/*Lastly*/
if($bits & Error:LOG)
{
//Show it
}
}
}

тогда вы бы привязать монитор к error_reportng и назвать ошибки::триггер в зависимости от того, какой тип ошибки был вызван, или вы можете расширить класс и запустить статический метод родителя

class ErrorHandler extends Error
{
public fucntion Monitor(/*...*/)
{
parent::Trigger(/*...*/);
}
}

И разрешить свой класс для обработки всех ошибок, как вы потом иметь больше контроля над решение о том, что делать.

затем вы можете установить обработку ошибок по умолчанию сочетания опций, таких как:

 define("DEFAULT_ERROR_HANDLING",Error:log | Error::SEND_MAIL);

и изменить $бит в параметра разделе триггера до $бит = DEFAULT_ERROR_HANDLING

3
ответ дан 27 января 2011 в 06:01 Источник Поделиться

Предисловие:

Я не собираюсь говорить об альтернативах trigger_error сейчас.

Редактировать: кто-то другой сделал, отлично ! :)

О конфиге:

Я предполагаю, что те параметры, что вы используете в разработке ?

Если так: я бы хотел совет против этого. Вы всегда должны производить не менее бесплатный код E_NOTICE и только ведение журнала ошибок в файл не поможет вам достичь этого.

Почему ?

В E_NOTICE ошибки вы увидите в основном составляет $ASD-это неопределенная переменная. Что будет указывать вам на ошибки в вашем коде очень быстро и вам не придется думать о ("почему не получается, я поставил значение в функцию") или подобные проблемы, исходящие от опечатки. Может быть, ваш IDE предупреждает Вас о тех, Но пусть на PHP сделать это слишком.

Инит:

Обычно обработчик ошибок не статическую функцию. Я не уверен, что версия PHP выдаст предупреждение уровня e_strict.

Также "класс::функция" - это не лучший способ провести обратный звонок. (См. здесь для PHP обратные вызовы)

Вы могли бы хотеть использовать set_error_handler("класс", "функция");. Это поможет, если вы решите, что не хотите использовать статическую функцию, а объект, поскольку он работает точно так же set_error_handler($obj, а "функция");

Обработчик:

Вы повторяете

'[' . date('Y-m-d h:i:s') . '] User Error: "' . $message . '", File: "'.$file_name.'", Line: '.$line_number.'

много раз там. Это дополнительный метод. Это поможет вам, если вы хотите изменить название журнала или дату, или что-то подобное.

Также он помогает с отличием уже делать беттен 2 файла журнала.

Отображение ошибок ?

Вы должны никогда не отображать ошибки в производстве. Я использую ini_get("что display_errors") , чтобы выяснить, как сервер настроить и честь, что на все расходы.

Если вы не хотите, чтобы ошибки отображается в области развития (может быть, много AJAX-вызовы ?)

Посмотрите на поджигатель. Она позволяет увидеть ошибки, если вы получили плагин для Firefox установлен, не загромождая выход страниц.

1
ответ дан 27 января 2011 в 06:01 Источник Поделиться