diff --git a/modules/dvg/dvg_logger/dvg_logger.admin.inc b/modules/dvg/dvg_logger/dvg_logger.admin.inc
index 3055857..ab55b5c 100644
--- a/modules/dvg/dvg_logger/dvg_logger.admin.inc
+++ b/modules/dvg/dvg_logger/dvg_logger.admin.inc
@@ -1,11 +1,23 @@
 <?php
 
 /**
+ * @file
+ * Contains admin user interface for DvG Logger.
+ */
+
+/**
  * DVG Logger configuration form.
  */
 function dvg_logger_admin_form() {
   $form = array();
 
+  $types_filter_default = array(
+    'failed_login_attempts' => 'failed_login_attempts',
+    'testdata_stuf_bg_attempts' => 'testdata_stuf_bg_attempts',
+  );
+
+  $types_filter = array_merge($types_filter_default, _dvg_logger_get_types());
+
   $form['dvg_logger_recipient_emails'] = array(
     '#type' => 'textfield',
     '#title' => t('Recipient email'),
@@ -25,7 +37,7 @@ function dvg_logger_admin_form() {
   $form['dvg_logger_attempts_digest'] = array(
     '#type' => 'select',
     '#title' => t('Period'),
-    '#description' => t('Select when to send an email containing failed login attempts.'),
+    '#description' => t('Select when to send an email containing logs of types below.'),
     '#options' => array(
       '' => t('Do not send emails'),
       'daily' => t('Daily'),
@@ -34,6 +46,35 @@ function dvg_logger_admin_form() {
     ),
     '#default_value' => variable_get('dvg_logger_attempts_digest', ''),
   );
+  $form['dvg_logger_email_types_filter'] = array(
+    '#type' => 'select',
+    '#multiple' => TRUE,
+    '#title' => t('Only email reports of these types'),
+    '#options' => $types_filter,
+    '#default_value' => variable_get('dvg_logger_email_types_filter', $types_filter_default),
+    '#required' => FALSE,
+  );
+
+  $form['dvg_logger_cleanup_limit_days'] = array(
+    '#type' => 'select',
+    '#title' => t('Remove encrypted logs after:'),
+    '#options' => array(
+      '1' => t('One day'),
+      '2' => t('Two days'),
+      '3' => t('Three days'),
+      '4' => t('Four days'),
+      '5' => t('Five days'),
+      '6' => t('Six days'),
+      '7' => t('One week'),
+      '14' => t('Two weeks'),
+      '21' => t('Three weeks'),
+      '31' => t('One month'),
+      '61' => t('Two months'),
+      '92' => t('Three months'),
+    ),
+    '#default_value' => variable_get('dvg_logger_cleanup_limit_days', '7'),
+    '#required' => TRUE,
+  );
 
   $form = system_settings_form($form);
 
@@ -55,3 +96,138 @@ function _dvg_logger_validate_emails($form_element, &$form_state) {
     }
   }
 }
+
+/**
+ * DVG Logger list logs form.
+ */
+function dvg_logger_list_form($form, &$form_state) {
+
+  $header = [
+    ['data' => t('Id'), 'field' => 'lid'],
+    ['data' => t('Type'), 'field' => 'type'],
+    ['data' => t('Hostname'), 'field' => 'hostname'],
+    ['data' => t('Timestamp'), 'field' => 'timestamp', 'sort' => 'desc'],
+    ['data' => t('Details')],
+  ];
+
+  $query = db_select('dvg_logger', 'dl');
+
+  $query->fields('dl', [
+    'lid',
+    'type',
+    'hostname',
+    'timestamp',
+    'encrypted',
+  ])
+    ->extend('TableSort')
+    ->extend('PagerDefault')
+    ->orderByHeader($header)
+    ->limit(25);
+
+  if (isset($form_state['input']['filter_type']) && $form_state['input']['filter_type'] != 'all') {
+    $query->condition('dl.type', check_plain($form_state['input']['filter_type']), '=');
+  }
+
+  $result = $query->execute();
+
+  $form = [];
+  $types = [];
+  $types['all'] = t('All');
+  $types = array_merge($types, _dvg_logger_get_types());
+
+  $form['filters'] = [
+    '#type' => 'fieldset',
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE,
+    '#title' => t('Filters'),
+  ];
+  $form['filters']['filter_type'] = [
+    '#type' => 'select',
+    '#options' => $types,
+    '#title' => t('Type'),
+  ];
+  $form['filters']['actions']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Filter'),
+  );
+
+  $rows = [];
+  foreach ($result as $row) {
+    $message = $row->message;
+    if ($row->encrypted) {
+      $message = decrypt($row->message);
+    }
+    $rows[] = [
+      $row->lid,
+      $row->type,
+      $row->hostname,
+      format_date($row->timestamp, 'custom', 'd-M-Y H:i:s', date_default_timezone()),
+      l(t('View details'), 'admin/reports/dvg-logger/' . $row->lid),
+    ];
+  }
+
+  $form['table'] = [
+    '#theme' => 'table',
+    '#header' => $header,
+    '#rows' => $rows,
+    '#empty' => t('Table has no rows!'),
+  ];
+
+  $form['pager'] = ['#markup' => theme('pager')];
+
+  return $form;
+}
+
+/**
+ * Submit handler.
+ */
+function dvg_logger_list_form_submit($form, &$form_state) {
+  $form_state['filters']['type'] = $form_state['values']['filter_type'];
+  $form_state['rebuild'] = TRUE;
+}
+
+/**
+ * Event detail.
+ *
+ * @param int $lid
+ *   Event id.
+ *
+ * @return string
+ *   A build array in the
+ *   format expected by drupal_render();
+ */
+function dvg_logger_event($lid) {
+  $log = db_query('SELECT * FROM {dvg_logger} dl WHERE dl.lid = :lid', array(':lid' => $lid))->fetchObject();
+  if (!$log) {
+    return t('No logs found.');
+  }
+  $message = $log->message;
+  if ($log->encrypted) {
+    $message = decrypt($log->message);
+  }
+  $rows = array(
+    array(
+      array('data' => t('Type'), 'header' => TRUE),
+      $log->type,
+    ),
+    array(
+      array('data' => t('Date'), 'header' => TRUE),
+      format_date($log->timestamp, 'long'),
+    ),
+    array(
+      array('data' => t('Hostname'), 'header' => TRUE),
+      check_plain($log->hostname),
+    ),
+    array(
+      array('data' => t('Message'), 'header' => TRUE),
+      $message,
+    ),
+  );
+  $build['dvg_logger_detail'] = array(
+    '#theme' => 'table',
+    '#rows' => $rows,
+  );
+
+  return $build;
+
+}
diff --git a/modules/dvg/dvg_logger/dvg_logger.cron.inc b/modules/dvg/dvg_logger/dvg_logger.cron.inc
index 6aec6ae..3aac7d0 100644
--- a/modules/dvg/dvg_logger/dvg_logger.cron.inc
+++ b/modules/dvg/dvg_logger/dvg_logger.cron.inc
@@ -10,6 +10,7 @@
  */
 function dvg_logger_cron() {
   _dvg_logger_send_email();
+  _dvg_logger_cleanup();
 }
 
 /**
@@ -52,13 +53,19 @@ function _dvg_logger_send_email() {
     if (isset($start) && isset($end)) {
       if ($period && !empty($recipients)) {
 
-        $types = db_select('dvg_logger', 'dl')
-          ->fields('dl', array('type'))
-          ->groupBy('type')
-          ->execute();
-        if ($types->rowCount()) {
+        $types = _dvg_logger_get_types();
+        $types_filter_default = array(
+          'failed_login_attempts' => 'failed_login_attempts',
+          'testdata_stuf_bg_attempts' => 'testdata_stuf_bg_attempts',
+        );
+        $filter_types = variable_get('dvg_logger_email_types_filter', $types_filter_default);
+
+        if (!empty($types)) {
           foreach ($types as $type) {
-            dvg_logger_send_email($type->type, $recipients, $start, $end);
+            if (in_array($type, $filter_types)) {
+              dvg_logger_send_email($type->type, $recipients, $start, $end);
+              _dvg_logger_register_log('dvg_logger_mail', t('E-mailed @period log of type @type', array('@period' => $period, '@type' => $type)));
+            }
           }
           // Update the last cron run timestamp.
           variable_set('dvg_logger_attempts_email_last_run', $today);
@@ -118,3 +125,26 @@ function dvg_logger_send_email($type, $recipients, $start, $end) {
     }
   }
 }
+
+/**
+ * Cleanup encrypted logs after a configurable amount of time.
+ */
+function _dvg_logger_cleanup() {
+  $last_run = variable_get('dvg_logger_attempts_cleanup_last_run', 0);
+  $today = strtotime('today 00:00:00');
+
+  if ($last_run < $today) {
+    $days = variable_get('dvg_logger_cleanup_limit_days', '31');
+    $seconds = $days * 24 * 60 * 60;
+    $timestamp = time() - $seconds;
+    $count = db_delete('dvg_logger')
+      ->condition('encrypted', 1)
+      ->condition('timestamp', $timestamp, '<')
+      ->execute();
+    if ($count > 0) {
+      _dvg_logger_register_log('dvg_logger_cleanup', t('Removed @num_items items from this log after @num_days days.', array('@num_items' => $count, '@num_days' => $days)));
+    }
+    // Update the last cron run timestamp.
+    variable_set('dvg_logger_attempts_cleanup_last_run', $today);
+  }
+}
diff --git a/modules/dvg/dvg_logger/dvg_logger.install b/modules/dvg/dvg_logger/dvg_logger.install
index 375eb2f..ae1873d 100644
--- a/modules/dvg/dvg_logger/dvg_logger.install
+++ b/modules/dvg/dvg_logger/dvg_logger.install
@@ -1,6 +1,11 @@
 <?php
 
 /**
+ * @file
+ * Contains install and update scripts for dvg_logger.
+ */
+
+/**
  * Implements hook_schema().
  */
 function dvg_logger_schema() {
@@ -38,6 +43,13 @@ function dvg_logger_schema() {
         'default' => 0,
         'description' => 'Unix timestamp of when event occurred.',
       ),
+      'encrypted' => array(
+        'type' => 'int',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+        'description' => 'Determines whether this field is encrypted.',
+      ),
     ),
     'primary key' => array('lid'),
     'indexes' => array(
@@ -60,3 +72,13 @@ function dvg_logger_update_7001() {
   variable_del('dvg_logger_login_attempts_digest');
 }
 
+/**
+ * Add new field to dvg_logger table.
+ */
+function dvg_logger_update_7002() {
+  $schema = drupal_get_schema('dvg_logger');
+  $field_name = 'encrypted';
+  if (!db_field_exists('dvg_logger', $field_name)) {
+    db_add_field('dvg_logger', $field_name, $schema['fields'][$field_name]);
+  }
+}
diff --git a/modules/dvg/dvg_logger/dvg_logger.module b/modules/dvg/dvg_logger/dvg_logger.module
index f659460..50e3e69 100644
--- a/modules/dvg/dvg_logger/dvg_logger.module
+++ b/modules/dvg/dvg_logger/dvg_logger.module
@@ -29,11 +29,36 @@ function dvg_logger_menu() {
     'access arguments' => array('administer site configuration'),
     'file' => 'dvg_logger.admin.inc',
   );
-
+  $items['admin/reports/dvg-logger'] = array(
+    'title' => 'DVG Logger',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('dvg_logger_list_form'),
+    'access arguments' => array('view dvg logger reports'),
+    'file' => 'dvg_logger.admin.inc',
+  );
+  $items['admin/reports/dvg-logger/%'] = array(
+    'title' => 'Detail',
+    'page callback' => 'dvg_logger_event',
+    'page arguments' => array(3),
+    'access arguments' => array('view dvg logger reports'),
+    'file' => 'dvg_logger.admin.inc',
+  );
   return $items;
 }
 
 /**
+ * Implements hook_permission().
+ */
+function dvg_logger_permission() {
+  return array(
+    'view dvg logger reports' => array(
+      'title' => t('View DvG logger reports'),
+      'description' => t('Allow users to view DvG logs'),
+    ),
+  );
+}
+
+/**
  * Implements hook_dvg_requirements().
  */
 function dvg_logger_dvg_requirements() {
@@ -96,16 +121,21 @@ function dvg_logger_register_failed_login_attempt($form, &$form_state) {
 }
 
 /**
- * Register a failed login attempt in de database.
+ * Register an event in dvg_logger table.
  */
-function _dvg_logger_register_log($type, $name) {
+function _dvg_logger_register_log($type, $name, $encrypted = FALSE) {
   $table = 'dvg_logger';
 
+  if ($encrypted) {
+    $name = encrypt($name);
+  }
+
   $data = array(
     'type' => $type,
     'message' => $name,
     'hostname' => ip_address(),
     'timestamp' => REQUEST_TIME,
+    'encrypted' => $encrypted,
   );
 
   drupal_write_record($table, $data);
@@ -119,3 +149,24 @@ function _dvg_logger_get_configured_recipient_emails() {
   $emails = explode(',', $email_string);
   return $emails;
 }
+
+/**
+ * Helper function to retrieve available types in the current logs.
+ *
+ * @return array
+ *    An array of log types.
+ */
+function _dvg_logger_get_types() {
+  $query = db_select('dvg_logger', 'dl');
+  $result = $query->fields('dl', [
+    'type',
+  ])
+    ->distinct()
+    ->execute();
+
+  $types = [];
+  foreach ($result as $row) {
+    $types[$row->type] = $row->type;
+  }
+  return $types;
+}
