diff --git a/config/install/monitoring.sensor_config.user_failed_logins.yml b/config/install/monitoring.sensor_config.user_failed_logins.yml
index 51dc3d3..e3ab638 100644
--- a/config/install/monitoring.sensor_config.user_failed_logins.yml
+++ b/config/install/monitoring.sensor_config.user_failed_logins.yml
@@ -16,7 +16,7 @@ settings:
     -
       field: 'message'
       value: 'Login attempt failed for %user.'
-  keys:
+  verbose_fields:
     - 'wid'
     - 'message'
     - 'variables'
diff --git a/config/install/monitoring.sensor_config.user_sessions_all.yml b/config/install/monitoring.sensor_config.user_sessions_all.yml
index 840892a..8834619 100644
--- a/config/install/monitoring.sensor_config.user_sessions_all.yml
+++ b/config/install/monitoring.sensor_config.user_sessions_all.yml
@@ -15,7 +15,7 @@ settings:
       field: 'uid'
       value: '0'
       operator: '!='
-  keys:
+  verbose_fields:
     - 'uid'
     - 'hostname'
     - 'timestamp'
diff --git a/config/install/monitoring.sensor_config.user_sessions_authenticated.yml b/config/install/monitoring.sensor_config.user_sessions_authenticated.yml
index 81e7e76..3729c20 100644
--- a/config/install/monitoring.sensor_config.user_sessions_authenticated.yml
+++ b/config/install/monitoring.sensor_config.user_sessions_authenticated.yml
@@ -15,7 +15,7 @@ settings:
       field: 'uid'
       value: '0'
       operator: '!='
-  keys:
+  verbose_fields:
     - 'uid'
     - 'hostname'
     - 'timestamp'
diff --git a/config/install/monitoring.sensor_config.user_sessions_logouts.yml b/config/install/monitoring.sensor_config.user_sessions_logouts.yml
index 7141ca3..c3bbe23 100644
--- a/config/install/monitoring.sensor_config.user_sessions_logouts.yml
+++ b/config/install/monitoring.sensor_config.user_sessions_logouts.yml
@@ -16,7 +16,7 @@ settings:
     -
       field: 'message'
       value: 'Session closed for %name.'
-  keys:
+  verbose_fields:
     - 'message'
     - 'wid'
     - 'variables'
diff --git a/config/install/monitoring.sensor_config.user_successful_logins.yml b/config/install/monitoring.sensor_config.user_successful_logins.yml
index 7fa49b3..5983ef9 100644
--- a/config/install/monitoring.sensor_config.user_successful_logins.yml
+++ b/config/install/monitoring.sensor_config.user_successful_logins.yml
@@ -16,7 +16,7 @@ settings:
     -
       field: 'message'
       value: 'Session opened for %name.'
-  keys:
+  verbose_fields:
     - 'wid'
     - 'message'
     - 'variables'
diff --git a/config/optional/monitoring.sensor_config.captcha_failed_count.yml b/config/optional/monitoring.sensor_config.captcha_failed_count.yml
index cc42243..2ea4672 100644
--- a/config/optional/monitoring.sensor_config.captcha_failed_count.yml
+++ b/config/optional/monitoring.sensor_config.captcha_failed_count.yml
@@ -17,7 +17,7 @@ settings:
         field: 'attempts'
         value: '0'
         operator: '>'
-  keys:
+  verbose_fields:
     - 'uid'
     - 'form_id'
     - 'attempts'
diff --git a/config/optional/monitoring.sensor_config.dblog_404.yml b/config/optional/monitoring.sensor_config.dblog_404.yml
index ded9ebb..205c697 100644
--- a/config/optional/monitoring.sensor_config.dblog_404.yml
+++ b/config/optional/monitoring.sensor_config.dblog_404.yml
@@ -18,7 +18,7 @@ settings:
     -
       field: type
       value: 'page not found'
-  keys:
+  verbose_fields:
     - 'wid'
     - 'location'
     - 'referer'
