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 75d4a86..551b128 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 dccaaea..3d623e8 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 08238e5..0071c59 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 c094ce5..da4013c 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 d567a5e..c5c3eee 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 bb1820b..b6b91cd 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 731e15d..99f6d81 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 5e50f45..b97cd64 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 6d99f1e..e8f7725 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 6f090c5..7b7fd38 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 21fd1b3..2736ef9 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
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 3655608..14b7d6c 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
@@ -18,6 +18,9 @@ settings:
     -
       field: 'type'
       value: 'page'
+  verbose_fields:
+    - id
+    - label
 thresholds:
   type: 'falls'
   warning: 2
diff --git a/src/Plugin/monitoring/SensorPlugin/ContentEntityAggregatorSensorPlugin.php b/src/Plugin/monitoring/SensorPlugin/ContentEntityAggregatorSensorPlugin.php
index 0228c25..6a3fe5b 100644
--- a/src/Plugin/monitoring/SensorPlugin/ContentEntityAggregatorSensorPlugin.php
+++ b/src/Plugin/monitoring/SensorPlugin/ContentEntityAggregatorSensorPlugin.php
@@ -188,6 +188,8 @@ class ContentEntityAggregatorSensorPlugin extends DatabaseAggregatorSensorPlugin
   public function resultVerbose(SensorResultInterface $result) {
     $output = [];
 
+    /** @var \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_manager */
+    $field_type_manager = \Drupal::service('plugin.manager.field.field_type');
     // Fetch the last 10 matching entries, unaggregated.
     $entity_ids = $this->getEntityQuery()
       ->range(0, 10)
@@ -202,6 +204,7 @@ class ContentEntityAggregatorSensorPlugin extends DatabaseAggregatorSensorPlugin
     // );
 
     // Load entities.
+    $entity_type = $this->entityManager->getDefinition($this->getEntityTypeId());
     $entity_type_id = $this->getEntityTypeId();
     $entities = $this->entityManager
       ->getStorage($entity_type_id)
@@ -217,30 +220,12 @@ class ContentEntityAggregatorSensorPlugin extends DatabaseAggregatorSensorPlugin
       $row = [];
       foreach ($fields as $field) {
         switch ($field) {
-          case 'uuid':
-            $row[] = $entity->uuid();
-            break;
-
           case 'id':
             $row[] = $entity->id();
             break;
 
           case 'label':
-            $entity_link = array(
-              '#type' => 'link',
-              '#title' => $entity->label(),
-              '#url' => $entity->urlInfo(),
-            );
-
-            $row[] = \Drupal::service('renderer')->renderPlain($entity_link);
-            break;
-
-          case 'langcode':
-            $row[] = $entity->language()->getName();
-            break;
-
-          case 'bundle':
-            $row[] = $entity->bundle();
+            $row[] = $entity->hasLinkTemplate('canonical') ? $entity->link() : $entity->label();
             break;
 
           default:
@@ -249,10 +234,17 @@ class ContentEntityAggregatorSensorPlugin extends DatabaseAggregatorSensorPlugin
               try {
                 // Get the main property as a fallback if the field can not be
                 // viewed.
-                $property = $entity->getFieldDefinition($field)->getFieldStorageDefinition()->getMainPropertyName();
-                $value = $entity->$field->view(['label' => 'hidden']);
-                // Try to render the field, fall back the main property.
-                $row[] = $value ? \Drupal::service('renderer')->renderPlain($value) : $entity->$field->$property;
+                $field_type = $entity->getFieldDefinition($field)->getFieldStorageDefinition()->getType();
+                // If the field type has a default formatter, try to view it.
+                if (isset($field_type_manager->getDefinition($field_type)['default_formatter'])) {
+                  $value = $entity->$field->view(['label' => 'hidden']);
+                  $row[] = \Drupal::service('renderer')->renderPlain($value);
+                }
+                else {
+                  // Fall back to the main property.
+                  $property = $entity->getFieldDefinition($field)->getFieldStorageDefinition()->getMainPropertyName();
+                  $row[] = SafeMarkup::checkPlain($entity->$field->$property);
+                }
               } catch (\Exception $e) {
                 // Catch any exception and display as an error.
                 drupal_set_message(t('Error while trying to display %field: @error', ['%field' => $field, '@error' => $e->getMessage()]), 'error');
@@ -433,21 +425,21 @@ class ContentEntityAggregatorSensorPlugin extends DatabaseAggregatorSensorPlugin
 
     // Fill the sensors table with form elements for each sensor.
     $form['verbose_fields'] = array(
-      '#type' => 'fieldset',
+      '#type' => 'details',
       '#title' => t('Verbose Output configuration'),
       '#prefix' => '<div id="selected-output">',
       '#suffix' => '</div>',
+      '#open' => TRUE,
     );
     $entity_type = $this->entityManager->getDefinition($this->getEntityTypeId());
-    $form['verbose_fields']['available_fields'] = [
-      '#markup' => t('Available Fields for entity %type: <b>%fields</b>', [
-        '%type' => $entity_type->getLabel(),
-        '%fields' => implode(', ', array_keys($this->entityManager->getBaseFieldDefinitions($this->getEntityTypeId())))
-      ]),
-    ];
+    $available_fields = array_merge(['id', 'label'], array_keys($this->entityManager->getBaseFieldDefinitions($entity_type->id())));
+    $form['verbose_fields']['#description'] = t('Available Fields for entity type %type: %fields.', [
+      '%type' => $entity_type->getLabel(),
+      '%fields' => implode(', ', $available_fields)
+    ]);
 
     // Fill the sensors table with form elements for each sensor.
-    $fields = $this->sensorConfig->getSetting('verbose_fields', ['id']);
+    $fields = $this->sensorConfig->getSetting('verbose_fields', ['id', 'label']);
     if (!$form_state->has('fields_rows')) {
       $form_state->set('fields_rows', count($fields) + 1);
     }
diff --git a/src/Plugin/monitoring/SensorPlugin/DatabaseAggregatorSensorPlugin.php b/src/Plugin/monitoring/SensorPlugin/DatabaseAggregatorSensorPlugin.php
index 1a1b3ac..0aa5d6d 100644
--- a/src/Plugin/monitoring/SensorPlugin/DatabaseAggregatorSensorPlugin.php
+++ b/src/Plugin/monitoring/SensorPlugin/DatabaseAggregatorSensorPlugin.php
@@ -24,7 +24,6 @@ use Drupal\Component\Utility\SafeMarkup;
  *   description = @Translation("Database aggregator able to query a single db table."),
  *   addable = TRUE
  * )
- *
  */
 class DatabaseAggregatorSensorPlugin extends DatabaseAggregatorSensorPluginBase implements ExtendedInfoSensorPluginInterface {
 
@@ -59,13 +58,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 +119,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 ($fields as $field) {
+        $query->addField($this->sensorConfig->getSetting('table'), $field);
       }
     }
 
@@ -249,12 +241,11 @@ 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);
 
-    $settings = $this->sensorConfig->getSettings();
     $form['table'] = array(
       '#type' => 'textfield',
       '#default_value' => $this->sensorConfig->getSetting('table'),
@@ -278,39 +269,15 @@ class DatabaseAggregatorSensorPlugin extends DatabaseAggregatorSensorPluginBase
       '#type' => 'table',
       '#tree' => TRUE,
       '#header' => array(
-        'field' => t('Field'),
+        'field' => t('Field key'),
         'operator' => t('Operator'),
         'value' => t('Value'),
       ),
-      '#empty' => t(
-        'Add conditions to filter the results.'
-      ),
+      '#empty' => t('Add conditions to filter the results.'),
     );
 
-    // 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 = [];
-    }
 
     if (!$form_state->has('conditions_rows')) {
       $form_state->set('conditions_rows', count($conditions) + 1);
@@ -356,7 +323,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'),
@@ -365,6 +332,54 @@ 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_key' => t('Field key'),
+      ),
+      '#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 = $this->sensorConfig->getSetting('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++) {
+      $field = isset($fields[$i]) ? $fields[$i] : $i;
+      $form['output_table']['verbose_fields'][$field] = array(
+        // This table only has one column called 'field_key'.
+        'field_key' => array(
+          '#type' => 'textfield',
+          '#default_value' => (is_int($field)) ? '' : $field,
+          '#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;
   }
 
@@ -401,12 +416,7 @@ class DatabaseAggregatorSensorPlugin extends DatabaseAggregatorSensorPluginBase
    */
   public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
     parent::submitConfigurationForm($form, $form_state);
-
-    /** @var \Drupal\monitoring\Form\SensorForm $sensor_form */
-    $sensor_form = $form_state->getFormObject();
-    /** @var \Drupal\monitoring\SensorConfigInterface $sensor_config */
-    $sensor_config = $sensor_form->getEntity();
-    $settings = $sensor_config->getSettings();
+    $settings = $this->sensorConfig->getSettings();
 
     // Cleanup conditions, remove empty.
     $settings['conditions'] = [];
@@ -416,23 +426,15 @@ class DatabaseAggregatorSensorPlugin extends DatabaseAggregatorSensorPluginBase
       }
     }
 
