You are here

class RulesDebugLoggerChannel in Rules 8.3

Logs rules log entries in the available loggers.

Hierarchy

Expanded class hierarchy of RulesDebugLoggerChannel

2 files declare their use of RulesDebugLoggerChannel
RulesDebugLoggerChannelTest.php in tests/src/Unit/RulesDebugLoggerChannelTest.php
TestDebugLogAction.php in tests/modules/rules_test/src/Plugin/RulesAction/TestDebugLogAction.php
1 string reference to 'RulesDebugLoggerChannel'
rules.services.yml in ./rules.services.yml
rules.services.yml
1 service uses RulesDebugLoggerChannel
logger.channel.rules_debug in ./rules.services.yml
Drupal\rules\Logger\RulesDebugLoggerChannel

File

src/Logger/RulesDebugLoggerChannel.php, line 13

Namespace

Drupal\rules\Logger
View source
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 = []) {

    // 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 = isset($context['element']) ? $context['element'] : NULL;
    $scope = isset($context['scope']) ? $context['scope'] : NULL;
    $path = isset($context['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--;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
LoggerChannel::$callDepth protected property Number of times LoggerChannel::log() has been called for a single message.
LoggerChannel::$channel protected property The name of the channel of this logger instance.
LoggerChannel::$currentUser protected property The current user object.
LoggerChannel::$levelTranslation protected property Map of PSR3 log constants to RFC 5424 log constants.
LoggerChannel::$loggers protected property An array of arrays of \Psr\Log\LoggerInterface keyed by priority.
LoggerChannel::$requestStack protected property The request stack object.
LoggerChannel::addLogger public function Adds a logger. Overrides LoggerChannelInterface::addLogger
LoggerChannel::MAX_CALL_DEPTH constant Maximum call depth to self::log() for a single log message.
LoggerChannel::setCurrentUser public function Sets the current user. Overrides LoggerChannelInterface::setCurrentUser
LoggerChannel::setLoggers public function Sets the loggers for this channel. Overrides LoggerChannelInterface::setLoggers
LoggerChannel::setRequestStack public function Sets the request stack. Overrides LoggerChannelInterface::setRequestStack
LoggerChannel::sortLoggers protected function Sorts loggers according to priority.
RulesDebugLoggerChannel::$config protected property A configuration object with rules settings.
RulesDebugLoggerChannel::$rulesDebugLog protected property The Rules debug log.
RulesDebugLoggerChannel::log public function 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… Overrides LoggerChannel::log
RulesDebugLoggerChannel::__construct public function Creates RulesDebugLoggerChannel object. Overrides LoggerChannel::__construct