diff --git a/config/optional/monitoring.sensor_config.dblog_event_severity_alert.yml b/config/optional/monitoring.sensor_config.dblog_event_severity_alert.yml
index b859479..0034df5 100644
--- a/config/optional/monitoring.sensor_config.dblog_event_severity_alert.yml
+++ b/config/optional/monitoring.sensor_config.dblog_event_severity_alert.yml
@@ -18,7 +18,7 @@ settings:
     -
       field: severity
       value: '1'
-  keys:
+  verbose_fields:
     - 'wid'
     - 'message'
     - 'variables'
diff --git a/config/optional/monitoring.sensor_config.dblog_event_severity_critical.yml b/config/optional/monitoring.sensor_config.dblog_event_severity_critical.yml
index e8e7c12..0791f9c 100644
--- a/config/optional/monitoring.sensor_config.dblog_event_severity_critical.yml
+++ b/config/optional/monitoring.sensor_config.dblog_event_severity_critical.yml
@@ -18,7 +18,7 @@ settings:
     -
       field: severity
       value: '2'
-  keys:
+  verbose_fields:
     - 'wid'
     - 'message'
     - 'variables'
diff --git a/config/optional/monitoring.sensor_config.dblog_event_severity_debug.yml b/config/optional/monitoring.sensor_config.dblog_event_severity_debug.yml
index ddd18a6..525c625 100644
--- a/config/optional/monitoring.sensor_config.dblog_event_severity_debug.yml
+++ b/config/optional/monitoring.sensor_config.dblog_event_severity_debug.yml
@@ -18,7 +18,7 @@ settings:
     -
       field: severity
       value: '7'
-  keys:
+  verbose_fields:
     - 'wid'
     - 'message'
     - 'variables'
diff --git a/config/optional/monitoring.sensor_config.dblog_event_severity_emergency.yml b/config/optional/monitoring.sensor_config.dblog_event_severity_emergency.yml
index 54e3229..9126a1c 100644
--- a/config/optional/monitoring.sensor_config.dblog_event_severity_emergency.yml
+++ b/config/optional/monitoring.sensor_config.dblog_event_severity_emergency.yml
@@ -18,7 +18,7 @@ settings:
     -
       field: severity
       value: '0'
-  keys:
+  verbose_fields:
     - 'wid'
     - 'message'
     - 'variables'
diff --git a/config/optional/monitoring.sensor_config.dblog_event_severity_error.yml b/config/optional/monitoring.sensor_config.dblog_event_severity_error.yml
index 7a034b7..1e6cbd4 100644
--- a/config/optional/monitoring.sensor_config.dblog_event_severity_error.yml
+++ b/config/optional/monitoring.sensor_config.dblog_event_severity_error.yml
@@ -18,7 +18,7 @@ settings:
     -
       field: severity
       value: '3'
-  keys:
+  verbose_fields:
     - 'wid'
     - 'message'
     - 'variables'
diff --git a/config/optional/monitoring.sensor_config.dblog_event_severity_info.yml b/config/optional/monitoring.sensor_config.dblog_event_severity_info.yml
index eb134c3..c98c6c5 100644
--- a/config/optional/monitoring.sensor_config.dblog_event_severity_info.yml
+++ b/config/optional/monitoring.sensor_config.dblog_event_severity_info.yml
@@ -18,7 +18,7 @@ settings:
     -
       field: severity
       value: '6'
-  keys:
+  verbose_fields:
     - 'wid'
     - 'message'
     - 'variables'
diff --git a/config/optional/monitoring.sensor_config.dblog_event_severity_notice.yml b/config/optional/monitoring.sensor_config.dblog_event_severity_notice.yml
index c62e079..ffa9e51 100644
--- a/config/optional/monitoring.sensor_config.dblog_event_severity_notice.yml
+++ b/config/optional/monitoring.sensor_config.dblog_event_severity_notice.yml
@@ -18,7 +18,7 @@ settings:
     -
       field: severity
       value: '5'