-    // 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;
+    // Update the verbose output fields.
+    $settings['verbose_fields'] = [];
+    foreach ($form_state->getValue('verbose_fields') as $field) {
+      if (!empty($field['field_key'])) {
+        $settings['verbose_fields'][] = $field['field_key'];
+      }
+    }
 
-      $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');
-    }
+    $this->sensorConfig->set('settings', $settings);
   }
 
   /**
@@ -451,7 +453,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.
@@ -467,6 +469,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) {
@@ -474,6 +506,17 @@ class DatabaseAggregatorSensorPlugin extends DatabaseAggregatorSensorPluginBase
 
     /** @var \Drupal\Core\Database\Connection $database */
     $database = $this->getService('database');
+    $table = $form_state->getValue(array('settings', 'table'));
+    $query = $database->select($table);
+    if (!$database->schema()->tableExists($table)) {
+      try {
+        $query->range(0, 1)->execute();
+      }
+      catch (\Exception $e) {
+        $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',
@@ -481,10 +524,26 @@ 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' => $table)));
+      }
+    }
+
+    // Validate verbose_fields.
+    $fields = $form_state->getValue('verbose_fields');
+    foreach ($fields as $key => $field) {
+      $query = $database->select($table);
+      $field_name = $field['field_key'];
+      if (!empty($field_name) && !$database->schema()->fieldExists($table, $field_name)) {
+        $query->addField($table, $field_name);
+        try {
+          $query->range(0, 1)->execute();
+        }
+        catch (\Exception $e) {
+          $form_state->setErrorByName("verbose_fields][$key][field_key", t('The field %field does not exist in the table "%table".', ['%field' => $field_name, '%table' => $table]));
+          continue;
+        }
       }
     }
   }
