Advanced statistics for Drupal: most viewed nodes in a week, month, ...

Submitted by Jochus on Wed, 08/12/2010 - 10:13 | Posted in: Drupal

I think most of the Drupal developers know the Statistics module, which makes part of the Core of D6. It basically logs access statistics for your site. Every time a node is viewed, a counter gets updated. This counter value is stored in the node_counter table, and gets reset each day at 00 AM.

The most important thing is the hook_cron() implementation:

 * Implementation of hook_cron().
function statistics_cron() {
  $statistics_timestamp = variable_get('statistics_day_timestamp', '');
  if ((time() - $statistics_timestamp) >= 86400) {
    // Reset day counts.
    db_query('UPDATE {node_counter} SET daycount = 0');
    variable_set('statistics_day_timestamp', time());
  // Clean up expired access logs.
  if (variable_get('statistics_flush_accesslog_timer', 259200) > 0) {
    db_query('DELETE FROM {accesslog} WHERE timestamp < %d', time() - variable_get('statistics_flush_accesslog_timer', 259200));

This function will check if we are 24 hours later since the last statistics check. If we are, it will clean all node_counter values. But for us, this was pretty annoying, as we wanted to keep track of older statistics. We wanted to know, "the most viewed" nodes in the last week, month, etc, etc, ...

We started looking around for a contrib module, but really, there was no contrib module that could satisfy our requirements. Most of the contrib modules just bring to much sh*t :-).

So what did we do? We created our own custom Statistics module!

  • We created a custom variable which keeps track when we ran our custom statistics system the last time
  • If we are 00 AM (or later), copy all values from node_counter to a custom table, and index it with a timestamp
  • The structure of this table is defined as:
  • +----------+------------------+------+-----+---------+-------+
    | FIELD    | TYPE             | NULL | KEY | DEFAULT | Extra |
    | DATE     | INT(10) UNSIGNED | NO   | PRI | NULL    |       |
    | nid      | INT(10) UNSIGNED | NO   | PRI | NULL    |       |
    | daycount | INT(10) UNSIGNED | NO   |     | NULL    |       |

  • Reset the node_counter table
  • Adjust the variable for cron run (Statistics module). So the "normal" Statistics cron will never run. We couldn't disable the "Statistics" module, as we were still keeping track of the views through the node_counter table :-)

The result


Submitted by Anonymous (not verified) on Thu, 16/12/2010 - 03:03

I am very much interested in your solution - would it be possible to get your module. I am not really good with my php skills yet.

Submitted by Jochus on Thu, 16/12/2010 - 13:56


I could contribute this module, but I have no experience with that, so I have to figure that out.
I cannot provide you the module, as it currently involves company code as well.


Submitted by Sajal (not verified) on Thu, 15/03/2012 - 08:42

Hello Jochen,

Very nice solution. But I just think here, we would have 24 hours accuracy loss?

Say cron ran on "15 March 2012 00:00", now it will next run on "16 March 2012 00:00".

So say some one views any node on "15 March 2012 11:00", the node views between "15 March 2012 00:00" and "15 March 2012 11:00" won't get count, fine?? Since our custom table would get updated on 16 march 00:00, we won't be able to accurately measure the counts for that whole day between cron runs.

Please correct me if I am wrong.


Submitted by Jochus on Thu, 24/05/2012 - 12:58


Hmm, no, normal cron isn't running any longer as we manually set the variable to not cleanup statistics. We do it in our own custom function.
If you want, I can add the function in this blogpost?


Submitted by AlX (not verified) on Thu, 11/10/2012 - 14:24

Dear developer, iam very Interessent on your Solution.can you Post you Module Code-Snippet or send it via Email?
That Would be Realy Great!!!

Thanks in Advanced ans have a nice Day :-)

Submitted by Jochus on Sun, 14/10/2012 - 10:55


I will try to post the code on my GitHub as soon as possible.
I'll keep you updated.


Add new comment

The content of this field is kept private and will not be shown publicly.


  • Lines and paragraphs break automatically.
  • You can caption images (data-caption="Text"), but also videos, blockquotes, and so on.
  • Web page addresses and email addresses turn into links automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <bash>, <cpp>, <css>, <html5>, <java>, <javascript>, <php>, <sql>, <xml>. The supported tag styles are: <foo>, [foo].
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.