-  keys:
+  verbose_fields:
     - 'wid'
     - 'message'
     - 'variables'
diff --git a/config/optional/monitoring.sensor_config.dblog_event_severity_warning.yml b/config/optional/monitoring.sensor_config.dblog_event_severity_warning.yml
index 21b35df..74a13b6 100644
--- a/config/optional/monitoring.sensor_config.dblog_event_severity_warning.yml
+++ b/config/optional/monitoring.sensor_config.dblog_event_severity_warning.yml
@@ -18,7 +18,7 @@ settings:
     -
       field: severity
       value: '4'
-  keys:
+  verbose_fields:
     - 'wid'
     - 'message'
     - 'variables'
diff --git a/config/optional/monitoring.sensor_config.dblog_image_missing_style.yml b/config/optional/monitoring.sensor_config.dblog_image_missing_style.yml
index 55a9eb3..360e710 100644
--- a/config/optional/monitoring.sensor_config.dblog_image_missing_style.yml
+++ b/config/optional/monitoring.sensor_config.dblog_image_missing_style.yml
@@ -22,7 +22,7 @@ settings:
     -
       field: message
       value: 'Source image at %source_image_path not found while trying to generate derivative image at %derivative_path.'
-  keys:
+  verbose_fields:
     - 'wid'
     - 'message'
     - 'variables'
diff --git a/config/optional/monitoring.sensor_config.maillog_records_count.yml b/config/optional/monitoring.sensor_config.maillog_records_count.yml
index 28a9b92..4863d0f 100644
--- a/config/optional/monitoring.sensor_config.maillog_records_count.yml
+++ b/config/optional/monitoring.sensor_config.maillog_records_count.yml
@@ -9,7 +9,7 @@ settings:
   table: 'maillog'
   time_interval_field: 'sent_date'
   time_interval_value: '86400'
-  keys:
+  verbose_fields:
     - 'idmaillog'
     - 'message_id'
     - 'subject'
diff --git a/config/optional/monitoring.sensor_config.past_form.yml b/config/optional/monitoring.sensor_config.past_form.yml
index e3fd98b..93b2046 100644
--- a/config/optional/monitoring.sensor_config.past_form.yml
+++ b/config/optional/monitoring.sensor_config.past_form.yml
@@ -13,7 +13,7 @@ settings:
     -
       field: 'module'
       value: 'past_form'
-  keys:
+  verbose_fields:
     - 'event_id'
     - 'type'
     - 'module'
diff --git a/config/schema/monitoring.schema.yml b/config/schema/monitoring.schema.yml
index 7398eef..58a2fbb 100644
--- a/config/schema/monitoring.schema.yml
+++ b/config/schema/monitoring.schema.yml
@@ -101,12 +101,12 @@ monitoring.settings.aggregator_base:
             type: string
           operator:
             type: string
-    keys:
+    verbose_fields:
       type: sequence
-      label: Keys
+      label: Verbose fields
       sequence:
         type: string
-        label: 'Key'
+        label: 'Field'
 
 monitoring.settings.database_aggregator:
   type: monitoring.settings.aggregator_base
@@ -122,6 +122,24 @@ monitoring.settings.entity_aggregator:
     entity_type:
       type: string
       label: 'Table'
+    conditions:
+      type: sequence
+      label: Conditions
+      sequence:
+        type: mapping
+        mapping:
+          field:
+            type: string
+          value:
+            type: string
+          operator:
+            type: string
+    fields:
+      type: sequence
+      label: Fields
+      sequence:
+        type: string
+        label: 'Field'
 
 monitoring.settings.monitoring_git_dirty_tree:
   type: mapping
