diff --git a/core/modules/dblog/dblog.module b/core/modules/dblog/dblog.module
index 06fef10..7ed0b69 100644
--- a/core/modules/dblog/dblog.module
+++ b/core/modules/dblog/dblog.module
@@ -61,23 +61,7 @@ function dblog_cron() {
   // Cleanup the watchdog table.
   $row_limit = \Drupal::config('dblog.settings')->get('row_limit');
 
-  // For row limit n, get the wid of the nth row in descending wid order.
-  // Counting the most recent n rows avoids issues with wid number sequences,
-  // e.g. auto_increment value > 1 or rows deleted directly from the table.
-  if ($row_limit > 0) {
-    $min_row = db_select('watchdog', 'w')
-      ->fields('w', array('wid'))
-      ->orderBy('wid', 'DESC')
-      ->range($row_limit - 1, 1)
-      ->execute()->fetchField();
-
-    // Delete all table entries older than the nth row, if nth row was found.
-    if ($min_row) {
-      db_delete('watchdog')
-        ->condition('wid', $min_row, '<')
-        ->execute();
-    }
-  }
+  \Drupal::service('logger.dblog')->deleteOldItems($row_limit);
 }
 
 /**
@@ -87,8 +71,7 @@ function dblog_cron() {
  *   List of uniquely defined database log message types.
  */
 function _dblog_get_message_types() {
-  return db_query('SELECT DISTINCT(type) FROM {watchdog} ORDER BY type')
-    ->fetchAllKeyed(0, 0);
+  return \Drupal::service('logger.dblog')->getTypes();
 }
 
 /**
diff --git a/core/modules/dblog/src/Controller/DbLogController.php b/core/modules/dblog/src/Controller/DbLogController.php
index 36ee204..6009176 100644
--- a/core/modules/dblog/src/Controller/DbLogController.php
+++ b/core/modules/dblog/src/Controller/DbLogController.php
@@ -6,12 +6,12 @@
 use Drupal\Component\Utility\Unicode;
 use Drupal\Component\Utility\Xss;
 use Drupal\Core\Controller\ControllerBase;
-use Drupal\Core\Database\Connection;
 use Drupal\Core\Datetime\DateFormatterInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Form\FormBuilderInterface;
 use Drupal\Core\Logger\RfcLogLevel;
 use Drupal\Core\Url;
+use Drupal\dblog\Logger\DbLogInterface;
 use Drupal\user\Entity\User;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
@@ -21,13 +21,6 @@
 class DbLogController extends ControllerBase {
 
   /**
-   * The database service.
-   *
-   * @var \Drupal\Core\Database\Connection
-   */
-  protected $database;
-
-  /**
    * The module handler service.
    *
    * @var \Drupal\Core\Extension\ModuleHandlerInterface
@@ -56,35 +49,42 @@ class DbLogController extends ControllerBase {
   protected $userStorage;
 
   /**
+   * The dblogger service.
+   *
+   * @var \Drupal\dblog\Logger\DbLogInterface
+   */
+  protected $dbLogger;
+
+  /**
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container) {
     return new static(
-      $container->get('database'),
       $container->get('module_handler'),
       $container->get('date.formatter'),
-      $container->get('form_builder')
+      $container->get('form_builder'),
+      $container->get('logger.dblog')
     );
   }
 
   /**
    * Constructs a DbLogController object.
    *
-   * @param \Drupal\Core\Database\Connection $database
-   *   A database connection.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   A module handler.
    * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
    *   The date formatter service.
    * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
    *   The form builder service.
+   * @param Drupal\dblog\Logger\DbLogInterface $db_logger
+   *   The dblogger service.
    */
