Watchdog_mail - системные журналы на электронную почту

Прислано: seaji

ср, 14/05/2008 - 14:56

Другие статьи по теме:

Привет всем!
Вчера случайно натолкнулся на системную функцию watchdog_overview() и решил ее расковырять.
Что делает эта функция? Она подготавливает и выводит список системных сообщений на странице: http://ваш_сайт/admin/logs/watchdog
Я подумал, что было бы клево, если бы этот список системных сообщений отсылался бы мне на электронную почту при ежедневном выполнении заданий крона.
Я давно мечтал о такой функциональности так как сейчас уже у меня семь сайтов, и следить за всеми этими сайтами я просто не могу физически.
Пробовал искать модули, но ничего так и не нашел.
Есть модули для D6, но там уже отдельная тема. В Drupal 6 вы можете назначить для каждого типа события свое уведомление.
Скажем, если это "замечание" - то никаких действий не производится, если это "предупреждение" - высылается письмо, если это "ошибка" - высылается SMS сообщение на ваш номер.
Вот так вот в D6, но до него еще далеко, а работать нужно сейчас.

Итак, что нужно делать для установки.
1. Скачать архив, прикрепленный к этому посту.
2. Этот архив содержит два файла "watchdog_mail.php" и "cron.php"
3. Нужно поменять параметры в начале файла "watchdog_mail.php", там задается отправитель, получатель и тема письма.
4. Закачать эти два файла в корневую папку установки Друпала.
5. Настроить крон и наслаждаться.

Известные проблемы: ни как не получается использовать тег "style" в теле письма для раскрашивания разных типов сообщений.

Прикрепленный файлРазмер
watchdog_mail.zip2.05 кб

Комментарии


Настройки просмотра комментариев

Выберите нужный метод показа комментариев и нажмите "Применить"
Опубликовано seaji в ср, 14/05/2008 - 15:06.

Для тех, кому интересен код, но архивы качать лень, вот он:

<?php
/**************************************
 *   Variables                        *
 **************************************/
$mail_to'your-name@example.com'// Ваш адрес электронной почты
$mail_subject  '['.$_SERVER['HTTP_HOST'].'] report'// Тема письма '[www.example.com] report'
// $overview_period = time() - 86400;
$last_day time() - 86400// Сутки от теперешнего момента.
$overview_period variable_get('cron_last'$last_day); // период обзора - с последнего запуска крона или за сутки.
$mailkey 'watchdog_overview_mail';
$headers = array (
    
'From' => 'name@from.com',
    
'Reply-To' => 'name@from.com',
    
'MIME-Version' => '1.0',
    
'Content-Type' => 'text/html; charset=UTF-8',
    
'Content-Transfer-Encoding' => 'quoted-printable' );
/**********************************************************
 *   Override of the system watchdog_overview() function  *
 **********************************************************/
