how to log downloaded files I have a content type with a (private) file field. Content is protected by a node access module.

I would like to log (in a particular way) when a user is about to download a file.

hook_file_download looks like it will do the trick, but on the other hand, its stated purpose is to "control access". I'm letting Drupal Core control access; I just want to log a (successful) download.

Is there a better hook to do this with?
hook_file_download() is invoked in two occasions:


When Drupal is verifying the users have access to the file they are trying to download

function file_download_access($uri) {
  return count(file_download_headers($uri)) &gt; 0;
}

When Drupal is returning the headers for the file to download (and then the data for the file to download)

function file_download() {
  // Merge remainder of arguments from GET['q'], into relative file path.
  $args = func_get_args();
  $scheme = array_shift($args);
  $target = implode('/', $args);
  $uri = $scheme . '://' . $target;
  if (file_stream_wrapper_valid_scheme($scheme) &amp;&amp; file_exists($uri)) {
    $headers = file_download_headers($uri);
    if (count($headers)) {
      file_transfer($uri, $headers);
    }
    drupal_access_denied();
  }
  else {
    drupal_not_found();
  }
  drupal_exit();
}



In both the cases, the function invoking the hook is file_download_headers().

function file_download_headers($uri) {
  // Let other modules provide headers and control access to the file.
  // module_invoke_all() uses array_merge_recursive() which merges header
  // values into a new array. To avoid that and allow modules to override
  // headers instead, use array_merge() to merge the returned arrays.
  $headers = array();
  foreach (module_implements('file_download') as $module) {
    $function = $module . '_file_download';
    $result = $function($uri);
    if ($result == -1) {
      // Throw away the headers received so far.
      $headers = array();
      break;
    }
    if (isset($result) &amp;&amp; is_array($result)) {
      $headers = array_merge($headers, $result);
    }
  }
  return $headers;
}


Watching the Drupal code, I cannot assure the hook is always called twice in row, during the same page request; if it were so, you could take the necessary action when the hook is invoked for the second time.  

I would rather change the callbacks for $directory_path . '/styles/%image_style' (where $directory_path contains the value returned from file_stream_wrapper_get_instance_by_scheme('public')-&gt;getDirectoryPath()), system/files/styles/%image_style, system/files, and system/temporary to verify when a file is going to be downloaded, and log what happening.

This is not going to change in Drupal 8, as it doesn't split hook_file_download() in two hooks.