-  public function __construct(Connection $database, ModuleHandlerInterface $module_handler, DateFormatterInterface $date_formatter, FormBuilderInterface $form_builder) {
-    $this->database = $database;
+  public function __construct(ModuleHandlerInterface $module_handler, DateFormatterInterface $date_formatter, FormBuilderInterface $form_builder, DbLogInterface $db_logger) {
     $this->moduleHandler = $module_handler;
     $this->dateFormatter = $date_formatter;
     $this->formBuilder = $form_builder;
     $this->userStorage = $this->entityManager()->getStorage('user');
+    $this->dbLogger = $db_logger;
   }
 
   /**
@@ -120,7 +120,6 @@ public static function getLogLevelClassMap() {
    */
   public function overview() {
 
-    $filter = $this->buildFilterQuery();
     $rows = array();
 
     $classes = static::getLogLevelClassMap();
@@ -151,28 +150,14 @@ public function overview() {
         'class' => array(RESPONSIVE_PRIORITY_LOW)),
     );
 
-    $query = $this->database->select('watchdog', 'w')
-      ->extend('\Drupal\Core\Database\Query\PagerSelectExtender')
-      ->extend('\Drupal\Core\Database\Query\TableSortExtender');
-    $query->fields('w', array(
-      'wid',
-      'uid',
-      'severity',
-      'type',
-      'timestamp',
-      'message',
-      'variables',
-      'link',
-    ));
-    $query->leftJoin('users_field_data', 'ufd', 'w.uid = ufd.uid');
-
-    if (!empty($filter['where'])) {
-      $query->where($filter['where'], $filter['args']);
-    }
-    $result = $query
-      ->limit(50)
-      ->orderByHeader($header)
-      ->execute();
+    $filter = $this->buildFilterQuery();
+    $sortingOptions = $header;
+
+    $result = $this->dbLogger->getCollection(
+      $filter,
+      $sortingOptions,
+      50
+    );
 
     foreach ($result as $dblog) {
       $message = $this->formatMessage($dblog);
@@ -237,12 +222,18 @@ public function overview() {
    */
   public function eventDetails($event_id) {
     $build = array();
-    if ($dblog = $this->database->query('SELECT w.*, u.uid FROM {watchdog} w LEFT JOIN {users} u ON u.uid = w.uid WHERE w.wid = :id', array(':id' => $event_id))->fetchObject()) {
+    $dblog = $this->dbLogger->get($event_id);
+    if (!empty($dblog)) {
       $severity = RfcLogLevel::getLevels();
       $message = $this->formatMessage($dblog);
       $username = array(
         '#theme' => 'username',
-        '#account' => $dblog->uid ? $this->userStorage->load($dblog->uid) : User::getAnonymousUser(),
+        '#account' => $this->userStorage->load($dblog->uid) ?: User::getAnonymousUser(),
+      );
+
+      $username = array(
+        '#theme' => 'username',
+        '#account' => $this->userStorage->load($dblog->uid) ?: User::getAnonymousUser(),
       );
       $rows = array(
         array(
@@ -303,7 +294,7 @@ public function eventDetails($event_id) {
    */
   protected function buildFilterQuery() {
     if (empty($_SESSION['dblog_overview_filter'])) {
-      return;
+      return [];
     }
 
     $this->moduleHandler->loadInclude('dblog', 'admin.inc');
@@ -378,29 +369,13 @@ public function formatMessage($row) {
    *   A build array in the format expected by drupal_render().
    */
   public function topLogMessages($type) {
+    $result = $this->dbLogger->topLogMessages($type);
+
     $header = array(
       array('data' => $this->t('Count'), 'field' => 'count', 'sort' => 'desc'),
       array('data' => $this->t('Message'), 'field' => 'message'),
     );
 
-    $count_query = $this->database->select('watchdog');
-    $count_query->addExpression('COUNT(DISTINCT(message))');
-    $count_query->condition('type', $type);
-
-    $query = $this->database->select('watchdog', 'w')
-      ->extend('\Drupal\Core\Database\Query\PagerSelectExtender')
-      ->extend('\Drupal\Core\Database\Query\TableSortExtender');
-    $query->addExpression('COUNT(wid)', 'count');
-    $query = $query
-      ->fields('w', array('message', 'variables'))
-      ->condition('w.type', $type)
-      ->groupBy('message')
-      ->groupBy('variables')
-      ->limit(30)
-      ->orderByHeader($header);
-    $query->setCountQuery($count_query);
-    $result = $query->execute();
-
     $rows = array();
     foreach ($result as $dblog) {
       if ($message = $this->formatMessage($dblog)) {
diff --git a/core/modules/dblog/src/Form/DblogClearLogConfirmForm.php b/core/modules/dblog/src/Form/DblogClearLogConfirmForm.php
index b1710df..2a2e5aa 100644
--- a/core/modules/dblog/src/Form/DblogClearLogConfirmForm.php
+++ b/core/modules/dblog/src/Form/DblogClearLogConfirmForm.php
@@ -2,10 +2,11 @@
 
 namespace Drupal\dblog\Form;
 
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Url;
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Form\ConfirmFormBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Url;
+use Drupal\dblog\Logger\DbLogInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -14,20 +15,20 @@
 class DblogClearLogConfirmForm extends ConfirmFormBase {
 
   /**
-   * The database connection.
+   * The dblogger service.
    *
-   * @var \Drupal\Core\Database\Connection
+   * @var \Drupal\dblog\Logger\DbLogInterface
    */
-  protected $connection;
+  protected $dbLogger;
 
   /**
    * Constructs a new DblogClearLogConfirmForm.
    *
-   * @param \Drupal\Core\Database\Connection $connection
-   *   The database connection.
+   * @param Drupal\dblog\Logger\DbLogInterface $db_logger
+   *   The dblogger service.
    */
-  public function __construct(Connection $connection) {
-    $this->connection = $connection;
+  public function __construct(DbLogInterface $db_logger) {
+    $this->dbLogger = $db_logger;
   }
 
   /**
@@ -35,7 +36,7 @@ public function __construct(Connection $connection) {
    */
   public static function create(ContainerInterface $container) {
     return new static(
-      $container->get('database')
+      $container->get('logger.dblog')
     );
   }
 
@@ -65,7 +66,7 @@ public function getCancelUrl() {
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
     $_SESSION['dblog_overview_filter'] = array();
-    $this->connection->truncate('watchdog')->execute();
+    $this->dbLogger->deleteAll();
     drupal_set_message($this->t('Database log cleared.'));
     $form_state->setRedirectUrl($this->getCancelUrl());
   }
diff --git a/core/modules/dblog/src/Logger/DbLog.php b/core/modules/dblog/src/Logger/DbLog.php
index af77be4..74fc20e 100644
--- a/core/modules/dblog/src/Logger/DbLog.php
+++ b/core/modules/dblog/src/Logger/DbLog.php
@@ -9,12 +9,11 @@
 use Drupal\Core\DependencyInjection\DependencySerializationTrait;
 use Drupal\Core\Logger\LogMessageParserInterface;
 use Drupal\Core\Logger\RfcLoggerTrait;
-use Psr\Log\LoggerInterface;
 
 /**
  * Logs events in the watchdog database table.
  */
-class DbLog implements LoggerInterface {
+class DbLog implements DbLogInterface {
   use RfcLoggerTrait;
   use DependencySerializationTrait;
 
@@ -109,4 +108,125 @@ public function log($level, $message, array $context = array()) {
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function get($id) {
+    return $this->connection
+          ->select('watchdog', 'w')
+          ->fields('w')
+          ->condition('wid', $id)
+          ->range(0, 1)
+          ->execute()
+          ->fetchObject();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCollection(array $filter, array $sorting, $limit) {
+    $query = $this->connection->select('watchdog', 'w')
+      ->extend('\Drupal\Core\Database\Query\PagerSelectExtender')
+      ->extend('\Drupal\Core\Database\Query\TableSortExtender');
+
+    $query->fields('w', array(
+      'wid',
+      'uid',
+      'severity',
+      'type',
+      'timestamp',
+      'message',
+      'variables',
+      'link',
+    ));
+
+    $query->leftJoin('users_field_data', 'ufd', 'w.uid = ufd.uid');
+
+    if (!empty($filter['where'])) {
+      $query->where($filter['where'], $filter['args']);
+    }
+
+    $result = $query
+      ->limit($limit)
+      ->orderByHeader($sorting)
+      ->execute();
+
+    return $result;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteAll() {
+    $this->connection->truncate('watchdog')->execute();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteOldItems($logs_to_keep) {
+    // For row limit n, get the wid of the nth row in descending wid order.
+    // Counting the most recent n rows avoids issues with wid number sequences,
+    // e.g. auto_increment value > 1 or rows deleted directly from the table.
+    if ($logs_to_keep > 0) {
+      $min_row = $this->connection
+        ->select('watchdog', 'w')
+        ->fields('w', ['wid'])
+        ->orderBy('wid', 'DESC')
+        ->range($logs_to_keep - 1, 1)
+        ->execute()
+        ->fetchField();
+
+      // Delete all table entries older than the nth row, if nth row was found.
+      if ($min_row) {
+        $this->connection
+          ->delete('watchdog')
+          ->condition('wid', $min_row, '<')
+          ->execute();
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTypes() {
+    return $this->connection
+      ->select('watchdog', 'w')
+      ->fields('w', ['type'])
+      ->distinct()
+      ->orderBy('type')
+      ->execute()
+      ->fetchAllKeyed(0, 0);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function topLogMessages($type) {
+    $count_query = $this->connection->select('watchdog');
+    $count_query->addExpression('COUNT(DISTINCT(message))');
+    $count_query->condition('type', $type);
+
+    $query = $this->connection->select('watchdog', 'w')
+      ->extend('\Drupal\Core\Database\Query\PagerSelectExtender')
+      ->extend('\Drupal\Core\Database\Query\TableSortExtender');
+    $query->addExpression('COUNT(wid)', 'count');
+
+    $header = array(
+      array('field' => 'count', 'sort' => 'desc'),
+      array('field' => 'message'),
+    );
+    $query = $query
+      ->fields('w', array('message', 'variables'))
+      ->condition('w.type', $type)
+      ->groupBy('message')
+      ->groupBy('variables')
+      ->limit(30)
+      ->orderByHeader($header);
+
+    $query->setCountQuery($count_query);
+    return $query->execute();
+  }
+
 }
diff --git a/core/modules/dblog/src/Logger/DbLogInterface.php b/core/modules/dblog/src/Logger/DbLogInterface.php
new file mode 100644
index 0000000..791d361
--- /dev/null
+++ b/core/modules/dblog/src/Logger/DbLogInterface.php
@@ -0,0 +1,70 @@
+<?php
+
+namespace Drupal\dblog\Logger;
+
+use Psr\Log\LoggerInterface;
+
+/**
+ * Logs events in the watchdog database table.
+ */
+interface DbLogInterface extends LoggerInterface {
+
+  /**
+   * Returns a watchdog log entry for the specified ID.
+   *
+   * @param int $id
+   *   The ID of the watchdog log entry.
+   *
+   * @return Object
+   *   The log entry for the given $id.
+   */
+  public function get($id);
+
+  /**
+   * Get a collection of logs.
+   *
+   * @param array $filter
+   *   An array of filters to filter the collection.
+   * @param array $sorting
+   *   An array of sorting options to sort the collection.
+   * @param int $limit
+   *   The number of logs to retrieve.
+   *
+   * @return array
+   *   A collection of log objects.
+   */
+  public function getCollection(array $filter, array $sorting, $limit);
+
+  /**
+   * Deletes all the logs.
+   */
+  public function deleteAll();
+
+  /**
+   * Deletes old log items.
+   *
+   * @param int $logs_to_keep
+   *   The number of items to keep.
+   */
+  public function deleteOldItems($logs_to_keep);
+
+  /**
+   * Gathers a list of uniquely defined log message types.
+   *
+   * @return array
+   *   List of uniquely defined database log message types.
+   */
+  public function getTypes();
+
+  /**
+   * Returns the most frequent log messages of a given event type.
+   *
+   * @param string $type
+   *   Type of database log events to display (e.g., 'search').
+   *
+   * @return array
+   *   An array of log entries.
+   */
+  public function topLogMessages($type);
+
+}
diff --git a/core/modules/dblog/src/Plugin/rest/resource/DBLogResource.php b/core/modules/dblog/src/Plugin/rest/resource/DBLogResource.php
index 4ac76f0..fa681e0 100644
--- a/core/modules/dblog/src/Plugin/rest/resource/DBLogResource.php
+++ b/core/modules/dblog/src/Plugin/rest/resource/DBLogResource.php
@@ -38,10 +38,10 @@ class DBLogResource extends ResourceBase {
    */
   public function get($id = NULL) {
     if ($id) {
-      $record = db_query("SELECT * FROM {watchdog} WHERE wid = :wid", array(':wid' => $id))
-        ->fetchAssoc();
+      $record = \Drupal::service('logger.dblog')->get($id);
+
       if (!empty($record)) {
-        return new ResourceResponse($record);
+        return new ResourceResponse((array) $record);
       }
 
       throw new NotFoundHttpException(t('Log entry with ID @id was not found', array('@id' => $id)));
