diff --git a/core/modules/dblog/dblog.module b/core/modules/dblog/dblog.module
index 202cfcf..0802420 100644
--- a/core/modules/dblog/dblog.module
+++ b/core/modules/dblog/dblog.module
@@ -11,6 +11,7 @@
  * @see watchdog()
  */
 
+use Drupal\Component\Utility\MapArray;
 use Drupal\Core\Database\Database;
 
 /**
@@ -134,7 +135,7 @@ function _dblog_get_message_types() {
     $types[] = $object->type;
   }
 
-  return $types;
+  return MapArray::copyValuesToKeys($types);
 }
 
 /**
diff --git a/core/modules/dblog/dblog.views.inc b/core/modules/dblog/dblog.views.inc
new file mode 100644
index 0000000..2b48e3e
--- /dev/null
+++ b/core/modules/dblog/dblog.views.inc
@@ -0,0 +1,223 @@
+<?php
+
+/**
+ * @file
+ * Provide views data for dblog.module.
+ *
+ * @ingroup views_module_ids
+ */
+
+/**
+ * Implements hook_views_data().
+ */
+function dblog_views_data() {
+  $data = array();
+
+  $data['watchdog']['table']['group'] = t('Watchdog');
+
+  $data['watchdog']['table']['base'] = array(
+    'field' => 'wid',
+    'title' => t('Watchdog events'),
+    'help' => t('Contains a list of log entries.'),
+  );
+
+  $data['watchdog']['wid'] = array(
+    'title' => t('WID'),
+    'help' => t('Unique watchdog event ID.'),
+    'field' => array(
+      'id' => 'numeric',
+    ),
+    'filter' => array(
+      'id' => 'numeric',
+    ),
+    'argument' => array(
+      'id' => 'numeric',
+    ),
+    'sort' => array(
+      'id' => 'standard',
+    ),
+    'search' => array(
+      'id' => 'standard',
+    ),
+  );
+
+  $data['watchdog']['uid'] = array(
+    'title' => t('UID'),
+    'help' => t('The user ID of the user on which the log entry was written..'),
+    'field' => array(
+      'id' => 'numeric',
+    ),
+    'filter' => array(
+      'id' => 'numeric',
+    ),
+    'argument' => array(
+      'id' => 'numeric',
+    ),
+    'search' => array(
+      'id' => 'standard',
+    ),
+    'relationship' => array(
+      'title' => t('User'),
+      'help' => t('The user on which the log entry as written.'),
+      'base' => 'users',
+      'base field' => 'uid',
+      'id' => 'standard',
+    ),
+  );
+
+  $data['watchdog']['type'] = array(
+    'title' => t('Type'),
+    'help' => t('The of the log entry, for example "user" or "page not found.".'),
+    'field' => array(
+      'id' => 'standard',
+    ),
+    'argument' => array(
+      'id' => 'string',
+    ),
+    'filter' => array(
+      'id' => 'in_operator',
+      'options callback' => '_dblog_get_message_types',
+    ),
+    'sort' => array(
+      'id' => 'standard',
+    ),
+  );
+
+  $data['watchdog']['message'] = array(
+    'title' => t('Message'),
+    'help' => t('The actual message of the log entry.'),
+    'field' => array(
+      'id' => 'dblog_message',
+    ),
+    'argument' => array(
+      'id' => 'string',
+    ),
+    'filter' => array(
+      'id' => 'string',
+    ),
+    'sort' => array(
+      'id' => 'standard',
+    ),
+  );
+
+  $data['watchdog']['variables'] = array(
+    'title' => t('Variables'),
+    'help' => t('The variables of the log entry in a serialized format.'),
+    'field' => array(
+      'id' => 'serialized',
+      'click sortable' => FALSE,
+    ),
+    'argument' => array(
+      'id' => 'string',
+    ),
+    'filter' => array(
+      'id' => 'string',
+    ),
+    'sort' => array(
+      'id' => 'standard',
+    ),
+  );
+
+  $data['watchdog']['severity'] = array(
+    'title' => t('Severity level'),
+    'help' => t('The severity level of the event; ranges from 0 (Emergency) to 7 (Debug).'),
+    'field' => array(
+      'id' => 'machine_name',
+      'options callback' => 'Drupal\dblog\Controller\DbLogController::getLogLevelClassMap',
+    ),
+    'filter' => array(
+      'id' => 'in_operator',
+      'options callback' => 'Drupal\dblog\Controller\DbLogController::getLogLevelClassMap',
+    ),
+    'sort' => array(
+      'id' => 'standard',
+    ),
+  );
+
+  $data['watchdog']['link'] = array(
+    'title' => t('Operations'),
+    'help' => t('Operation links for the event.'),
+    'field' => array(
+      'id' => 'dblog_operations',
+    ),
+    'argument' => array(
+      'id' => 'string',
+    ),
+    'filter' => array(
+      'id' => 'string',
+    ),
+    'sort' => array(
+      'id' => 'standard',
+    ),
+  );
+
+  $data['watchdog']['location'] = array(
+    'title' => t('Location'),
+    'help' => t('URL of the origin of the event.'),
+    'field' => array(
+      'id' => 'standard',
+    ),
+    'argument' => array(
+      'id' => 'string',
+    ),
+    'filter' => array(
+      'id' => 'string',
+    ),
+    'sort' => array(
+      'id' => 'standard',
+    ),
+  );
+
+  $data['watchdog']['referer'] = array(
+    'title' => t('Referer'),
+    'help' => t('URL of the previous page.'),
+    'field' => array(
+      'id' => 'standard',
+    ),
+    'argument' => array(
+      'id' => 'string',
+    ),
+    'filter' => array(
+      'id' => 'string',
+    ),
+    'sort' => array(
+      'id' => 'standard',
+    ),
+  );
+
+  $data['watchdog']['hostname'] = array(
+    'title' => t('Hostname'),
+    'help' => t('Hostname of the user who triggered the event.'),
+    'field' => array(
+      'id' => 'standard',
+    ),
+    'argument' => array(
+      'id' => 'string',
+    ),
+    'filter' => array(
+      'id' => 'string',
+    ),
+    'sort' => array(
+      'id' => 'standard',
+    ),
+  );
+
+  $data['watchdog']['timestamp'] = array(
+    'title' => t('Timestamp'),
+    'help' => t('Date when the event occurred.'),
+    'field' => array(
+      'id' => 'date',
+    ),
+    'argument' => array(
+      'id' => 'date',
+    ),
+    'filter' => array(
+      'id' => 'date',
+    ),
+    'sort' => array(
+      'id' => 'date',
+    ),
+  );
+
+  return $data;
+}
diff --git a/core/modules/dblog/lib/Drupal/dblog/Plugin/views/field/DblogMessage.php b/core/modules/dblog/lib/Drupal/dblog/Plugin/views/field/DblogMessage.php
new file mode 100644
index 0000000..80a6a0f
--- /dev/null
+++ b/core/modules/dblog/lib/Drupal/dblog/Plugin/views/field/DblogMessage.php
@@ -0,0 +1,74 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\dblog\Plugin\views\field\DblogMessage.
+ */
+
+namespace Drupal\dblog\Plugin\views\field;
+
+use Drupal\Component\Utility\String;
+use Drupal\views\Plugin\views\field\FieldPluginBase;
+use Drupal\Component\Annotation\PluginID;
+use Drupal\views\ViewExecutable;
+use Drupal\views\Plugin\views\display\DisplayPluginBase;
+
+/**
+ * Provides a field handler that renders a log event with replaced variables.
+ *
+ * @ingroup views_field_handlers
+ *
+ * @PluginID("dblog_message")
+ */
+class DblogMessage extends FieldPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
+    parent::init($view, $display, $options);
+
+    if ($this->options['replace_variables']) {
+      $this->additional_fields['variables'] = 'variables';
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineOptions() {
+    $options = parent::defineOptions();
+    $options['replace_variables'] = array('default' => TRUE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildOptionsForm(&$form, &$form_state) {
+    parent::buildOptionsForm($form, $form_state);
+
+    $form['replace_variables'] = array(
+      '#title' => t('Replace variables'),
+      '#type' => 'checkbox',
+      '#default_value' => $this->options['replace_variables'],
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function render($values) {
+    $value = $this->getValue($values);
+
+    if ($this->options['replace_variables']) {
+      $variables = unserialize($this->getvalue($values, 'variables'));
+      return String::format($value, (array) $variables);
+    }
+    else {
+      return $this->sanitizeValue($value);
+    }
+  }
+
+}
diff --git a/core/modules/dblog/lib/Drupal/dblog/Plugin/views/field/DblogOperations.php b/core/modules/dblog/lib/Drupal/dblog/Plugin/views/field/DblogOperations.php
new file mode 100644
index 0000000..ae90053
--- /dev/null
+++ b/core/modules/dblog/lib/Drupal/dblog/Plugin/views/field/DblogOperations.php
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\dblog\Plugin\views\field\DblogOperations.
+ */
+
+namespace Drupal\dblog\Plugin\views\field;
+
+use Drupal\views\Plugin\views\field\FieldPluginBase;
+use Drupal\Component\Annotation\PluginID;
+use Drupal\views\ViewExecutable;
+use Drupal\views\Plugin\views\display\DisplayPluginBase;
+
+/**
+ * Provides a field handler that renders operation link markup.
+ *
+ * @ingroup views_field_handlers
+ *
+ * @PluginID("dblog_operations")
+ */
+class DblogOperations extends FieldPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function clickSortable() {
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function render($values) {
+    $value = $this->getValue($values);
+    return $this->sanitizeValue($value, 'xss_admin');
+  }
+
+}
diff --git a/core/modules/dblog/lib/Drupal/dblog/Tests/Views/ViewsIntegrationTest.php b/core/modules/dblog/lib/Drupal/dblog/Tests/Views/ViewsIntegrationTest.php
new file mode 100644
index 0000000..d548480
--- /dev/null
+++ b/core/modules/dblog/lib/Drupal/dblog/Tests/Views/ViewsIntegrationTest.php
@@ -0,0 +1,110 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\dblog\Tests\Views\ViewsIntegrationTest.
+ */
+
+namespace Drupal\dblog\Tests\Views;
+
+use Drupal\Component\Utility\String;
+use Drupal\Component\Utility\Xss;
+use Drupal\views\Tests\ViewTestData;
+use Drupal\views\Tests\ViewUnitTestBase;
+
+/**
+ * Tests the views integration of dblog module.
+ */
+class ViewsIntegrationTest extends ViewUnitTestBase {
+
+  /**
+   * Views used by this test.
+   *
+   * @var array
+   */
+  public static $testViews = array('test_dblog');
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('dblog_test_views');
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Dblog Integration',
+      'description' => 'Tests the views integration of dblog module.',
+      'group' => 'Views module integration'
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->enableModules(array('system', 'dblog'));
+    $this->installSchema('dblog', array('watchdog'));
+
+    ViewTestData::importTestViews(get_class($this), array('dblog_test_views'));
+  }
+
+  /**
+   * Tests the integration.
+   */
+  public function testIntegration() {
+
+    // Remove the watchdog entries added by the potential batch process.
+    $this->container->get('database')->truncate('watchdog')->execute();
+
+    $entries = array();
+    // Setup a watchdog entry without tokens.
+    $entries[] = array(
+      'message' => $this->randomName(),
+      'variables' => array(),
+      'link' => l('Link', 'node/1'),
+    );
+    // Setup a watchdog entry with one token.
+    $entries[] = array(
+      'message' => '@token1',
+      'variables' => array('@token1' => $this->randomName()),
+      'link' => l('Link', 'node/2'),
+    );
+    // Setup a watchdog entry with two tokens.
+    $entries[] = array(
+      'message' => '@token1 !token2',
+      'variables' => array('@token1' => $this->randomName(), '!token2' => $this->randomName()),
+      // Setup a link with a tag which is filtered by filter_xss_admin.
+      'link' => l('<object>Link</object>', 'node/2', array('html' => TRUE)),
+    );
+    foreach ($entries as $entry) {
+      $entry += array(
+        'type' => 'test-views',
+        'severity' => WATCHDOG_NOTICE,
+      );
+      watchdog($entry['type'], $entry['message'], $entry['variables'], $entry['severity'], $entry['link']);
+    }
+
+    $view = views_get_view('test_dblog');
+    $this->executeView($view);
+    $view->initStyle();
+
+    foreach ($entries as $index => $entry) {
+      $this->assertEqual($view->style_plugin->getField($index, 'message'), String::format($entry['message'], $entry['variables']));
+      $this->assertEqual($view->style_plugin->getField($index, 'link'), Xss::filterAdmin($entry['link']));
+    }
+
+    // Disable replacing variables and check that the tokens aren't replaced.
+    $view->destroy();
+    $view->initHandlers();
+    $this->executeView($view);
+    $view->initStyle();
+    $view->field['message']->options['replace_variables'] = FALSE;
+    foreach ($entries as $index => $entry) {
+      $this->assertEqual($view->style_plugin->getField($index, 'message'), $entry['message']);
+    }
+  }
+
+}
diff --git a/core/modules/dblog/tests/modules/dblog_test_views/dblog_test_views.info.yml b/core/modules/dblog/tests/modules/dblog_test_views/dblog_test_views.info.yml
new file mode 100644
index 0000000..0357267
--- /dev/null
+++ b/core/modules/dblog/tests/modules/dblog_test_views/dblog_test_views.info.yml
@@ -0,0 +1,9 @@
+name: 'Dblog test views'
+description: 'Provides default views for views dblog tests.'
+package: Testing
+version: VERSION
+core: 8.x
+dependencies:
+  - dblog
+  - views
+hidden: TRUE
diff --git a/core/modules/dblog/tests/modules/dblog_test_views/dblog_test_views.module b/core/modules/dblog/tests/modules/dblog_test_views/dblog_test_views.module
new file mode 100644
index 0000000..b3d9bbc
--- /dev/null
+++ b/core/modules/dblog/tests/modules/dblog_test_views/dblog_test_views.module
@@ -0,0 +1 @@
+<?php
diff --git a/core/modules/dblog/tests/modules/dblog_test_views/test_views/views.view.test_dblog.yml b/core/modules/dblog/tests/modules/dblog_test_views/test_views/views.view.test_dblog.yml
new file mode 100644
index 0000000..0792087
--- /dev/null
+++ b/core/modules/dblog/tests/modules/dblog_test_views/test_views/views.view.test_dblog.yml
@@ -0,0 +1,61 @@
+base_field: wid
+base_table: watchdog
+core: 8.x
+description: ''
+status: '1'
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: ''
+    display_options:
+      access:
+        type: none
+      cache:
+        type: none
+      query:
+        type: views_query
+      exposed_form:
+        type: basic
+      pager:
+        type: full
+      style:
+        type: default
+      row:
+        type: fields
+      fields:
+        wid:
+          id: wid
+          table: watchdog
+          field: wid
+          plugin_id: numeric
+        message:
+          id: message
+          table: watchdog
+          field: message
+          plugin_id: dblog_message
+        link:
+          id: link
+          table: watchdog
+          field: link
+          plugin_id: dblog_operations
+      filters: {  }
+      sorts:
+        wid:
+          id: wid
+          table: watchdog
+          field: wid
+          order: ASC
+          plugin_id: standard
+  page_1:
+    display_plugin: page
+    id: page_1
+    display_title: Page
+    position: ''
+    display_options:
+      path: test-dblog
+label: test_dblog
+module: views
+id: test_dblog
+tag: ''
