Chris@0: connection = $connection; Chris@0: $this->parser = $parser; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function log($level, $message, array $context = []) { Chris@0: // Remove any backtraces since they may contain an unserializable variable. Chris@0: unset($context['backtrace']); Chris@0: Chris@17: // Convert PSR3-style messages to \Drupal\Component\Render\FormattableMarkup Chris@17: // style, so they can be translated too in runtime. Chris@0: $message_placeholders = $this->parser->parseMessagePlaceholders($message, $context); Chris@0: Chris@0: try { Chris@0: $this->connection Chris@0: ->insert('watchdog') Chris@0: ->fields([ Chris@0: 'uid' => $context['uid'], Chris@17: 'type' => mb_substr($context['channel'], 0, 64), Chris@0: 'message' => $message, Chris@0: 'variables' => serialize($message_placeholders), Chris@0: 'severity' => $level, Chris@0: 'link' => $context['link'], Chris@0: 'location' => $context['request_uri'], Chris@0: 'referer' => $context['referer'], Chris@17: 'hostname' => mb_substr($context['ip'], 0, 128), Chris@0: 'timestamp' => $context['timestamp'], Chris@0: ]) Chris@0: ->execute(); Chris@0: } Chris@0: catch (\Exception $e) { Chris@0: // When running Drupal on MySQL or MariaDB you can run into several errors Chris@0: // that corrupt the database connection. Some examples for these kind of Chris@0: // errors on the database layer are "1100 - Table 'xyz' was not locked Chris@0: // with LOCK TABLES" and "1153 - Got a packet bigger than Chris@0: // 'max_allowed_packet' bytes". If such an error happens, the MySQL server Chris@0: // invalidates the connection and answers all further requests in this Chris@0: // connection with "2006 - MySQL server had gone away". In that case the Chris@0: // insert statement above results in a database exception. To ensure that Chris@0: // the causal error is written to the log we try once to open a dedicated Chris@0: // connection and write again. Chris@0: if ( Chris@0: // Only handle database related exceptions. Chris@0: ($e instanceof DatabaseException || $e instanceof \PDOException) && Chris@0: // Avoid an endless loop of re-write attempts. Chris@0: $this->connection->getTarget() != self::DEDICATED_DBLOG_CONNECTION_TARGET Chris@0: ) { Chris@0: // Open a dedicated connection for logging. Chris@0: $key = $this->connection->getKey(); Chris@0: $info = Database::getConnectionInfo($key); Chris@0: Database::addConnectionInfo($key, self::DEDICATED_DBLOG_CONNECTION_TARGET, $info['default']); Chris@0: $this->connection = Database::getConnection(self::DEDICATED_DBLOG_CONNECTION_TARGET, $key); Chris@0: // Now try once to log the error again. Chris@0: $this->log($level, $message, $context); Chris@0: } Chris@0: else { Chris@0: throw $e; Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: }