diff --git a/modules/test/config/install/monitoring.sensor_config.watchdog_aggregate_test.yml b/modules/test/config/install/monitoring.sensor_config.watchdog_aggregate_test.yml
index f98d471..ac7c529 100644
--- a/modules/test/config/install/monitoring.sensor_config.watchdog_aggregate_test.yml
+++ b/modules/test/config/install/monitoring.sensor_config.watchdog_aggregate_test.yml
@@ -9,7 +9,7 @@ settings:
   table: watchdog
   time_interval_field: 'timestamp'
   time_interval_value: 86400
-  keys:
+  verbose_fields:
     - 'wid'
     - 'message'
     - 'variables'
diff --git a/modules/test/config/optional/monitoring.sensor_config.entity_aggregate_test.yml b/modules/test/config/optional/monitoring.sensor_config.entity_aggregate_test.yml
index c5ea837..3c9019f 100644
--- a/modules/test/config/optional/monitoring.sensor_config.entity_aggregate_test.yml
+++ b/modules/test/config/optional/monitoring.sensor_config.entity_aggregate_test.yml
@@ -15,6 +15,9 @@ settings:
     -
       field: 'type'
       value: 'page'
+  fields:
+    - id
+    - label
 thresholds:
   type: 'falls'
   warning: 2
diff --git a/src/Plugin/monitoring/SensorPlugin/DatabaseAggregatorSensorPlugin.php b/src/Plugin/monitoring/SensorPlugin/DatabaseAggregatorSensorPlugin.php
index a8ed1c5..6995507 100644
--- a/src/Plugin/monitoring/SensorPlugin/DatabaseAggregatorSensorPlugin.php
+++ b/src/Plugin/monitoring/SensorPlugin/DatabaseAggregatorSensorPlugin.php
@@ -59,13 +59,6 @@ class DatabaseAggregatorSensorPlugin extends DatabaseAggregatorSensorPluginBase
   protected $fetchedObject;
 
   /**
-   * The currently active keys for verbose output.
-   *
-   * @var array
-   */
-  protected $currentKeys;
-
-  /**
    * Builds simple aggregate query over one db table.
    *
    * @return \Drupal\Core\Database\Query\Select
@@ -127,10 +120,10 @@ class DatabaseAggregatorSensorPlugin extends DatabaseAggregatorSensorPluginBase
     }
 
     // Add key fields.
-    $keys = $this->sensorConfig->getSetting('keys');
-    if (!empty($keys)) {
-      foreach ($this->sensorConfig->getSetting('keys') as $key) {
-        $query->addField($this->sensorConfig->getSetting('table'), $key);
+    $fields = $this->sensorConfig->getSetting('verbose_fields');
+    if (!empty($fields)) {
+      foreach ($this->sensorConfig->getSetting('verbose_fields') as $field) {
+        $query->addField($this->sensorConfig->getSetting('table'), $field);
       }
     }
 
@@ -232,7 +225,7 @@ class DatabaseAggregatorSensorPlugin extends DatabaseAggregatorSensorPluginBase
   }
 
   /**
-   * Adds UI for variables table and conditions.
+   * Adds UI for variables table, conditions and keys.
    */
   public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
     $form = parent::buildConfigurationForm($form, $form_state);
@@ -240,7 +233,7 @@ class DatabaseAggregatorSensorPlugin extends DatabaseAggregatorSensorPluginBase
     $settings = $this->sensorConfig->getSettings();
     $form['table'] = array(
       '#type' => 'textfield',
-      '#default_value' => $this->sensorConfig->getSetting('table'),
+      '#default_value' => $settings['table'],
       '#maxlength' => 255,
       '#title' => t('Table'),
       '#required' => TRUE,
@@ -270,30 +263,8 @@ class DatabaseAggregatorSensorPlugin extends DatabaseAggregatorSensorPluginBase
       ),
     );
 