diff --git a/src/Tests/MonitoringCoreWebTest.php b/src/Tests/MonitoringCoreWebTest.php
index 2218508..a7f40d9 100644
--- a/src/Tests/MonitoringCoreWebTest.php
+++ b/src/Tests/MonitoringCoreWebTest.php
@@ -55,16 +55,16 @@ class MonitoringCoreWebTest extends MonitoringTestBase {
     $this->assertTrue($message == 'Session opened for .', 'Found replaced message in output.');
     $this->assertText('Session opened for ' . $test_user->label());
     // Remove variables from the fields and assert message has no replacements.
-    $this->drupalPostForm('admin/config/system/monitoring/sensors/user_successful_logins', ['keys' => 'wid' . PHP_EOL . 'message'], t('Save'));
+    $this->drupalPostForm('admin/config/system/monitoring/sensors/user_successful_logins', ['verbose_fields[variables][field_key]' => ''], t('Save'));
     $this->drupalGet('admin/reports/monitoring/sensors/user_successful_logins');
     $xpath = $this->xpath('//fieldset[@id="edit-verbose"]/div[@class="fieldset-wrapper"]/table/tbody/tr[@class="entity odd"]');
     $wid = (string) $xpath[0]->td[0];
     $message = (string) $xpath[0]->td[1];
     $this->assertTrue($wid == 14, 'Found WID in verbose output');
     $this->assertTrue($message == 'Session opened for %name.', 'Found unreplaced message in output.');
-    // Test wrong configuration (messages field does not exist).
-    $this->drupalPostForm('admin/config/system/monitoring/sensors/user_successful_logins', ['keys' => 'wid' . PHP_EOL . 'messages'], t('Save'));
-    $this->assertText('Verbose output configuration is invalid, keys were not saved.');
+    // Test field validation.
+    $this->drupalPostForm('admin/config/system/monitoring/sensors/user_successful_logins', ['verbose_fields[2][field_key]' => 'horstname'], t('Save'));
+    $this->assertText('The field horstname does not exist in the table "watchdog".');
   }
 
   /**
@@ -419,7 +419,7 @@ class MonitoringCoreWebTest extends MonitoringTestBase {
     $this->assertLink($node3->label());
     $this->clickLink(t('Edit'));
     // Assert some of the 'available fields'.
-    $this->assertText('Content: nid, uuid, vid, type, langcode, title, uid, status, created, changed, promote, sticky, revision_timestamp, revision_uid,');
+    $this->assertText('Available Fields for entity type Content: id, label, nid, uuid, vid, type, langcode, title, uid, status, created, changed, promote, sticky, revision_timestamp, revision_uid, revision_log, revision_translation_affected, default_langcode.');
     $this->assertFieldByName('conditions[0][field]', 'term_reference.target_id');
     $this->assertFieldByName('conditions[0][value]', $term1->id());
 
