From c890ca9ad2ae66d3c875ffd4d927bdf90b3092ed Mon Sep 17 00:00:00 2001
From: Frederic G. MARAND <fgm@osinet.fr>
Date: Sun, 4 Nov 2012 13:07:19 +0100
Subject: [PATCH 2/2] Issue #1289536: Adopt Monolog for logging, on top of #1810664.

---
 core/includes/bootstrap.inc                        |   25 ++++--
 core/lib/Drupal/Core/CoreBundle.php                |    4 +
 core/modules/dblog/dblog.module                    |   22 -----
 .../modules/dblog/lib/Drupal/dblog/DblogBundle.php |   32 +++++++
 .../dblog/lib/Drupal/dblog/DblogHandler.php        |   41 +++++++++
 core/modules/syslog/config/syslog.settings.yml     |    3 +-
 .../syslog/lib/Drupal/syslog/SyslogBundle.php      |   39 +++++++++
 core/modules/syslog/syslog.install                 |    1 -
 core/modules/syslog/syslog.module                  |   56 -------------
 core/modules/system/system.api.php                 |   88 --------------------
 10 files changed, 136 insertions(+), 175 deletions(-)
 create mode 100755 core/modules/dblog/lib/Drupal/dblog/DblogBundle.php
 create mode 100755 core/modules/dblog/lib/Drupal/dblog/DblogHandler.php
 create mode 100755 core/modules/syslog/lib/Drupal/syslog/SyslogBundle.php

diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index eac2f97..3ee78df 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -12,6 +12,7 @@
 use Drupal\Core\Language\Language;
 use Drupal\Core\Lock\DatabaseLockBackend;
 use Drupal\Core\Lock\LockBackendInterface;