-    // Fill the sensors table with form elements for each sensor.
-    $form['output_table'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Verbose Output configuration'),
-      '#prefix' => '<div id="selected-output">',
-      '#suffix' => '</div>',
-      '#tree' => FALSE,
-    );
-    // Fill the keys text field with keys.
-    $form['output_table']['keys'] = array(
-      '#type' => 'textarea',
-      '#tree' => FALSE,
-      '#default_value' => implode("\n", $this->sensorConfig->getSetting('keys')),
-      '#maxlength' => 255,
-      '#title' => t('Keys'),
-      '#required' => TRUE,
-    );
-
-
     // Fill the conditions table with keys and values for each condition.
-    $conditions = $this->sensorConfig->getSetting('conditions');
-    if (empty($conditions)) {
-      $conditions = [];
-    }
+    $conditions = $settings['conditions'];
 
     if (!$form_state->has('conditions_rows')) {
       $form_state->set('conditions_rows', count($conditions) + 1);
@@ -339,7 +310,7 @@ class DatabaseAggregatorSensorPlugin extends DatabaseAggregatorSensorPluginBase
     // Select element for available conditions.
     $form['conditions_table']['condition_add_button'] = array(
       '#type' => 'submit',
-      '#value' => t('Add more conditions'),
+      '#value' => t('Add another condition'),
       '#ajax' => array(
         'wrapper' => 'selected-conditions',
         'callback' => array($this, 'conditionsReplace'),
@@ -348,6 +319,56 @@ class DatabaseAggregatorSensorPlugin extends DatabaseAggregatorSensorPluginBase
       '#submit' => array(array($this, 'addConditionSubmit')),
     );
 
+    // Add a fieldset to filter verbose output by fields.
+    $form['output_table'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Verbose Fields'),
+      '#prefix' => '<div id="selected-output">',
+      '#suffix' => '</div>',
+      '#tree' => FALSE,
+    );
+    // Add a table for the fields.
+    $form['output_table']['verbose_fields'] = array(
+      '#type' => 'table',
+      '#tree' => TRUE,
+      '#header' => array(
+        'field' => t('Configure verbose fields'),
+      ),
+      '#title' => t('Verbose fields'),
+      '#empty' => t(
+        'Add keys to display in the verbose output.'
+      ),
+    );
+
+    // Fill the fields table with verbose fields to filter the output.
+    $fields = $settings['verbose_fields'];
+
+    if (!$form_state->has('fields_rows')) {
+      $form_state->set('fields_rows', count($fields) + 1);
+    }
+    for ($i = 0; $i < $form_state->get('fields_rows'); $i++) {
+      $form['output_table']['verbose_fields'][$i] = array(
+        'field' => array(
+          '#type' => 'textfield',
+          '#default_value' => isset($fields[$i]) ? $fields[$i] : '',
+          '#title' => t('Field'),
+          '#title_display' => 'invisible',
+          '#size' => 20,
+        ),
+      );
+    }
+    // Select element for available fields.
+    $form['output_table']['fields_add_button'] = array(
+      '#type' => 'submit',
+      '#value' => t('Add another field'),
+      '#ajax' => array(
+        'wrapper' => 'selected-output',
+        'callback' => array($this, 'fieldsReplace'),
+        'method' => 'replace',
+      ),
+      '#submit' => array(array($this, 'addFieldSubmit')),
+    );
+
     return $form;
   }
 
@@ -398,24 +419,13 @@ class DatabaseAggregatorSensorPlugin extends DatabaseAggregatorSensorPluginBase
         $settings['conditions'][] = $condition;
       }
     }
