diff --git a/better_statistics.admin.inc b/better_statistics.admin.inc
index bccc75c..cf11d73 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,109 @@ function _better_statistics_form_statistics_settings_form_alter(&$form, &$form_s
     );
   }
 
+  // Restrictions settings.
+  $form['restrictions_settings'] = array(
+    '#type' => 'vertical_tabs',
+    '#weight' => -5,
+  );
+  $form['access_log_restrictions_title'] = array(
+    '#type' => 'item',
+    '#title' => t('Access log restrictions'),
+    '#description' => t('Define restrictions on when page requests are logged in the access log. As an example, you may want to disable logging in admin areas 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'),
+      '#group' => 'restrictions_settings',
+    );
+    $form['access_log_restrictions']['caching']['log_cached_status'] = array(
+      '#markup' => t('Tracking of page requests served from cache is currently !log_cached_status. Visit !the_performance_configuration_page to change settings.', array(
+        '!log_cached_status' => '<strong>' . variable_get('statistics_access_log_cached', TRUE) ? t('enabled') : t('disabled') . '</strong>',
+        '!the_performance_configuration_page' => l(t('the performance configuration page'), 'admin/config/development/performance'),
+      )),
+    );
+  }
+  // Page-based restrictions.
+  $form['access_log_restrictions']['pages'] = array(
+    '#type' => 'fieldset',
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#title' => t('Pages'),
+    '#group' => 'restrictions_settings',
+  );
+  $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'),
+    '#group' => 'restrictions_settings',
+  );
+  $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 +217,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 on cached page requests can negatively impact performance a scalability.'),
+    '#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..0b513b6 100644
--- a/better_statistics.api.php
+++ b/better_statistics.api.php
@@ -182,5 +182,22 @@ function hook_better_statistics_fields() {
 }
 
 /**
+ * Allows modules to react just before Better Statistics performs access log
+ * field data collection and just after all module.statistics.inc files have
+ * been loaded.
+ *
+ * A good use of this is to call better_statistics_request_is_loggable().
+ *
+ * Implementations of this hook should be placed in your module.statistics.inc.
+ */
+function hook_better_statistics_prelog() {
+  // Never record statistics for user 1.
+  global $user;
+  if ($user->uid == 1) {
+    better_statistics_request_is_loggable(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..ac1b151 100644
--- a/better_statistics.module
+++ b/better_statistics.module
@@ -81,21 +81,30 @@ 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();
+    // Load all relevant module.statistics.inc files for hook invocations.
+    better_statistics_load_active_incs();
 
-    // 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();
+    // Allow all modules to react before logging begins.
+    module_invoke_all('better_statistics_prelog');
+
+    // Log the request if the request is loggable.
+    if (better_statistics_request_is_loggable()) {
+      // Get all declared fields and their computed values.
+      $fields = better_statistics_get_fields_data();
 
-      // Log the error.
-      watchdog('better statistics', 'There was an error collecting statistics data:<br /><br />@error', array('@error' => $e->getMessage()), WATCHDOG_ERROR);
+      // 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 +152,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 +217,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 +236,50 @@ 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 the loggability of the current request.
+ *
+ * @return
+ *   TRUE if the current page can be logged, FALSE otherwise.
+ */
+function better_statistics_request_is_loggable($allow_logging = NULL) {
+  $allow_logging_static = &drupal_static(__FUNCTION__, TRUE);
+
+  if (isset($allow_logging)) {
+    $allow_logging_static = $allow_logging;
+  }
+
+  return $allow_logging_static;
+}
+
+/**
  * 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..2afff75 100644
--- a/better_statistics.statistics.inc
+++ b/better_statistics.statistics.inc
@@ -119,3 +119,47 @@ function better_statistics_get_field_value($field) {
       return truncate_utf8($_SERVER['HTTP_USER_AGENT'], 255);
   }
 }
+
+
+/**
+ * Implements hook_better_statistics_prelog().
+ *
+ * Better Statistics provides inclusion/exclusion restrictions for collecting
+ * access log data based on request paths, user roles and cache status.
+ */
+function better_statistics_better_statistics_prelog() {
+  // 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 && !variable_get('statistics_access_log_cached', TRUE)) {
+    better_statistics_request_is_loggable(FALSE);
+  }
+
+  // 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)) {
+      better_statistics_request_is_loggable(FALSE);
+    }
+    // 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)) {
+      better_statistics_request_is_loggable(FALSE);
+    }
+  }
+
+  // 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)) {
+      better_statistics_request_is_loggable(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.'));
   }
 }
