diff --git a/core/modules/dblog/dblog.admin.inc b/core/modules/dblog/dblog.admin.inc
index ec0e5e9..7fe54f4 100644
--- a/core/modules/dblog/dblog.admin.inc
+++ b/core/modules/dblog/dblog.admin.inc
@@ -6,71 +6,6 @@
  */
 
 /**
- * Page callback: Shows the most frequent log messages of a given event type.
- *
- * Messages are not truncated on this page because events detailed herein do not
- * have links to a detailed view.
- *
- * @param string $type
- *   Type of database log events to display (e.g., 'search').
- *
- * @return array
- *   A build array in the format expected by drupal_render().
- *
- * @see dblog_menu()
- */
-function dblog_top($type) {
-
-  $header = array(
-    array('data' => t('Count'), 'field' => 'count', 'sort' => 'desc'),
-    array('data' => t('Message'), 'field' => 'message')
-  );
-  $count_query = db_select('watchdog');
-  $count_query->addExpression('COUNT(DISTINCT(message))');
-  $count_query->condition('type', $type);
-
-  $query = db_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) {
-    // Check for required properties.
-    if (isset($dblog->message) && isset($dblog->variables)) {
-      // Messages without variables or user specified text.
-      if ($dblog->variables === 'N;') {
-        $message = $dblog->message;
-      }
-      // Message to translate with injected variables.
-      else {
-        $message = t($dblog->message, unserialize($dblog->variables));
-      }
-    }
-    $rows[] = array($dblog->count, $message);
-  }
-
-  $build['dblog_top_table'] = array(
-    '#theme' => 'table',
-    '#header' => $header,
-    '#rows' => $rows,
-    '#empty' => t('No log messages available.'),
-  );
-  $build['dblog_top_pager'] = array('#theme' => 'pager');
-
-  return $build;
-}
-
-/**
  * Creates a list of database log administration filters that can be applied.
  *
  * @return array
diff --git a/core/modules/dblog/dblog.module b/core/modules/dblog/dblog.module
index 165d3cb..ad147dd 100644
--- a/core/modules/dblog/dblog.module
+++ b/core/modules/dblog/dblog.module
@@ -49,18 +49,12 @@ function dblog_menu() {
   $items['admin/reports/page-not-found'] = array(
     'title' => "Top 'page not found' errors",
     'description' => "View 'page not found' errors (404s).",
-    'page callback' => 'dblog_top',
-    'page arguments' => array('page not found'),
-    'access arguments' => array('access site reports'),
-    'file' => 'dblog.admin.inc',
+    'route_name' => 'dblog_top_404',
   );
   $items['admin/reports/access-denied'] = array(
     'title' => "Top 'access denied' errors",
     'description' => "View 'access denied' errors (403s).",
-    'page callback' => 'dblog_top',
-    'page arguments' => array('access denied'),
-    'access arguments' => array('access site reports'),
-    'file' => 'dblog.admin.inc',
+    'route_name' => 'dblog_top_403',
   );
   $items['admin/reports/event/%'] = array(
     'title' => 'Details',
@@ -71,10 +65,7 @@ function dblog_menu() {
     $items['admin/reports/search'] = array(
       'title' => 'Top search phrases',
       'description' => 'View most popular search phrases.',
-      'page callback' => 'dblog_top',
-      'page arguments' => array('search'),
-      'access arguments' => array('access site reports'),
-      'file' => 'dblog.admin.inc',
+      'route_name' => 'dblog_top_search',
     );
   }
 
diff --git a/core/modules/dblog/dblog.routing.yml b/core/modules/dblog/dblog.routing.yml
index 388348d..897224b 100644
--- a/core/modules/dblog/dblog.routing.yml
+++ b/core/modules/dblog/dblog.routing.yml
@@ -11,3 +11,27 @@ dblog_event:
     _content: '\Drupal\dblog\Controller\DbLogController::eventDetails'
   requirements:
     _permission: 'access site reports'
+
+dblog_top_403:
+  pattern: '/admin/reports/access-denied'
+  defaults:
+    _content: '\Drupal\dblog\Controller\DbLogController::topLogMessages'
+    type: 'access denied'
+  requirements:
+    _permission: 'access site reports'
+
+dblog_top_404:
+  pattern: '/admin/reports/page-not-found'
+  defaults:
+    _content: '\Drupal\dblog\Controller\DbLogController::topLogMessages'
+    type: 'page not found'
+  requirements:
+    _permission: 'access site reports'
+
+dblog_top_search:
+  pattern: '/admin/reports/search'
+  defaults:
+    _content: '\Drupal\dblog\Controller\DbLogController::topLogMessages'
+    type: 'search'
+  requirements:
+    _permission: 'access site reports'
diff --git a/core/modules/dblog/lib/Drupal/dblog/Controller/DbLogController.php b/core/modules/dblog/lib/Drupal/dblog/Controller/DbLogController.php
index 5ae1ad3..f2196ff 100644
--- a/core/modules/dblog/lib/Drupal/dblog/Controller/DbLogController.php
+++ b/core/modules/dblog/lib/Drupal/dblog/Controller/DbLogController.php
@@ -123,21 +123,21 @@ public function overview() {
       // Icon column.
       '',
       array(
-        'data' => t('Type'),
+        'data' => $this->t('Type'),
         'field' => 'w.type',
         'class' => array(RESPONSIVE_PRIORITY_MEDIUM)),
       array(
-        'data' => t('Date'),
+        'data' => $this->t('Date'),
         'field' => 'w.wid',
         'sort' => 'desc',
         'class' => array(RESPONSIVE_PRIORITY_LOW)),
-      t('Message'),
+      $this->t('Message'),
       array(
-        'data' => t('User'),
+        'data' => $this->t('User'),
         'field' => 'u.name',
         'class' => array(RESPONSIVE_PRIORITY_MEDIUM)),
       array(
-        'data' => t('Operations'),
+        'data' => $this->t('Operations'),
         'class' => array(RESPONSIVE_PRIORITY_LOW)),
     );
 
@@ -172,7 +172,7 @@ public function overview() {
         }
         // Message to translate with injected variables.
         else {
-          $message = t($dblog->message, unserialize($dblog->variables));
+          $message = $this->t($dblog->message, unserialize($dblog->variables));
         }
         if (isset($dblog->wid)) {
           // Truncate link_text to 56 chars of message.
@@ -188,7 +188,7 @@ public function overview() {
         'data' => array(
           // Cells.
           array('class' => array('icon')),
-          t($dblog->type),
+          $this->t($dblog->type),
           $this->date->format($dblog->timestamp, 'short'),
           $message,
           array('data' => $username),
@@ -204,7 +204,7 @@ public function overview() {
       '#header' => $header,
       '#rows' => $rows,
       '#attributes' => array('id' => 'admin-dblog', 'class' => array('admin-dblog')),
-      '#empty' => t('No log messages available.'),
+      '#empty' => $this->t('No log messages available.'),
     );
     $build['dblog_pager'] = array('#theme' => 'pager');
 
@@ -230,7 +230,7 @@ public function eventDetails($event_id) {
       // Check for required properties.
       if (isset($dblog->message) && isset($dblog->variables)) {
         // Inject variables into the message if required.
-        $message = $dblog->variables === 'N;' ? $dblog->message : t($dblog->message, unserialize($dblog->variables));
+        $message = $dblog->variables === 'N;' ? $dblog->message : $this->t($dblog->message, unserialize($dblog->variables));
       }
       $username = array(
         '#theme' => 'username',
@@ -238,39 +238,39 @@ public function eventDetails($event_id) {
       );
       $rows = array(
         array(
-          array('data' => t('Type'), 'header' => TRUE),
-          t($dblog->type),
+          array('data' => $this->t('Type'), 'header' => TRUE),
+          $this->t($dblog->type),
         ),
         array(
-          array('data' => t('Date'), 'header' => TRUE),
+          array('data' => $this->t('Date'), 'header' => TRUE),
           $this->date->format($dblog->timestamp, 'long'),
         ),
         array(
-          array('data' => t('User'), 'header' => TRUE),
+          array('data' => $this->t('User'), 'header' => TRUE),
           array('data' => $username),
         ),
         array(
-          array('data' => t('Location'), 'header' => TRUE),
+          array('data' => $this->t('Location'), 'header' => TRUE),
           l($dblog->location, $dblog->location),
         ),
         array(
-          array('data' => t('Referrer'), 'header' => TRUE),
+          array('data' => $this->t('Referrer'), 'header' => TRUE),
           l($dblog->referer, $dblog->referer),
         ),
         array(
-          array('data' => t('Message'), 'header' => TRUE),
+          array('data' => $this->t('Message'), 'header' => TRUE),
           $message,
         ),
         array(
-          array('data' => t('Severity'), 'header' => TRUE),
+          array('data' => $this->t('Severity'), 'header' => TRUE),
           $severity[$dblog->severity],
         ),
         array(
-          array('data' => t('Hostname'), 'header' => TRUE),
+          array('data' => $this->t('Hostname'), 'header' => TRUE),
           String::checkPlain($dblog->hostname),
         ),
         array(
-          array('data' => t('Operations'), 'header' => TRUE),
+          array('data' => $this->t('Operations'), 'header' => TRUE),
           $dblog->link,
         ),
       );
@@ -319,4 +319,70 @@ protected function buildFilterQuery() {
     );
   }
 
+  /**
+   * Shows the most frequent log messages of a given event type.
+   *
+   * Messages are not truncated on this page because events detailed herein do
+   * not have links to a detailed view.
+   *
+   * Use one of the above *Report() methods.
+   *
+   * @param string $type
+   *   Type of database log events to display (e.g., 'search').
+   *
+   * @return array
+   *   A build array in the format expected by drupal_render().
+   */
+  public function 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) {
+      // Check for required properties.
+      if (isset($dblog->message) && isset($dblog->variables)) {
+        // Messages without variables or user specified text.
+        if ($dblog->variables === 'N;') {
+          $message = $dblog->message;
+        }
+        // Message to translate with injected variables.
+        else {
+          $message = $this->t($dblog->message, unserialize($dblog->variables));
+        }
+      }
+      $rows[] = array($dblog->count, $message);
+    }
+
+    $build['dblog_top_table']  = array(
+      '#theme' => 'table',
+      '#header' => $header,
+      '#rows' => $rows,
+      '#empty' => $this->t('No log messages available.'),
+    );
+    $build['dblog_top_pager'] = array('#theme' => 'pager');
+
+    return $build;
+  }
+
 }