+use Monolog\Logger;
 
 /**
  * @file
@@ -1715,7 +1716,7 @@ function watchdog_exception($type, Exception $exception, $message = NULL, $varia
  *   A link to associate with the message.
  *
  * @see watchdog_severity_levels()
- * @see hook_watchdog()
+ * @see Monolog\Logger
  */
 function watchdog($type, $message, array $variables = array(), $severity = WATCHDOG_NOTICE, $link = NULL) {
   global $user, $base_root;
@@ -1733,7 +1734,6 @@ function watchdog($type, $message, array $variables = array(), $severity = WATCH
     // Prepare the fields to be logged
     $log_entry = array(
       'type'        => $type,
-      'message'     => $message,
       'variables'   => $variables,
       'severity'    => $severity,
       'link'        => $link,
@@ -1746,10 +1746,23 @@ function watchdog($type, $message, array $variables = array(), $severity = WATCH
       'timestamp'   => time(),
     );
 
-    // Call the logging hooks to log/process the message
-    foreach (module_implements('watchdog') as $module) {
-      module_invoke($module, 'watchdog', $log_entry);
-    }
+    // Translate the watchdog constant value to a Monolog value.
+    // @todo Switch the WATCHDOG constants to the straight Logger constants?
+    $level_map = array(
+      WATCHDOG_EMERGENCY => Logger::EMERGENCY,
+      WATCHDOG_ALERT     => Logger::ALERT,
+      WATCHDOG_CRITICAL  => Logger::CRITICAL,
+      WATCHDOG_ERROR     => Logger::ERROR,
+      WATCHDOG_WARNING   => Logger::WARNING,
+      WATCHDOG_NOTICE    => Logger::NOTICE,
+      WATCHDOG_INFO      => Logger::INFO,
+      WATCHDOG_DEBUG     => Logger::DEBUG,
+    );
+    // Invoking with an incorrect level is an actual error, so mark it as such.
+    $severity = isset($level_map[$severity]) ? $level_map[$severity] : Logger::ERROR;
+
+    // Add the record to the logger.
+    drupal_container()->get('logger')->addRecord($severity, $message, $log_entry);
 
     // It is critical that the semaphore is only cleared here, in the parent
     // watchdog() call (not outside the loop), to prevent recursive execution.
diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php
index f1d0046..801bcd4 100644
--- a/core/lib/Drupal/Core/CoreBundle.php
+++ b/core/lib/Drupal/Core/CoreBundle.php
@@ -126,6 +126,10 @@ public function build(ContainerBuilder $container) {
       ->setFactoryClass('Drupal\Core\ExceptionController')
       ->setFactoryMethod('getExceptionListener');
 
+    // Register services needed for the watchdog logging system.
+    $container->register('logger', 'Symfony\Bridge\Monolog\Logger')
+      ->addArgument('Drupal');
+
     $container->addCompilerPass(new RegisterMatchersPass());
     $container->addCompilerPass(new RegisterNestedMatchersPass());
     // Add a compiler pass for registering event subscribers.
diff --git a/core/modules/dblog/dblog.module b/core/modules/dblog/dblog.module
index 89efb57..95024a1 100644
--- a/core/modules/dblog/dblog.module
+++ b/core/modules/dblog/dblog.module
@@ -141,28 +141,6 @@ function _dblog_get_message_types() {
 }
 
 /**
- * Implements hook_watchdog().
- *
- * Note: Some values may be truncated to meet database column size restrictions.
- */
-function dblog_watchdog(array $log_entry) {
-  Database::getConnection('default', 'default')->insert('watchdog')
-    ->fields(array(
-      'uid' => $log_entry['uid'],
-      'type' => substr($log_entry['type'], 0, 64),
-      'message' => $log_entry['message'],
-      'variables' => serialize($log_entry['variables']),
-      'severity' => $log_entry['severity'],
-      'link' => substr($log_entry['link'], 0, 255),
-      'location' => $log_entry['request_uri'],
-      'referer' => $log_entry['referer'],
-      'hostname' => substr($log_entry['ip'], 0, 128),
-      'timestamp' => $log_entry['timestamp'],
-    ))
-    ->execute();
-}
-
-/**
  * Implements hook_form_FORM_ID_alter() for system_logging_settings().
  */
 function dblog_form_system_logging_settings_alter(&$form, $form_state) {
diff --git a/core/modules/dblog/lib/Drupal/dblog/DblogBundle.php b/core/modules/dblog/lib/Drupal/dblog/DblogBundle.php
new file mode 100755
index 0000000..e54b148
--- /dev/null
+++ b/core/modules/dblog/lib/Drupal/dblog/DblogBundle.php
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\dblog\DblogBundle.
+ */
+
+namespace Drupal\dblog;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\HttpKernel\Bundle\Bundle;
+
+/**
+ * Database Logging dependency injection container.
+ */
+class DblogBundle extends Bundle {
+
+  /**
+   * Overrides Symfony\Component\HttpKernel\Bundle\Bundle::build().
+   */
+  public function build(ContainerBuilder $container) {
+    // Register the database logging handler.
+    $container->register('logger.dbloghandler', 'Drupal\dblog\DblogHandler');
+
+    // Add the handler to the logging system.
+    $reference = new Reference('logger.dbloghandler');
+    $container->getDefinition('logger')
+      ->addMethodCall('pushHandler', array($reference));
+  }
+
+}
diff --git a/core/modules/dblog/lib/Drupal/dblog/DblogHandler.php b/core/modules/dblog/lib/Drupal/dblog/DblogHandler.php
new file mode 100755
index 0000000..c86e560
--- /dev/null
+++ b/core/modules/dblog/lib/Drupal/dblog/DblogHandler.php
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\dblog\DatabaseLoggingBundle.
+ */
+
+namespace Drupal\dblog;
+
+use Drupal\Core\Database\Database;
+
+use Monolog\Logger;
+use Monolog\Handler\AbstractProcessingHandler;
+
+/**
+ * Logs and records system events to the database.
+ *
+ * Note: Some values may be truncated to meet database column size restrictions.
+ */
+class DblogHandler extends AbstractProcessingHandler {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function write(array $record) {
+    Database::getConnection('default', 'default')->insert('watchdog')
+      ->fields(array(
+        'uid' => $record['context']['uid'],
+        'type' => substr($record['context']['type'], 0, 64),
+        'message' => $record['message'],
+        'variables' => serialize($record['context']['variables']),
+        'severity' => $record['context']['severity'],
+        'link' => substr($record['context']['link'], 0, 255),
+        'location' => $record['context']['request_uri'],
+        'referer' => $record['context']['referer'],
+        'hostname' => substr($record['context']['ip'], 0, 128),
+        'timestamp' => $record['context']['timestamp'],
+      ))
+      ->execute();
+  }
+}
diff --git a/core/modules/syslog/config/syslog.settings.yml b/core/modules/syslog/config/syslog.settings.yml
index 1aa5b90..7f17a98 100644
--- a/core/modules/syslog/config/syslog.settings.yml
+++ b/core/modules/syslog/config/syslog.settings.yml
@@ -1,3 +1,2 @@
 identity: drupal
-facility: ''
-format: '!base_url|!timestamp|!type|!ip|!request_uri|!referer|!uid|!link|!message'
+facility: 8  # Facility defaults to the value of LOG_USER.
diff --git a/core/modules/syslog/lib/Drupal/syslog/SyslogBundle.php b/core/modules/syslog/lib/Drupal/syslog/SyslogBundle.php
new file mode 100755
index 0000000..f29bb24
--- /dev/null
+++ b/core/modules/syslog/lib/Drupal/syslog/SyslogBundle.php
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\syslog\SyslogBundle.
+ */
+
+namespace Drupal\syslog;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\HttpKernel\Bundle\Bundle;
+
+/**
+ * Database Logging dependency injection container.
+ */
+class DatabaseLoggingBundle extends Bundle {
+
+  /**
+   * Overrides Symfony\Component\HttpKernel\Bundle\Bundle::build().
+   */
+  public function build(ContainerBuilder $container) {
+    // Register the database logging handler.
+    // @todo Retrieve values dynamically from config so that the services can be
+    // compiled correctly.
+    $config = config('syslog.settings');
+    $ident = $config->get('identity');
+    $facility = $config->get('facility');
+    $container->register('logger.sysloghandler', 'Monolog/Handler/SyslogHandler')
+      ->addArgument($ident)
+      ->addArgument('facility');
+
+    // Add the handler to the logging system.
+    $reference = new Reference('logger.sysloghandler');
+    $container->getDefinition('logger')
+      ->addMethodCall('pushHandler', array($reference));
+  }
+
+}
diff --git a/core/modules/syslog/syslog.install b/core/modules/syslog/syslog.install
index 5b2c41a..8c8b03e 100644
--- a/core/modules/syslog/syslog.install
+++ b/core/modules/syslog/syslog.install
@@ -26,7 +26,6 @@ function syslog_update_8000() {
   update_variables_to_config('syslog.settings', array(
     'syslog_identity' => 'identity',
     'syslog_facility' => 'facility',
-    'syslog_format' => 'format',
   ));
 }
 
diff --git a/core/modules/syslog/syslog.module b/core/modules/syslog/syslog.module
index 8af77c1..7426e13 100644
--- a/core/modules/syslog/syslog.module
+++ b/core/modules/syslog/syslog.module
@@ -5,22 +5,6 @@
  * Redirects logging messages to syslog.
  */
 
-if (defined('LOG_LOCAL0')) {
-  /**
-   * Sets the proper logging facility.
-   *
-   * Note that LOG_LOCAL0 through LOG_LOCAL7 are not available on Windows, so we
-   * check for availability. If LOG_LOCAL0 is defined by the PHP environment, we
-   * set that as the default; if not, we use LOG_USER.
-   *
-   * @see http://php.net/manual/function.syslog.php
-   */
-  define('DEFAULT_SYSLOG_FACILITY', LOG_LOCAL0);
-}
-else {
-  define('DEFAULT_SYSLOG_FACILITY', LOG_USER);
-}
-
 /**
  * Implements hook_help().
  */
@@ -62,12 +46,6 @@ function syslog_form_system_logging_settings_alter(&$form, &$form_state) {
       '#description'   => t('Depending on the system configuration, Syslog and other logging tools use this code to identify or filter messages from within the entire system log.') . $help,
      );
   }
-  $form['syslog_format'] = array(
-    '#type'          => 'textarea',
-    '#title'         => t('Syslog format'),
-    '#default_value' => $config->get('format'),
-    '#description'   => t('Specify the format of the syslog entry. Available variables are: <dl><dt><code>!base_url</code></dt><dd>Base URL of the site.</dd><dt><code>!timestamp</code></dt><dd>Unix timestamp of the log entry.</dd><dt><code>!type</code></dt><dd>The category to which this message belongs.</dd><dt><code>!ip</code></dt><dd>IP address of the user triggering the message.</dd><dt><code>!request_uri</code></dt><dd>The requested URI.</dd><dt><code>!referer</code></dt><dd>HTTP Referer if available.</dd><dt><code>!uid</code></dt><dd>User ID.</dd><dt><code>!link</code></dt><dd>A link to associate with the message.</dd><dt><code>!message</code></dt><dd>The message to store in the log.</dd></dl>'),
-  );
 
   $form['#submit'][] = 'syslog_logging_settings_submit';
 }
@@ -81,7 +59,6 @@ function syslog_logging_settings_submit($form, &$form_state) {
   config('syslog.settings')
     ->set('identity', $form_state['values']['syslog_identity'])
     ->set('facility', $form_state['values']['syslog_facility'])
-    ->set('format', $form_state['values']['syslog_format'])
     ->save();
 }
 
@@ -103,36 +80,3 @@ function syslog_facility_list() {
     LOG_LOCAL7 => 'LOG_LOCAL7',
   );
 }
-
-/**
- * Implements hook_watchdog().
- */
-function syslog_watchdog(array $log_entry) {
-  global $base_url;
-
-  $log_init = &drupal_static(__FUNCTION__, FALSE);
-  $config = config('syslog.settings');
-
-  if (!$log_init) {
-    $log_init = TRUE;
-    $facility = $config->get('facility');
-    if ($facility === '') {
-      $facility = defined('LOG_LOCAL0') ? LOG_LOCAL0 : LOG_USER;
-    }
-    openlog($config->get('identity'), LOG_NDELAY, $facility);
-  }
-
-  $message = strtr($config->get('format'), array(
-    '!base_url'    => $base_url,
-    '!timestamp'   => $log_entry['timestamp'],
-    '!type'        => $log_entry['type'],
-    '!ip'          => $log_entry['ip'],
-    '!request_uri' => $log_entry['request_uri'],
-    '!referer'     => $log_entry['referer'],
-    '!uid'         => $log_entry['uid'],
-    '!link'        => strip_tags($log_entry['link']),
-    '!message'     => strip_tags(!isset($log_entry['variables']) ? $log_entry['message'] : strtr($log_entry['message'], $log_entry['variables'])),
-  ));
-
-  syslog($log_entry['severity'], $message);
-}
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index 2d09534..c77127c 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -1968,94 +1968,6 @@ function hook_custom_theme() {
 }
 
 /**
- * Log an event message.
- *
- * This hook allows modules to route log events to custom destinations, such as
- * SMS, Email, pager, syslog, ...etc.
- *
- * @param array $log_entry
- *   An associative array containing the following keys:
- *   - type: The type of message for this entry.
- *   - user: The user object for the user who was logged in when the event
- *     happened.
- *   - uid: The user ID for the user who was logged in when the event happened.
- *   - request_uri: The request URI for the page the event happened in.
- *   - referer: The page that referred the user to the page where the event
- *     occurred.
- *   - ip: The IP address where the request for the page came from.
- *   - timestamp: The UNIX timestamp of the date/time the event occurred.
- *   - severity: The severity of the message; one of the following values as
- *     defined in @link http://www.faqs.org/rfcs/rfc3164.html RFC 3164: @endlink
- *     - WATCHDOG_EMERGENCY: Emergency, system is unusable.
- *     - WATCHDOG_ALERT: Alert, action must be taken immediately.
- *     - WATCHDOG_CRITICAL: Critical conditions.
- *     - WATCHDOG_ERROR: Error conditions.
- *     - WATCHDOG_WARNING: Warning conditions.
- *     - WATCHDOG_NOTICE: Normal but significant conditions.
- *     - WATCHDOG_INFO: Informational messages.
- *     - WATCHDOG_DEBUG: Debug-level messages.
- *   - link: An optional link provided by the module that called the watchdog()
- *     function.
- *   - message: The text of the message to be logged. Variables in the message
- *     are indicated by using placeholder strings alongside the variables
- *     argument to declare the value of the placeholders. See t() for
- *     documentation on how the message and variable parameters interact.
- *   - variables: An array of variables to be inserted into the message on
- *     display. Will be NULL or missing if a message is already translated or if
- *     the message is not possible to translate.
- */
-function hook_watchdog(array $log_entry) {
-  global $base_url;
-  $language_interface = language(LANGUAGE_TYPE_INTERFACE);
-
-  $severity_list = array(
-    WATCHDOG_EMERGENCY     => t('Emergency'),
-    WATCHDOG_ALERT     => t('Alert'),
-    WATCHDOG_CRITICAL     => t('Critical'),
-    WATCHDOG_ERROR       => t('Error'),
-    WATCHDOG_WARNING   => t('Warning'),
-    WATCHDOG_NOTICE    => t('Notice'),
-    WATCHDOG_INFO      => t('Info'),
-    WATCHDOG_DEBUG     => t('Debug'),
-  );
-
-  $to = 'someone@example.com';
-  $params = array();
-  $params['subject'] = t('[@site_name] @severity_desc: Alert from your web site', array(
-    '@site_name' => config('system.site')->get('name'),
-    '@severity_desc' => $severity_list[$log_entry['severity']],
-  ));
-
-  $params['message']  = "\nSite:         @base_url";
-  $params['message'] .= "\nSeverity:     (@severity) @severity_desc";
-  $params['message'] .= "\nTimestamp:    @timestamp";
-  $params['message'] .= "\nType:         @type";
-  $params['message'] .= "\nIP Address:   @ip";
-  $params['message'] .= "\nRequest URI:  @request_uri";
-  $params['message'] .= "\nReferrer URI: @referer_uri";
-  $params['message'] .= "\nUser:         (@uid) @name";
-  $params['message'] .= "\nLink:         @link";
-  $params['message'] .= "\nMessage:      \n\n@message";
-
-  $params['message'] = t($params['message'], array(
-    '@base_url'      => $base_url,
-    '@severity'      => $log_entry['severity'],
-    '@severity_desc' => $severity_list[$log_entry['severity']],
-    '@timestamp'     => format_date($log_entry['timestamp']),
-    '@type'          => $log_entry['type'],
-    '@ip'            => $log_entry['ip'],
-    '@request_uri'   => $log_entry['request_uri'],
-    '@referer_uri'   => $log_entry['referer'],
-    '@uid'           => $log_entry['uid'],
-    '@name'          => $log_entry['user']->name,
-    '@link'          => strip_tags($log_entry['link']),
-    '@message'       => strip_tags($log_entry['message']),
-  ));
-
-  drupal_mail('emaillog', 'entry', $to, $language_interface->langcode, $params);
-}
-
-/**
  * Prepare a message based on parameters; called from drupal_mail().
  *
  * Note that hook_mail(), unlike hook_mail_alter(), is only called on the
-- 
1.7.4.1

