diff --git a/better_statistics.admin.inc b/better_statistics.admin.inc
index bccc75c..c43d64e 100644
--- a/better_statistics.admin.inc
+++ b/better_statistics.admin.inc
@@ -14,13 +14,15 @@ function _better_statistics_form_statistics_settings_form_alter(&$form, &$form_s
   $log_description = &$form['access']['statistics_enable_access_log']['#description'];
   $log_description .= ' ' . t('Also required by the Better Statistics module.');
 
-  // Create a fieldset for our settings.
+  $form['access']['#weight'] = -10;
+
+  // Create a fieldset for data collection settings.
   $form['better_statistics'] = array(
     '#type' => 'fieldset',
     '#collapsible' => FALSE,
-    '#title' => t('Better statistics settings'),
+    '#title' => t('Access Log - Data Collection'),
     '#description' => t('Select the data you would like to collect on each page request. Note that unchecking a field below will permanently delete all data collected for that field.'),
-    '#weight' => 0,
+    '#weight' => -8,
     '#tree' => TRUE,
     // Only show this fieldset if the accesslog is enabled.
     '#states' => array(
@@ -105,6 +107,105 @@ function _better_statistics_form_statistics_settings_form_alter(&$form, &$form_s
     );
   }
 
+  // Restrictions settings.
+  $form['access_log_restrictions'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Access Log - Restrictions'),
+    '#description' => t('Define <strong>restrictions</strong> to the pages whose accesses have to be logged. As an example, you may want to exclude, for performance reasons, logging for pages served from cache. Or, only log access for specific user roles.'),
+    '#weight' => -6,
+    // Only show this fieldset if the accesslog is enabled.
+    '#states' => array(
+      'visible' => array(
+        ':input[name="statistics_enable_access_log"]' => array('checked' => TRUE),
+      ),
+    ),
+  );
+  // Cache-based restrictions reference.
+  if (variable_get('cache', 0)) {
+    $form['access_log_restrictions']['caching'] = array(
+      '#type' => 'fieldset',
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+      '#title' => t('Cache'),
+    );
+    $form['access_log_restrictions']['caching']['log_cached_status'] = array(
+      '#markup' => t(
+        "Tracking of page requests served through cache is currently <strong>@log_cached_status</strong>. Visit <a href='!url'>Performance configuration</a> to change settings.",
+        array(
+          '@log_cached_status' => variable_get('statistics_access_log_cached', TRUE) ? t('enabled') : t('disabled'),
+          '!url' => url('admin/config/development/performance'),
+        )
+      ),
+    );
+  }
+  // Page-based restrictions.
+  $form['access_log_restrictions']['pages'] = array(
+    '#type' => 'fieldset',
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#title' => t('Pages'),
+  );
+  $page_options = array(0 => t('Log all pages'), 1 => t('Log pages based on inclusion/exclusion patterns'));
+  $form['access_log_restrictions']['pages']['statistics_access_log_pages'] = array(
+    '#type' => 'radios',
+    '#options' => $page_options,
+    '#title' => t("Page requests to be logged"),
+    '#default_value' => variable_get('statistics_access_log_pages', 0),
+  );
+  $form['access_log_restrictions']['pages']['statistics_access_log_include_pages'] = array(
+    '#type' => 'textarea',
+    '#rows' => 2,
+    '#title' => t("Include page request paths"),
+    '#default_value' => variable_get('statistics_access_log_include_pages', '*'),
+    '#description' => t("Enter relative request paths, one per line. Use Drupal internal request paths, not the URL aliases. The asterisk by itself means any page on your site."),
+    // Only show this if the logging is based on patterns.
+    '#states' => array(
+      'visible' => array(
+        ':input[name="statistics_access_log_pages"]' => array('value' => 1),
+      ),
+    ),
+  );
+  $form['access_log_restrictions']['pages']['statistics_access_log_exclude_pages'] = array(
+    '#type' => 'textarea',
+    '#rows' => 3,
+    '#title' => t("Exclude page request paths"),
+    '#default_value' => variable_get('statistics_access_log_exclude_pages', ''),
+    '#description' => t('Exclude these paths even if they are part of the inclusions specified above. As above, one path specification per line.'),
+    // Only show this if the logging is based on patterns.
+    '#states' => array(
+      'visible' => array(
+        ':input[name="statistics_access_log_pages"]' => array('value' => 1),
+      ),
+    ),
+  );
+  // Role-based restrictions.
+  $form['access_log_restrictions']['roles'] = array(
+    '#type' => 'fieldset',
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#title' => t('Roles'),
+  );
+  $role_options = array(0 => t('Log all roles'), 1 => t('Log specific roles'));
+  $form['access_log_restrictions']['roles']['statistics_access_log_roles'] = array(
+    '#type' => 'radios',
+    '#options' => $role_options,
+    '#title' => t("Roles to be logged"),
+    '#default_value' => variable_get('statistics_access_log_roles', 0),
+  );
+  $form['access_log_restrictions']['roles']['statistics_access_log_include_roles'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t("User roles"),
+    '#default_value' => variable_get('statistics_access_log_include_roles', array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID)),
+    '#options' => user_roles(),
+    '#description' => t('Only requests from users with the selected roles will be included in the access log.'),
+    // Only show this if the logging is based on specific roles.
+    '#states' => array(
+      'visible' => array(
+        ':input[name="statistics_access_log_roles"]' => array('value' => 1),
+      ),
+    ),
+  );
+
   // Add a submit handler to handle schema changes as a result of changes here.
   // Fire before the system settings; we don't want it to save variables.
   array_unshift($form['#submit'], 'better_statistics_settings_form_submit');
@@ -112,6 +213,25 @@ function _better_statistics_form_statistics_settings_form_alter(&$form, &$form_s
 
 
 /**
+ * Makes alterations to the core site performance settings configuration form.
+ */
+function _better_statistics_form_system_performance_settings_alter(&$form, &$form_state, $form_id) {
+  $form['caching']['statistics_access_log_cached'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Log access statistics for pages served by the cache'),
+   '#description' => t("Logging access statistics for cached pages generates significant overhead."),
+    '#default_value' => variable_get('statistics_access_log_cached', TRUE),
+    // Only show this field if caching is enabled.
+    '#states' => array(
+      'visible' => array(
+        ':input[name="cache"]' => array('checked' => TRUE),
+      ),
+    ),
+  );
+}
+
+
+/**
  * Submit handler for Better Statistics configuration settings.
  */
 function _better_statistics_settings_form_submit($form, &$form_state) {
diff --git a/better_statistics.api.php b/better_statistics.api.php
index 440a4c0..ae7f462 100644
--- a/better_statistics.api.php
+++ b/better_statistics.api.php
@@ -182,5 +182,24 @@ function hook_better_statistics_fields() {
 }
 
 /**
+ * Tell Statistics API to skip data collection on this request. That is to say,
+ * use this to declare you DO NOT want statistics collected under your specific
+ * circumstances.
+ *
+ * @return
+ *   A boolean TRUE if statistics should NOT be collected on this request.
+ *   Otherwise, FALSE.
+ */
+function hook_better_statistics_skip() {
+  // Never record statistics for user 1.
+  global $user;
+  if ($user->uid == 1) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/**
  * @}
  */
diff --git a/better_statistics.install b/better_statistics.install
index 5adb77f..f566ed4 100644
--- a/better_statistics.install
+++ b/better_statistics.install
@@ -54,4 +54,10 @@ function better_statistics_uninstall() {
   }
 
   variable_del('better_statistics_fields');
+  variable_del('statistics_access_log_cached');
+  variable_del('statistics_access_log_pages');
+  variable_del('statistics_access_log_include_pages');
+  variable_del('statistics_access_log_exclude_pages');
+  variable_del('statistics_access_log_roles');
+  variable_del('statistics_access_log_include_roles');
 }
diff --git a/better_statistics.module b/better_statistics.module
index 600e687..961d6e1 100644
--- a/better_statistics.module
+++ b/better_statistics.module
@@ -81,21 +81,36 @@ function better_statistics_exit() {
     drupal_bootstrap(DRUPAL_BOOTSTRAP_SESSION);
     include_once DRUPAL_ROOT . '/includes/unicode.inc';
 
-    // Get all declared fields and their computed values.
-    $fields = better_statistics_get_fields_data();
-
-    // Now that we have data, try to insert it.
-    try {
-      db_insert('accesslog')->fields($fields)->execute();
+    // Load all relevant module.statistics.inc files for hook invocations.
+    better_statistics_load_active_incs();
+
+    // Test if Statistics should be collected on this request.
+    $skip = FALSE;
+    foreach (module_implements('better_statistics_skip') as $module) {
+      $skip_test = $module . '_' . 'better_statistics_skip';
+      if ($skip_test()) {
+        $skip = TRUE;
+       break;
+      }
     }
-    catch (Exception $e) {
-      // At least log core fields.
-      $defaults = better_statistics_get_default_fields();
-      $core_fields = array_intersect_key($fields, $defaults);
-      db_insert('accesslog')->fields($core_fields)->execute();
-
-      // Log the error.
-      watchdog('better statistics', 'There was an error collecting statistics data:<br /><br />@error', array('@error' => $e->getMessage()), WATCHDOG_ERROR);
+    // Don't collect statistics if we're told to skip.
+    if (!$skip) {
+      // Get all declared fields and their computed values.
+      $fields = better_statistics_get_fields_data();
+
+      // Now that we have data, try to insert it.
+      try {
+        db_insert('accesslog')->fields($fields)->execute();
+      }
+      catch (Exception $e) {
+        // At least log core fields.
+        $defaults = better_statistics_get_default_fields();
+        $core_fields = array_intersect_key($fields, $defaults);
+        db_insert('accesslog')->fields($core_fields)->execute();
+
+        // Log the error.
+        watchdog('better statistics', 'There was an error collecting statistics data:<br /><br />@error', array('@error' => $e->getMessage()), WATCHDOG_ERROR);
+      }
     }
   }
 
@@ -143,6 +158,17 @@ function better_statistics_form_statistics_settings_form_alter(&$form, &$form_st
 
 
 /**
+ * Implements hook_form_FORM_ID_alter().
+ *
+ * @see _better_statistics_form_system_performance_settings_form_alter()
+ */
+function better_statistics_form_system_performance_settings_alter(&$form, &$form_state, $form_id) {
+  module_load_include('inc', 'better_statistics', 'better_statistics.admin');
+  _better_statistics_form_system_performance_settings_alter($form, $form_state, $form_id);
+}
+
+
+/**
  * Submit handler for the Better Statistics configuration form.
  *
  * @see _better_statistics_settings_form_submit()
@@ -197,22 +223,14 @@ function better_statistics_get_default_fields() {
  * Returns data for all valid, declared fields in preparation for DB insertion.
  */
 function better_statistics_get_fields_data() {
-  // Include this module's API file because of how core fields are implemented.
-  require_once(dirname(__FILE__) . '/better_statistics.statistics.inc');
+  // Ensure all module.statistics.inc files are loaded.
+  better_statistics_load_active_incs();
 
   $fields = variable_get('better_statistics_fields', better_statistics_get_default_fields());
   $field_data = array();
 
   // Loop through all custom fields.
   foreach ($fields as $field => $data) {
-    // If there's an inc file and it hasn't been loaded yet, load it.
-    if (isset($data['_file']) && !isset($already[$data['_file']])) {
-      if (file_exists(DRUPAL_ROOT . '/' . $data['_file'])) {
-        require_once(DRUPAL_ROOT . '/' . $data['_file']);
-        $already[$data['_file']] = TRUE;
-      }
-    }
-
     // Only insert data into this field if there's a callback to get data.
     if (is_callable($data['callback'])) {
       $field_data[$field] = $data['callback']($field);
@@ -224,6 +242,34 @@ function better_statistics_get_fields_data() {
 
 
 /**
+ * Loads module.statistics.inc files for all active fields.
+ */
+function better_statistics_load_active_incs() {
+  // Prevent this function from loading it multiple times.
+  static $loaded;
+
+  if (empty($loaded)) {
+    $loaded = TRUE;
+
+    // Include this module's API file because of how core fields are implemented.
+    require_once(dirname(__FILE__) . '/better_statistics.statistics.inc');
+
+    $fields = variable_get('better_statistics_fields', better_statistics_get_default_fields());
+
+    // Loop through each declaring field and require associated files.
+    foreach ($fields as $field => $data) {
+      // If there's an inc file and it hasn't been loaded yet, load it.
+      if (isset($data['_file'])) {
+        if (file_exists(DRUPAL_ROOT . '/' . $data['_file'])) {
+          require_once(DRUPAL_ROOT . '/' . $data['_file']);
+       }
+      }
+    }
+ }
+}
+
+
+/**
  * Determines whether or not the current request is being served from cache.
  *
  * Note that you may need to use === to determine the cache status of the page,
diff --git a/better_statistics.statistics.inc b/better_statistics.statistics.inc
index f38a704..6f7d86e 100644
--- a/better_statistics.statistics.inc
+++ b/better_statistics.statistics.inc
@@ -119,3 +119,53 @@ function better_statistics_get_field_value($field) {
       return truncate_utf8($_SERVER['HTTP_USER_AGENT'], 255);
   }
 }
+
+
+/**
+ * Implements hook_better_statistics_skip().
+ *
+ * Better Statistics provides inclusion/exclusion restrictions for collecting
+ * access logs based on request paths, user roles and cache status.
+ *
+ * @return
+ *   A boolean TRUE if statistics should NOT be collected on this request.
+ *   Otherwise, FALSE.
+ */
+function better_statistics_better_statistics_skip() {
+  // Skip if page is served from cache and Better Statistics is set to
+  // exclude logging cached requests.
+  $cache_status = better_statistics_served_from_cache();
+  if ($cache_status === TRUE and !variable_get('statistics_access_log_cached', TRUE)) {
+    return TRUE;
+ }
+
+  // If page-based restrictions are enabled, check inclusion/exclusion.
+  if (variable_get('statistics_access_log_pages', 0) == 1) {
+    // Make sure drupal_match_path() is available.
+    require_once DRUPAL_ROOT . '/' . variable_get('path_inc', 'includes/path.inc');
+    // Skip if page request path is not in the included paths.
+    $path = truncate_utf8($_GET['q'], 255);
+    $include_requests = variable_get('statistics_access_log_include_pages', '*');
+    if (!drupal_match_path($path, $include_requests)) {
+      return TRUE;
+    }
+    // Skip if page request path is in the excluded paths.
+    $exclude_requests = variable_get('statistics_access_log_exclude_pages', '');
+    if (drupal_match_path($path, $exclude_requests)) {
+      return TRUE;
+    }
+  }
+
+  // If role-based restrictions are enabled, check inclusion/exclusion.
+  if (variable_get('statistics_access_log_roles', 0) == 1) {
+    // Skip if user is not part of a role included.
+    global $user;
+    $role_includes = variable_get('statistics_access_log_include_roles', array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID));
+    $roles_check = array_intersect($role_includes, array_keys($user->roles));
+    if (empty($roles_check)) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
diff --git a/better_statistics.test b/better_statistics.test
index 3964433..677a942 100644
--- a/better_statistics.test
+++ b/better_statistics.test
@@ -12,6 +12,7 @@
 class BetterStatisticsTest extends DrupalWebTestCase {
 
   protected $stats_admin = 'admin/config/system/statistics';
+  protected $perf_admin = 'admin/config/development/performance';
 
   public static function getInfo() {
     return array(
@@ -128,5 +129,68 @@ class BetterStatisticsTest extends DrupalWebTestCase {
     $query = db_query('SELECT aid FROM {accesslog}');
     $rows = $query->rowCount();
     $this->assertTrue($rows == 3, t('Accesslog data being collected when page cache is enabled (cache hit).'));
+
+    // Create a user and log it in.
+    $this->admin_user = $this->drupalCreateUser(array(
+      'access administration pages',
+      'administer statistics',
+      'access content',
+      'access statistics',
+      'administer site configuration',  // to be able to access performance settings
+    ));
+    $this->drupalLogin($this->admin_user);
+
+    // Disable logging of cached page requests.
+    $edit = array(
+      'statistics_access_log_cached' => FALSE,
+    );
+    $this->drupalPost($this->perf_admin, $edit, t('Save configuration'));
+
+    // Check page access is not logged.
+    $this->drupalLogout();
+    db_delete('accesslog')->execute();
+    // First get will be a MISS.
+    $this->drupalGet('node');
+    // Second get will be a HIT.
+    $this->drupalGet('node');
+    $query = db_query('SELECT aid FROM {accesslog}');
+    $rows = $query->rowCount();
+    // We expect the MISS to be logged, the HIT not.
+    $this->assertTrue($rows == 1, t('Accesslog data not being collected when page cache is enabled, and logging of cached paged is disabled.'));
+
+    // Re-enable logging of cached page requests, disable logging of authenticated users.
+    $this->drupalLogin($this->admin_user);
+    $edit = array(
+      'statistics_access_log_cached' => TRUE,
+    );
+    $this->drupalPost($this->perf_admin, $edit, t('Save configuration'));
+    $edit = array(
+      'statistics_access_log_roles' => 1,
+      'statistics_access_log_include_roles[2]' => FALSE,
+    );
+    $this->drupalPost($this->stats_admin, $edit, t('Save configuration'));
+
+    // Check page access is not logged.
+    db_delete('accesslog')->execute();
+    $this->drupalGet('node');
+    $query = db_query('SELECT aid FROM {accesslog}');
+    $rows = $query->rowCount();
+    $this->assertTrue($rows == 0, t('Accesslog data not being collected when logging is disabled for authenticated users.'));
+
+    // Re-enable logging of all roles requests, disable logging admin pages.
+    $edit = array(
+      'statistics_access_log_roles' => 0,
+      'statistics_access_log_include_roles[2]' => '2',
+      'statistics_access_log_pages' => 1,
+      'statistics_access_log_exclude_pages' => 'admin/*',
+    );
+    $this->drupalPost($this->stats_admin, $edit, t('Save configuration'));
+
+    // Check page access is not logged.
+    db_delete('accesslog')->execute();
+    $this->drupalGet('admin/reports/dblog');
+    $query = db_query('SELECT aid FROM {accesslog}');
+    $rows = $query->rowCount();
+    $this->assertTrue($rows == 0, t('Accesslog data not being collected when there is a defined exclusion pattern.'));
   }
 }
