René Nyffenegger's collection of things on the web
René Nyffenegger on Oracle - Most wanted - Feedback -
 

Is Firefox on the rise?

Firefox 1.0 was recently release and the news are that Firefox is used more and more. Just for the heck of it, I wanted to know if this is true for my webpage. So, I hacked together a perl script that analyzes my webserver log.
The output of the script is the following picture:
/blog/2004/december/count_browser.gif
The script uses HTTP::BrowserDetect to determine the browser. Each browser is drawn with another color:
  • Internet Explorer: red
  • Firefox: blue
  • Netscape: green
  • Mozilla: orange
  • Safari: cyan
  • Lynx: fuchsia
  • AOL browser: purple
  • Opera: medium cyan
  • Unknown: gray
For each day and browser, exactly one dot is drawn. A dot at the lower end of the graphic means that for that particular day, the website was hit 0% by that browser. A dot at the higher end similarly means that the site was hit 100% by that browser.
The log starts on March 30th 2004 (corrsponding to the left end) and ends on December 4th 2004; it covers 250 days.
As the graph shows, Internet explorer usage has fallen from between 70% and 80% to some 60% while Firefox has risen from some 5% usage to 20%.
For completeness, here is the perl script I used:
count_browser.pl
use strict;
use warnings;

use Text::CSV_XS;
use HTTP::BrowserDetect;
use GD;

my $log_file = $ARGV[0];
open LOG, $log_file or die "could not open log file: $log_file";

my $csv = Text::CSV_XS->new({
     'quote_char'  => '"',
     'escape_char' => '"',
     'sep_char'    => ' ',
     'binary'      => 0
 });

my %stats;

my %month_map;
$month_map{'Jan'}= 1;
$month_map{'Feb'}= 2;
$month_map{'Mar'}= 3;
$month_map{'Apr'}= 4;
$month_map{'May'}= 5;
$month_map{'Jun'}= 6;
$month_map{'Jul'}= 7;
$month_map{'Aug'}= 8;
$month_map{'Sep'}= 9;
$month_map{'Oct'}=10;
$month_map{'Nov'}=11;
$month_map{'Dec'}=12;

my $c=0;

my $day_count=0;
my $last_day=-1;
while (my $log_line =<LOG>) {
  my $status = $csv -> parse($log_line);
  next unless $status;

  my ($ip, $when, $request, $referrer, $user_agent) = 
     ($csv -> fields()) [0,3,5,8,9];

  my ($day,$month_str,$year,$hour,$minute,$second) = 
     ($when =~ m,(\d\d)/(\w{3})/(\d{4}):(\d\d):(\d\d):(\d\d),);

  if ($last_day != $day) {
    $last_day=$day;
    $day_count++;
    print "day_count=$day_count\n";
  }

  my $month = $month_map{$month_str};

  my $browser_info = new HTTP::BrowserDetect($user_agent);

  next if $browser_info->robot();
  if ($user_agent eq 'Mozilla/3.01 (compatible;)') {
    $stats{$year}{$month}{$day}{'Mozilla'}{cnt}++;
  }
  else {
    my $bs = $browser_info->browser_string();
    unless (defined $bs) {
      $bs = "Unknown";
    }
    $stats{$year}{$month}{$day}{$bs}{cnt}++;
  }
}

my %color_map;

$color_map{'MSIE'        } = {color=>[255,   0,   0]};
$color_map{'Firefox'     } = {color=>[  0,   0, 255]};
$color_map{'Netscape'    } = {color=>[  0, 255,   0]};
$color_map{'Mozilla'     } = {color=>[255, 127,   0]};
$color_map{'Safari'      } = {color=>[  0, 255, 255]};
$color_map{'Lynx'        } = {color=>[255,   0, 255]};
$color_map{'AOL Browser' } = {color=>[127,   0, 127]};
$color_map{'Opera'       } = {color=>[  0, 127, 127]};
$color_map{'Unknown'     } = {color=>[127, 127, 127]};

my $border=5;
my $image = new GD::Image(2*$border+$day_count,2*$border+100);

$image->colorAllocate(255,255,255);

my $gray = $image->colorAllocate(190,190,190);

for (my $i=0;$i<=100;$i+=10) {
  $image->line($border, $border+$i, $border+$day_count, $border+$i, $gray);
}
$image->line($border, $border, $border,$border+100, $gray);
$image->line($border+$day_count, $border, $border+$day_count,$border+100, $gray);

foreach my $c (keys %color_map) {
  $color_map{$c}{ix} = $image -> colorAllocate(@{$color_map{$c}{color}});
}

my $cur_day=0;
foreach my $year  (sort {$a <=> $b} keys % stats                 ) {
foreach my $month (sort {$a <=> $b} keys %{$stats{$year}        }) {
foreach my $day   (sort {$a <=> $b} keys %{$stats{$year}{$month}}) {

  my $total=0;

  map { $total += $stats{$year}{$month}{$day}{$_}{cnt} } 
      keys %{$stats{$year}{$month}{$day}};

  foreach my $browser (
      keys %{$stats{$year}{$month}{$day}}) {

    $image->setPixel(
      $border+$cur_day, 
      $border+ 100 - 100/$total*$stats{$year}{$month}{$day}{$browser}{cnt}, 
      $color_map{$browser}{ix});
  }
  $cur_day++;
}}}

open GIF, ">count_browser.gif";
print GIF $image->gif;
close GIF;