function watchdog_overview_mail_body($overview_period) {
  
$output "\n\n<html><head><title></title></head><body>";

  
$classes = array(WATCHDOG_NOTICE => 'watchdog-notice'WATCHDOG_WARNING => 'watchdog-warning'WATCHDOG_ERROR => 'watchdog-error');
  
$header = array(
    array(
'data' => t('Type')),
    array(
'data' => t('Date')),
    array(
'data' => t('Message')),
    array(
'data' => t('User')),
    array(
'data' => t('Operations'))
  );

  
$sql "SELECT w.wid, w.uid, w.severity, w.type, w.timestamp, w.message, w.link, u.name FROM {watchdog} w INNER JOIN {users} u ON w.uid = u.uid";
  
$result db_query($sql ." WHERE w.timestamp > '%d' ORDER BY w.wid desc"$overview_period);

  while (
$watchdog db_fetch_object($result)) {
    
$rows[] = array('data' =>
      array(
        
// Cells
        
t($watchdog->type),
        
format_date($watchdog->timestamp'small'),
        
l(truncate_utf8($watchdog->message80TRUETRUE), 'http://'.$_SERVER['HTTP_HOST'].'/admin/logs/event/'$watchdog->wid, array(), NULLNULLFALSETRUE),
        
theme('username'$watchdog),
        
$watchdog->link,
      ),
      
// Attributes for tr
      
'class' => 'watchdog-'preg_replace('/[^a-z]/i''-'$watchdog->type) .' '$classes[$watchdog->severity],
      
'style' => 'font-size: 8pt; border: 1px solid #DDDDDD;'
    
);
  }

  if (!
$rows) {
    
$rows[] = array(array('data' => t('No log messages available.'), 'colspan' => 5));
  }
  
$output .= format_date(time(), $type 'large').'  '.$_SERVER['HTTP_HOST'].'<br/ >';
  
$output .= '
  <style>
  tr.watchdog-notice td  { background-color:#FFFFFF; }
  tr.watchdog-warning td { background-color:#FCFDBD; }
  tr.watchdog-error td   { background-color:#FFDAD2; }
  tr.watchdog-cron td    { background-color:#D2F4FF; }
  tr.watchdog-content td { background-color:#CBCBFA; }
  tr.watchdog-user td    { background-color:#EFEFDE; }
  </style>'
;
  
$output .= theme('table'$header$rows, array('cellpadding' => '2px'));
  
$output .= '</body></html>';
  return 
$output;
}

$mail_body .= watchdog_overview_mail_body($overview_period);

// Это место под вопросом с точки зрения того, что лучше использовать imap_8bit() или wordwrap()
$mail_body imap_8bit($mail_body);
// $mail_body = wordwrap($mail_body, 70);

//  Говорят, что письма с незакодированны заголовком считаются потенциально опасными.
//  Но реализовывать это я не стал.
// $mail_subject = mb_encode_mimeheader($mail_subject,'UTF-8');

drupal_mail($mailkey$mail_to$mail_subject$mail_body$from NULL$headers);
?>


Опубликовано player в ср, 14/05/2008 - 15:58.

гуд.


Опубликовано Valeratal в ср, 14/05/2008 - 19:09.

спасибо


Опубликовано VladSavitsky в пт, 16/05/2008 - 08:05.

Спасибо. Очень нужный функционал.


Опубликовано бухучет (гостевой логин) в пн, 19/05/2008 - 12:45.

Спасибо. Было интересно почитать.
Артем


Опубликовано seaji в вт, 20/05/2008 - 10:26.

UPD:
В процессе тестов обнаружено три вещи.
1. Цвет строчек разного типа сообщений можно задать с помощью атрибута 'style' элемента 'tr'
2. Запись о работе самого крона не появляется в логах т.к. время этой записи равняется времени отсечки запроса.
3. Дополнительные ссылки типа "просмотреть" и "изменить" имеют относительный вид, что для почтового сообщения - не корректно.

Новая версия, уже с учетом первых двух пунктов.

<?php
/**************************************
 *   Variables                        *
 **************************************/
$mail_to'you_name@example.com';  //  Ваш адрес, куда слать письма
$mail_subject  '['.$_SERVER['HTTP_HOST'].'] report'// Тема письма
$last_day time() - 86400// Сутки от теперешнего момента.
$overview_period variable_get('cron_last'$last_day); // период обзора - с последнего запуска крона или за сутки.
$overview_period $overview_period 2;  // берем двух секундный запас с момента последнего запуска крона
$mailkey 'watchdog_overview_mail';
$headers = array (
    
'From' => 'from@example.com',
    
'Reply-To' => 'from@example.com',
    
'MIME-Version' => '1.0',
    
'Content-Type' => 'text/html; charset=UTF-8',
    
'Content-Transfer-Encoding' => 'quoted-printable' );

function 
watchdog_overview_mail_body($overview_period) {
  
$output "\n\n<html><head><title></title></head><body>";  // <html><head>\r\n  <title>$mail_subject</title>\r\n

  
$classes = array(WATCHDOG_NOTICE => 'watchdog-notice'WATCHDOG_WARNING => 'watchdog-warning'WATCHDOG_ERROR => 'watchdog-error');
  
$header = array(
    array(
'data' => 'Тип'),
    array(
'data' => '&nbsp;Дата/Время&nbsp;'),
    array(
'data' => 'Сообщение'),
    array(
'data' => 'Пользователь'),
    array(
'data' => 'Действия')
  );

  
$sql "SELECT w.wid, w.uid, w.severity, w.type, w.timestamp, w.message, w.link, u.name FROM {watchdog} w INNER JOIN {users} u ON w.uid = u.uid";
  
$result db_query($sql ." WHERE w.timestamp > '%d' ORDER BY w.wid desc"$overview_period);

  while (
$watchdog db_fetch_object($result)) {
    switch (
$watchdog->severity) {
      case 
WATCHDOG_NOTICE:
         
$color '#D1FFD6';  // цвет замечания
        
break;
      case 
WATCHDOG_WARNING:
         
$color '#FFFFD8';  //  цвет предупреждения
        
break;
      case 
WATCHDOG_ERROR:
         
$color '#FFB7B7';  //  цвет ошибки
        
break;
    }
    switch (
$watchdog->type) {
      case 
'user':
         
$color '#EFEFDE';  //  цвет для типа "пользователь"
        
break;
      case 
'access-denied':
         
$color '#FCF2BA';  //  цвет для типа "доступ запрещен"
        
break;
      case 
'php':
         
$color '#EDADAF';   //  цвет для типа "PHP"
        
break;
      case 
'content':
         
$color '#C6CBFF';    //  цвет для типа "содержимое"
        
break;
    }
    
$rows[] = array('data' =>
      array(
        
// Cells
        
t($watchdog->type),
        
format_date($watchdog->timestamp'small'),
        
l(truncate_utf8($watchdog->message80TRUETRUE), 'http://'.$_SERVER['HTTP_HOST'].'/admin/logs/event/'$watchdog->wid, array(), NULLNULLFALSETRUE),
        
theme('username'$watchdog),
        
$watchdog->link,
      ),
      
// Attributes for tr
      
'class' => 'watchdog-'preg_replace('/[^a-z]/i''-'$watchdog->type) .' '$classes[$watchdog->severity],
      
'style' => 'font-size: 8pt; border: 1px solid #DDDDDD; background-color: '.$color
    
);
  }

  if (!
$rows) {
    
$rows[] = array(array('data' => t('No log messages available.'), 'colspan' => 5));
  }
  
$output .= format_date(time(), $type 'large').'  <a href="http://>'.$_SERVER['HTTP_HOST'].'">'.$_SERVER['HTTP_HOST'].'</a><br/ >';
  
$output .= theme('table'$header$rows, array('cellpadding' => '2px'));
  
$output .= '</body></html>';
  return 
$output;
}

$mail_body .= watchdog_overview_mail_body($overview_period);
$mail_body imap_8bit($mail_body);
// $mail_body = wordwrap($mail_body, 70);

// $mail_subject = mb_encode_mimeheader($mail_subject,'UTF-8');

drupal_mail($mailkey$mail_to$mail_subject$mail_body$from NULL$headers);
?>


Опубликовано seaji в чт, 05/06/2008 - 10:21.

Еще одно обновление.
В результате тестов этого скрипта выяснилось еще две вещи.
1. Не хорошо сначала высылать письмо, потом отрабатывать крон. Во первых мы узнает отработал или нет крон сегодня только через сутки, во вторых на некоторых моих сайтах крон вообще перестал запускаться. Следовательно тут идет преимущество крона. Он должен быть выполнен первым, а затем уже можно и письмо выслать.
В связи с этим предлагаю включать watchdog_mail.php в конце файла cron.php

<?php
include_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
drupal_cron_run();

include_once 
'watchdog_mail.php';
?>

2. Не хорошо высылать письмо при каждом прогоне крона. У меня на одном сайте крон выполняется каждые шесть часов. Соответственно я имею четыре письма в день и в каждом письме максимум три сообщения, а чаще всего - ни одного.
Еще на другом сайте у меня уже третий день крон просто зависает и в каждом новом письме дублируются записи прошлых дней.
Значит нужно ввести новую переменную, в которую фиксировать время отправки письма. Сверяясь с этой переменной можно выбирать события с момента последней отправки письма (а не отработки крона) и ограничить отправку до 1 раза в сутки.
<?php
/**************************************
 *   Variables                        *
 **************************************/
$mail_to'you@example.com';
$mail_subject  '['.$_SERVER['HTTP_HOST'].'] report';
$time time();
$last_day $time 86400// Сутки от теперешнего момента.
$overview_period variable_get('last_watchdog_mail'$last_day); // период обзора - с последнего отправленного письма или за сутки.
$overview_period $overview_period 2// Даем отступ в две секунды
$mailkey 'watchdog_overview_mail';
$headers = array (
    
'From' => 'name@example.com',
    
'Reply-To' => 'name@example.com',
    
'MIME-Version' => '1.0',
    
'Content-Type' => 'text/html; charset=UTF-8',
    
'Content-Transfer-Encoding' => 'quoted-printable' );

function 
watchdog_overview_mail_body($overview_period) {
  
$output "\n\n<html><head><title></title></head><body>";  // <html><head>\r\n  <title>$mail_subject</title>\r\n

  
$classes = array(WATCHDOG_NOTICE => 'watchdog-notice'WATCHDOG_WARNING => 'watchdog-warning'WATCHDOG_ERROR => 'watchdog-error');
  
$header = array(
    array(
'data' => 'Тип'),
    array(
'data' => '&nbsp;Дата/Время&nbsp;'),
    array(
'data' => 'Сообщение'),
    array(
'data' => 'Пользователь'),
    array(
'data' => 'Действия')
  );

  
$sql "SELECT w.wid, w.uid, w.severity, w.type, w.timestamp, w.message, w.link, u.name FROM {watchdog} w INNER JOIN {users} u ON w.uid = u.uid";
  
$result db_query($sql ." WHERE w.timestamp > '%d' ORDER BY w.wid desc"$overview_period);

  while (
$watchdog db_fetch_object($result)) {
    switch (
$watchdog->severity) {
      case 
WATCHDOG_NOTICE:
         
$color '#D1FFD6';
        break;
      case 
WATCHDOG_WARNING:
         
$color '#FFFFD8';
        break;
      case 
WATCHDOG_ERROR:
         
$color '#FFB7B7';
        break;
    }
    switch (
$watchdog->type) {
      case 
'user':
         
$color '#EFEFDE';
        break;
      case 
'access-denied':
         
$color '#FCF2BA';
        break;
      case 
'php':
         
$color '#EDADAF';
        break;
      case 
'content':
         
$color '#C6CBFF';
        break;
    }
    
$rows[] = array('data' =>
      array(
        
// Cells
        
t($watchdog->type),
        
format_date($watchdog->timestamp'small'),
        
l(truncate_utf8($watchdog->message80TRUETRUE), 'http://'.$_SERVER['HTTP_HOST'].'/admin/logs/event/'$watchdog->wid, array(), NULLNULLFALSETRUE),
        
theme('username'$watchdog),
        
$watchdog->link,
      ),
      
// Attributes for tr
      
'class' => 'watchdog-'preg_replace('/[^a-z]/i''-'$watchdog->type) .' '$classes[$watchdog->severity],
      
'style' => 'font-size: 8pt; border: 1px solid #DDDDDD; background-color: '.$color
    
);
  }

  if (!
$rows) {
    
$rows[] = array(array('data' => t('No log messages available.'), 'colspan' => 5));
  }
  
$output .= format_date(time(), $type 'large').'  <a href="http://'.$_SERVER['HTTP_HOST'].'">'.$_SERVER['HTTP_HOST'].'</a><br/ >';
  
$output .= theme('table'$header$rows, array('cellpadding' => '2px'));
  
$output .= '</body></html>';
  return 
$output;
}

$test_time $time $overview_period;  // Проверка условия для отправки письма только раз в сутки.
if ($test_time>86400) {
$mail_body .= watchdog_overview_mail_body($overview_period);
$mail_body imap_8bit($mail_body);
// $mail_body = wordwrap($mail_body, 70);
// $mail_subject = mb_encode_mimeheader($mail_subject,'UTF-8');

  
if (drupal_mail($mailkey$mail_to$mail_subject$mail_body$from NULL$headers)) {
    
variable_set('last_watchdog_mail'$time);
  }
}
?>


Опубликовано seaji в вс, 08/06/2008 - 11:06.

У меня на одном хостинге не стала работать функция $mail_body = imap_8bit($mail_body);
В этом случае используйте $mail_body = wordwrap($mail_body, 70);


Опубликовано gematolog (гостевой логин) в вт, 10/06/2008 - 05:33.

Отличный функционал. Спасиб!


Опубликовано RoSk0 в пт, 01/08/2008 - 10:05.

классная штука!
Вот если б еще и смс слало... ;)


Опубликовано seaji в сб, 02/08/2008 - 09:26.

Для шестого Друпала есть модули, которые могут слать или письма или СМС для разных типов событий.


Опубликовано relogger в ср, 14/01/2009 - 08:52.

спасибо!


Новое на сайте