RulesDebugLoggerChannel.php

Namespace

Drupal\rules\Logger

File

src/Logger/RulesDebugLoggerChannel.php

View source
<?php

namespace Drupal\rules\Logger;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Logger\LoggerChannel;
use Drupal\Core\Url;
use Psr\Log\LoggerInterface;

/**
 * Logs rules log entries in the available loggers.
 */
class RulesDebugLoggerChannel extends LoggerChannel {
  
  /**
   * The Rules debug log.
   *
   * @var \Psr\Log\LoggerInterface
   */
  protected $rulesDebugLog;
  
  /**
   * A configuration object with rules settings.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $config;
  
  /**
   * Creates RulesDebugLoggerChannel object.
   *
   * @param \Psr\Log\LoggerInterface $rules_debug_log
   *   The Rules debug log.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   Config factory instance.
   */
  public function __construct(LoggerInterface $rules_debug_log, ConfigFactoryInterface $config_factory) {
    parent::__construct('rules_debug');
    $this->rulesDebugLog = $rules_debug_log;
    $this->config = $config_factory;
  }
  
  /**
   * {@inheritdoc}
   *
   * Parent log() function is overridden to use microtime() for Rules execution
   * times and to prepare additional variables to pass to the logger. These
   * variables hold the extra call parameters used by RulesDebugLog for
   * backtracing. These are passed in via $context[] where they will be ignored
   * by any module that doesn't know about them ...
   */
  public function log($level, $message, array $context = []) : void {
    // Log debugging information only if the debug_log.enabled setting is
    // enabled. Otherwise exit immediately.
    $config = $this->config
      ->get('rules.settings');
    if (!$config->get('debug_log.enabled')) {
      return;
    }
    if ($this->callDepth == self::MAX_CALL_DEPTH) {
      return;
    }
    $this->callDepth++;
    // Merge in defaults normally provided by the parent LoggerChannel class.
    $context += [
      'channel' => $this->channel,
      'link' => '',
      'uid' => 0,
      'request_uri' => '',
      'referer' => '',
      'ip' => '',
      'timestamp' => microtime(TRUE),
    ];
    // Some context values are only available when in a request context.
    if ($this->requestStack && $request = $this->requestStack
      ->getCurrentRequest()) {
      $context['request_uri'] = $request->getUri();
      $context['referer'] = $request->headers
        ->get('Referer', '');
      $context['ip'] = $request->getClientIP();
      if ($this->currentUser) {
        $context['uid'] = $this->currentUser
          ->id();
      }
    }
    // Extract the Rules-specific defaults from $context.
    $element = $context['element'] ?? NULL;
    $scope = $context['scope'] ?? NULL;
    $path = $context['path'] ?? NULL;
    if (!empty($element)) {
      // Need to know if we're in a Reaction Rule or a Rules Component, and need
      // to be able to get a reference to that specific entity. For now we just
      // assume Reaction Rule until we know how to do this better.
      $path = $element->getRoot()
        ->getLabel() ? Url::fromRoute('entity.rules_reaction_rule.edit_form.expression.edit', [
        'rules_reaction_rule' => $element->getRoot()
          ->getPluginId(),
        'uuid' => $element->getUuid(),
      ])
        ->toString() : NULL;
    }
    // Pack $element, $scope, and $path into the context array so as to forward
    // them to the logger.channel.rules_debug logger channel for logging.
    $context += [
      'element' => $element,
      'scope' => $scope,
      'path' => $path,
    ];
    // Now, write the logs to the RulesDebugLog to store in memory. This is the
    // principal reason for this class! Keep the array structure we used in D7
    // so we don't have to re-write the theming functions and JavaScript too
    // much. We added keys for D8 so we don't have to guess the contents of the
    // array elements from their order index.
    $rfc_level = $level;
    if (is_string($level)) {
      // Convert to integer equivalent for consistency with RFC 5424.
      $rfc_level = $this->levelTranslation[$level];
    }
    // A lesser RFC level is MORE severe, so we want to test if the RFC level
    // of the message is LESS than or equal to the threshold level setting.
    if ($this->levelTranslation[$config->get('debug_log.log_level')] >= $rfc_level) {
      $this->rulesDebugLog
        ->log($level, $message, $context);
      // Support any loggers added through the API, just because we can (most
      // of this is inherited from parent LoggerChannel class).
      foreach ($this->sortLoggers() as $logger) {
        $logger->log($rfc_level, $message, $context);
      }
    }
    $this->callDepth--;
  }

}

Classes

Title Deprecated Summary
RulesDebugLoggerChannel Logs rules log entries in the available loggers.