-
-    // Update the verbose output keys.
-    try {
-      $this->currentKeys = $this->sensorConfig->getSetting('keys');
-      $keys = array_filter(explode("\n", $form_state->getValue('keys')));
-      $keys = array_map('trim', $keys);
-      $settings['keys'] = $keys;
-
-      $this->sensorConfig->set('settings', $settings);
-      $this->getQuery()->execute();
-    }
-    catch (DatabaseExceptionWrapper $e) {
-      $settings = $this->sensorConfig->getSettings();
-      $settings['keys'] = $this->currentKeys;
-      $this->sensorConfig->set('settings', $settings);
-      drupal_set_message('Verbose output configuration is invalid, keys were not saved.', 'error');
-      drupal_set_message($e->getMessage(), 'warning');
+    $settings['verbose_fields'] = [];
+    foreach ($form_state->getValue('verbose_fields') as $delta => $field) {
+      if (!empty($field)) {
+        $settings['verbose_fields'][] = $field;
+      }
     }
+    $this->sensorConfig->set('settings', $settings);
   }
 
   /**
@@ -434,7 +444,7 @@ class DatabaseAggregatorSensorPlugin extends DatabaseAggregatorSensorPluginBase
   }
 
   /**
-   * Adds sensor to entity when 'Add field' button is pressed.
+   * Add row to table when pressing 'Add another condition' and rebuild.
    *
    * @param array $form
    *   The form structure array.
@@ -450,6 +460,36 @@ class DatabaseAggregatorSensorPlugin extends DatabaseAggregatorSensorPluginBase
   }
 
   /**
+   * Returns the updated 'output_table' fieldset for replacement by ajax.
+   *
+   * @param array $form
+   *   The updated form structure array.
+   * @param FormStateInterface $form_state
+   *   The form state structure.
+   *
+   * @return array
+   *   The updated form component for the selected fields.
+   */
+  public function fieldsReplace(array $form, FormStateInterface $form_state) {
+    return $form['plugin_container']['settings']['output_table'];
+  }
+
+  /**
+   * Adds another field to the keys table when pressing 'Add another key'.
+   *
+   * @param array $form
+   *   The form structure array.
+   * @param FormStateInterface $form_state
+   *   The form state structure.
+   */
+  public function addFieldSubmit(array $form, FormStateInterface $form_state) {
+    $form_state->setRebuild();
+
+    $form_state->set('fields_rows', $form_state->get('fields_rows') + 1);
+    drupal_set_message(t('Field added.'), 'status');
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
@@ -457,6 +497,11 @@ class DatabaseAggregatorSensorPlugin extends DatabaseAggregatorSensorPluginBase
 
     /** @var \Drupal\Core\Database\Connection $database */
     $database = $this->getService('database');
+    $table = $form_state->getValue(array('settings', 'table'));
+    if (!$database->schema()->tableExists($table)) {
+      $form_state->setErrorByName('settings][table', t('The table %table does not exist in the database %database', ['%table' => $table, '%database' => $database->getConnectionOptions()['database']]));
+      return;
+    }
     $field_name = $form_state->getValue(array(
       'settings',
       'aggregation',
@@ -464,12 +509,31 @@ class DatabaseAggregatorSensorPlugin extends DatabaseAggregatorSensorPluginBase
     ));
     if (!empty($field_name)) {
       // @todo instead of validate, switch to a form select.
-      $table = $form_state->getValue(array('settings', 'table'));
       if (!$database->schema()->fieldExists($table, $field_name)) {
         $form_state->setErrorByName('settings][aggregation][time_interval_field',
-          t('The specified time interval field %name does not exist.', array('%name' => $field_name)));
+          t('The specified time interval field %name does not exist in table %table.', array('%name' => $field_name, $table)));
+      }
+    }
+    $fields = $form_state->getValue('verbose_fields');
+    $new_fields = [];
+    foreach ($fields as $key => $field) {
+      $field_name = $field['field'];
+      if (!empty($field_name)) {
+        if (!$database->schema()->fieldExists($table, $field_name)) {
+          $query = $database->select($table);
+          $query->addField($table, $field_name);
+          try{
+            $query->range(0, 1)->execute();
+          }
+          catch (\Exception $e) {
+            $form_state->setErrorByName('verbose_fields][' . $key . '][field', t('The specified field "%name" does not exist in table "%table".', ['%name' => $field_name, '%table' => $table]));
+            continue;
+          }
+        }
+        $new_fields[] = (array_pop($fields[$key]));
       }
     }
+    $form_state->setValue('verbose_fields', $new_fields);
   }
 
 }
