#!/usr/bin/perl ######################################################################### # Access Stats v1.12 # # Copyright (c)2000 Chi Kien Uong # # URL: http://www.proxy2.de # # # # This Software is distributed under the GNU General Public # # License. For more details see license.txt # # # ######################################################################### # url to script $cgiurl = "http://www.ralphstuff.com/cgi-local/stat.cgi"; # url to the image files without trailing "/" $gif_url = "http://www.ralphstuff.com/gif"; # path to the log files from the server root without trailing "/" (chmoded to 777 (drwxrwxrwx)) $base_dir = "../logfiles"; # url to the log files without trailing "/" $log_url = "http://www.ralphstuff.com/logfiles"; # minimum visits before to show in list $host_min = 1; $browser_min = 1; $os_min = 1; $referer_min = 1; # show visits from all countries $show_ccodes = "yes"; $show_max = 15; # only valid if $show_ccodes="no" # log file extension $log_file_ext = "txt"; # misc configurations $font_size = "10pt"; # font size $table_width = 600; # table width $max_bar_length = 300; # bar lenght of host,os,browser,etc. in relation to $table_width $max_bar_day_length = 170; # bar lenght of day should be set in relation to $table_width $hits_by_weekday = "yes"; $top_countries = "yes"; $top_browsers = "yes"; $top_os = "yes"; $top_host = "yes"; # Done ########### %CCodes = ( ad => "Andorra", ae => "United Arab Emirates", af => "Afghanistan", ag => "Antigua and Barbuda", ai => "Anguilla", al => "Albania", am => "Armenia", an => "Netherlands Antilles", ao => "Angola", aq => "Antarctica", ar => "Argentina", as => "American Samoa", at => "Austria", au => "Australia", aw => "Aruba", az => "Azerbaijan", ba => "Bosnia Herzegovina", bb => "Barbados", bd => "Bangladesh", be => "Belgium", bf => "Burkina Faso", bg => "Bulgaria", bh => "Bahrain", bi => "Burundi", bj => "Benin", bm => "Bermuda", bn => "Brunei Darussalam", bo => "Bolivia", br => "Brazil", bs => "Bahamas", bt => "Bhutan", bv => "Bouvet Island", bw => "Botswana", by => "Belarus", bz => "Belize", ca => "Canada", cc => "Cocos (Keeling) Islands", cf => "Central African Republic", cg => "Congo", ch => "Switzerland", ci => "Cote DIvoire", ck => "Cook Islands", cl => "Chile", cm => "Cameroon", cn => "China", co => "Colombia", cr => "Costa Rica", cs => "Czechoslovakia", cu => "Cuba", cv => "Cape Verde", cx => "Christmas Island", cy => "Cyprus", cz => "Czech Republic", de => "Germany", dj => "Djibouti", dk => "Denmark", dm => "Dominica", do => "Dominican Republic", dz => "Algeria", ec => "Ecuador", ee => "Estonia", eg => "Egypt", eh => "Western Sahara", er => "Eritrea", es => "Spain", et => "Ethiopia", fi => "Finland", fj => "Fiji", fk => "Falkland Islands (Malvinas)", fm => "Micronesia", fo => "Faroe Islands", fr => "France", fx => "France (Metropolitan)", ga => "Gabon", gb => "Great Britain (UK)", gd => "Grenada", ge => "Georgia", gf => "French Guiana", gh => "Ghana", gi => "Gibraltar", gl => "Greenland", gm => "Gambia", gn => "Guinea", gp => "Guadeloupe", gq => "Equatorial Guinea", gr => "Greece", gs => "S. Georgia and S. Sandwich Islands", gt => "Guatemala", gu => "Guam", gw => "Guinea-Bissau", gy => "Guyana", hk => "Hong Kong", hm => "Heard and McDonald Islands", hn => "Honduras", hr => "Croatia (Hrvatska)", ht => "Haiti", hu => "Hungary", id => "Indonesia", ie => "Ireland", il => "Israel", in => "India", io => "British Indian Ocean Territory", iq => "Iraq", ir => "Iran", is => "Iceland", it => "Italy", jm => "Jamaica", jo => "Jordan", jp => "Japan", ke => "Kenya", kg => "Kyrgyzstan", kh => "Cambodia", ki => "Kiribati", km => "Comoros", kn => "Saint Kitts and Nevis", kp => "North Korea", kr => "South Korea", kw => "Kuwait", ky => "Cayman Islands", kz => "Kazakhstan", la => "Laos", lb => "Lebanon", lc => "Saint Lucia", li => "Liechtenstein", lk => "Sri Lanka", lr => "Liberia", ls => "Lesotho", lt => "Lithuania", lu => "Luxembourg", lv => "Latvia", ly => "Libya", ma => "Morocco", mc => "Monaco", md => "Moldova", mg => "Madagascar", mh => "Marshall Islands", mk => "Macedonia", ml => "Mali", mm => "Myanmar", mn => "Mongolia", mo => "Macau", mp => "Northern Mariana Islands", mq => "Martinique", mr => "Mauritania", ms => "Montserrat", mt => "Malta", mu => "Mauritius", mv => "Maldives", mw => "Malawi", mx => "Mexico", my => "Malaysia", mz => "Mozambique", na => "Namibia", nc => "New Caledonia", ne => "Niger", nf => "Norfolk Island", ng => "Nigeria", ni => "Nicaragua", nl => "Netherlands", no => "Norway", np => "Nepal", nr => "Nauru", nt => "Neutral Zone", nu => "Niue", nz => "New Zealand (Aotearoa)", om => "Oman", pa => "Panama", pe => "Peru", pf => "French Polynesia", pg => "Papua New Guinea", ph => "Philippines", pk => "Pakistan", pl => "Poland", pm => "St. Pierre and Miquelon", pn => "Pitcairn", pr => "Puerto Rico", pt => "Portugal", pw => "Palau", py => "Paraguay", qa => "Qatar", re => "Reunion", ro => "Romania", ru => "Russian Federation", rw => "Rwanda", sa => "Saudi Arabia", sb => "Solomon Islands", sc => "Seychelles", sd => "Sudan", se => "Sweden", sg => "Singapore", sh => "St. Helena", si => "Slovenia", sj => "Svalbard and Jan Mayen Islands", sk => "Slovak Republic", sl => "Sierra Leone", sm => "San Marino", sn => "Senegal", so => "Somalia", sr => "Suriname", st => "Sao Tome and Principe", su => "USSR (Former)", sv => "El Salvador", sy => "Syria", sz => "Swaziland", tc => "Turks and Caicos Islands", td => "Chad", tf => "French Southern Territories", tg => "Togo", th => "Thailand", tj => "Tajikistan", tk => "Tokelau", tm => "Turkmenistan", tn => "Tunisia", to => "Tonga", tp => "East Timor", tr => "Turkey", tt => "Trinidad and Tobago", tv => "Tuvalu", tw => "Taiwan", tz => "Tanzania", ua => "Ukraine", ug => "Uganda", uk => "United Kingdom", um => "US Minor Outlying Islands", us => "United States", uy => "Uruguay", uz => "Uzbekistan", va => "Vatican City State (Holy See)", vc => "Saint Vincent and the Grenadines", ve => "Venezuela", vg => "Virgin Islands (British)", vi => "Virgin Islands (US)", vn => "Vietnam", vu => "Vanuatu", wf => "Wallis and Futuna Islands", ws => "Samoa", ye => "Yemen", yt => "Mayotte", yu => "Yugoslavia", za => "South Africa", zm => "Zambia", zr => "Zaire", zw => "Zimbabwe", com => "US Commercial", edu => "US Educational", gov => "US Government", int => "International", mil => "US Military", net => "Network", org => "Non-Profit Organization", arpa => "Old-Style Arpanet", nato => "NATO Field" ); @gif_array = ("purple","orange","green","pink","blue","yellow","red","gold","darkgreen","aqua"); $|++; &parse_form; if ($FORM{'action'} eq "eval" && $FORM{'id'} ne '') { &html_header; &parse_log("$FORM{'id'}"); &topbar; &days; &http_ref; &hours; &html_week if ($hits_by_weekday eq "yes"); &html_browser if ($top_browsers eq "yes"); &os_system if ($top_os eq "yes"); &countries if ($top_countries eq "yes"); &html_remote_host if ($top_host eq "yes"); print " \n \n"; print "
\n"; print "
\n\n\n\n"; } else { &show_files; } exit (0); sub parse_form { if ($ENV{'REQUEST_METHOD'} eq "GET") { $buffer = $ENV{'QUERY_STRING'}; } else { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $name =~ tr/+/ /; $name =~ s/%([a-f0-9]{2})/pack("C", hex($1))/egi; $value =~ tr/+/ /; $value =~ s/%([a-f0-9]{2})/pack("C", hex($1))/egi; $FORM{$name} = $value; } } sub show_files { &html_header; print "\n\n\n\n"; } sub parse_log { $log_file = "$base_dir/$_[0]"; open(DATA,"$log_file") || &message('Cannot Open Log File!'); @lines = ; close(DATA); $total = @lines; foreach $line (@lines) { if ($line =~ /(.*) - (.*) - \"(.*)\" - \"(.*)\"/) { $date = $1; ($weekday,$day,$time) = split(/ /,$date); ($hour,$minute) = split(/:/,$time); ($temp,$month,$year) = split (/-/,$day); $host_name = $2; $user_agent = $3; $referer = $4; $day = "$day "."$weekday"; $referer{$referer}++; $day{$day}++; $week_days{$weekday}++; $hour{$hour}++; if ($top_countries eq "yes" || $top_host eq "yes") { if ($host_name =~ /\.([_a-z0-9-]*\.[a-z]{2,4}$)/i) { $remote{$1}++; $host_name =~ s/(.*)\.// ; $host_name =~ tr/[A-Z]/[a-z]/; $domain{$host_name}++; $total_doms += 1; } else { $remote{'IP only'}++; } } push(@USER_AGENT, $user_agent); } } $total_agent = @USER_AGENT; if ($top_os eq "yes") { foreach $user_agent (@USER_AGENT) { if ($user_agent =~ /MSIE/i) { if ($user_agent =~ /Windows 98/i) { $os{'Windows 98'}++; next; } elsif ($user_agent =~ /Windows NT/i) { $os{'Windows NT'}++; next; } elsif ($user_agent =~ /Windows 95/i) { $os{'Windows 95'}++; next; } elsif ($user_agent =~ /Mac_PowerPC/i || $user_agent =~ /Macintosh/i) { $os{'Macintosh'}++; next; } } elsif ($user_agent =~ /Win98/i || $user_agent =~ /Windows 98/i) { $os{'Windows 98'}++; next; } elsif ($user_agent =~ /WinNT/i || $user_agent =~ /Windows NT/i) { $os{'Windows NT'}++; next; } elsif ($user_agent =~ /Win95/i || $user_agent =~ /Windows 95/i) { $os{'Windows 95'}++; next; } elsif ($user_agent =~ /Mac_PowerPC/i || $user_agent =~ /Macintosh/i) { $os{'Macintosh'}++; next; } elsif ($user_agent =~ /X11/i) { if ($user_agent =~ /Linux/i) { $os{'Linux'}++; next; } elsif ($user_agent =~ /SunOS/i) { $os{'SunOS'}++; next; } elsif ($user_agent =~ /FreeBSD/i) { $os{'FreeBSD'}++; next; } elsif ($user_agent =~ /BSD/i) { $os{'BSD'}++; next; } else { $os{'UNIX Clone'}++; next; } } elsif ($user_agent =~ /Win16/i || $user_agent =~ /Windows 3\.1/i) { $os{'Windows 3.1'}++; next; } elsif ($user_agent =~ /OS\/2/i) { $os{'OS/2'}++; next; } elsif ($user_agent =~ /Amiga/i) { $os{'Amiga'}++; next; } else { $os{'Unknown Platform'}++; next; } } } if ($top_browsers eq "yes") { foreach $agent (@USER_AGENT) { if ($agent =~ /Opera/i) { $browser{'Opera'}++; next; } elsif ($agent =~ /MSIE/i) { if ($agent =~ /AltaVista/i) { $browser{'AltaVista'}++; next; } elsif ($agent =~ /Lycos/i) { $browser{'Lycos'}++; next; } elsif ($agent =~ /MSIE (\d)/i) { $browser{"Internet Explorer $1"}++; next; } else { $browser{$agent}++; next; } } elsif ($agent =~ /Mozilla/i) { if ($agent =~ /Mozilla\/5/i || $agent =~ /Mozilla 5/i) { $browser{'Netscape Navigator 6'}++; next; } elsif ($agent =~ /Mozilla\/(\d)/i || $agent =~ /Mozilla (\d)/i) { $browser{"Netscape Navigator $1"}++; next; } else { $browser{$agent}++; next; } } elsif ($agent ne "") { $browser{$agent}++; next; } else { $browser{'NO USER AGENT'}++; } } } foreach $count (keys %day) { $total_days++; } $hits_per_day = sprintf ("%.2f",($total/$total_days)); $hits_per_hour = sprintf ("%.2f",($total/$total_days/24)); } sub message { print "Content-type: text/html\n\n"; print "$_[0]"; exit (0); } sub html_header { print "Content-type: text/html\n\n"; print <
Access Stats
www.ralphstuff.com site traffic
Header opendir(HOMEDIR, "$base_dir"); @filename = readdir(HOMEDIR); closedir(HOMEDIR); foreach $logfile (@filename) { if ($logfile =~ /(.*)\.$log_file_ext$/) { push (@new_array,$logfile); } } foreach $logfile (sort @new_array) { print " \n \n"; print " \n \n"; } print "
Logfile  
$logfile\n \n"; print "
\n
\n"; } sub sort_host { if ($remote{$a} > $remote{$b}) { $retval = -1; } elsif ($remote{$a} == $remote{$b}) { $retval = uc($a) cmp uc($b); } else { $retval = 1; } $retval; } sub sort_ref { if ($referer{$a} > $referer{$b}) { $retval = -1; } elsif ($referer{$a} == $referer{$b}) { $retval = uc($a) cmp uc($b); } else { $retval = 1; } $retval; } sub topbar { print <
[ Visits by day ]
[ Visits by week-day ]
[ Referer ]
[ Visits by hour ]
[ Top Countries ]
[ Browsers ]
[ OS ]
[ Host ]


Month $month $year
Total Days $total_days
Total Visits $total
Avarage visits per day $hits_per_day
Avarage visits per hour $hits_per_hour
Header } sub days { print <


Visits by day

Header my ($this_date,$week_day,$img_width,$top_day); foreach $get_max (%day) { $top_day = $day{$get_max} if ($day{$get_max} > $top_day); } $top_day = 1 if ($top_day==0); foreach $key (sort keys %day) { ($this_date,$week_day) = split(/ /,$key); $img_width = int($day{$key}*$max_bar_day_length/$top_day); print " \n"; if ($week_day eq "Sun") { print " \n"; print " \n"; print " \n"; print " \n"; } elsif ($week_day eq "Sat") { print " \n"; print " \n"; print " \n"; print " \n"; } else { print " \n"; print " \n"; print " \n"; print " \n"; } print " \n"; } $img_width = int($hits_per_day*$max_bar_day_length/$top_day); print " \n \n"; print " \n"; print " \n"; print " \n"; print " \n
Day Date Visits  
$week_day $this_date $day{$key}$week_day $this_date $day{$key}$week_day $this_date $day{$key}
 Days: $total_days$total $hits_per_day
\n

\n"; } sub http_ref { print <
Referer

Header my $percent; foreach $refer (sort sort_ref keys %referer) { if ($referer{$refer} >= $referer_min) { $percent = sprintf ("%.2f",($referer{$refer}/$total*100)); print " \n \n \n"; if ($refer eq "-") { print " \n \n"; } else { print " \n \n"; } } else { last; } } print "
Visits Percent Referer
$referer{$refer} $percent\% NO REFERER
$refer
\n
\n
\n"; } sub html_week { print <

Visits by week-day

Monday Tuesday Wednesday Thursday Friday Saturday Sunday
$week_days{"Mon"} $week_days{"Tue"} $week_days{"Wed"} $week_days{"Thu"} $week_days{"Fri"} $week_days{"Sat"} $week_days{"Sun"}


Header } sub html_remote_host { print <
Hostname

EOM my $flag=0; my $i=0; my $num=0; my ($top_pos,$img_width,$percent); foreach $show_host (sort sort_host keys %remote) { $top_pos = $remote{$show_host} if ($flag == 0); $num++; $i++; if ($remote{$show_host} >= $host_min) { $img_width = int($remote{$show_host}*$max_bar_length/$top_pos); $percent = sprintf ("%.2f",($remote{$show_host}/$total*100)); print " \n \n"; print " \n"; print " \n"; print " \n"; } else { last; } $i=0 if ($i>=10); $flag=1; } print "
Hostname    
$num) $show_host$remote{$show_host} $percent\%
\n
\n
\n"; } sub html_browser { print <
Browser

EOM my $flag=0; my $i=0; my $num=0; my ($top_pos,$img_width,$percent); foreach $brow (sort { $browser{$b} <=> $browser{$a} } keys %browser) { $top_pos = $browser{$brow} if ($flag == 0); $num++; $i++; if ($browser{$brow} >= $browser_min) { $img_width = int($browser{$brow}*$max_bar_length/$top_pos); $percent = sprintf ("%.2f",($browser{$brow}/$total_agent*100)); print " \n \n"; print " \n"; print " \n"; print " \n"; } else { last; } $i=0 if ($i>=10); $flag=1; } print "
Browser    
$num) $brow$browser{$brow} $percent\%
\n
\n
\n"; } sub os_system { print <
Operating System

EOM my $flag=0; my $i=0; my $num=0; my ($top_pos,$img_width,$percent); foreach $os_sys (sort { $os{$b} <=> $os{$a} } keys %os) { $top_pos = $os{$os_sys} if ($flag==0); $num++; $i++; if ($os{$os_sys} >= $os_min) { $img_width = int($os{$os_sys}*$max_bar_length/$top_pos); $percent = sprintf ("%.2f",($os{$os_sys}/$total_agent*100)); print " \n \n"; print " \n"; print " \n"; print " \n"; } else { last; } $i=0 if ($i>=10); $flag=1; } print "
Operating System    
$num) $os_sys$os{$os_sys} $percent\%
\n
\n
\n"; } sub countries { print <
Top Countries

EOM my $show=0; my $i=0; my $num=0; my ($top_pos,$img_width,$percent); if (scalar keys %domain) { foreach $tmp_country (%domain) { $top_pos = $domain{$tmp_country} if ($domain{$tmp_country}) > $top_pos; } if ($top_pos==0) { $top_pos=1; } elsif ($top_pos>0 && $top_pos<($total-$total_doms)) { $top_pos=($total-$total_doms); } foreach $country (sort {$domain{$b} <=> $domain{$a}} keys %domain) { $num++; $i++; if (($show_ccodes ne "yes" && $show < $show_max) || $show_ccodes eq "yes") { $img_width = int($domain{$country}*$max_bar_length/$top_pos); $percent = sprintf ("%.2f",($domain{$country}/$total*100)); print " \n \n"; print " \n"; print " \n"; print " \n"; } else { $remain += $domain{$country}; } $i=0 if ($i>=10); $show++; } if ($show_ccodes ne "yes") { $percent = sprintf ("%.2f",($remain/$total*100)); $img_width = int($remain*$max_bar_length/$top_pos); print " \n \n"; print " \n"; print " \n"; print " \n"; } } else { $top_pos=$total; } $ip_only = ($total - $total_doms); $percent = sprintf ("%.2f",($ip_only/$total*100)); $img_width = int($ip_only*$max_bar_length/$top_pos); print " \n \n"; print " \n"; print " \n"; print " \n"; print "
Top Countries    
$num) $CCodes{$country} ($country)$domain{$country} $percent\%
others$remain $percent\%
Unknown$ip_only $percent\%
\n
\n
\n"; } sub hours { foreach $tmp_hour (%hour) { $top_hour = $hour{$tmp_hour} if ($hour{$tmp_hour} > $top_hour); } $top_hour = 1 if ($top_hour==0); print <
Visits by hour

Header my $max_height=200; for ($hour_i=0;$hour_i<24;$hour_i++) { $pad=$hour_i; $pad="0$pad" if ($pad<10); $img_height=int(($hour{$pad} * $max_height)/$top_hour); $img_height=1 if ($img_height==0); print " \n"; } print " \n \n \n \n"; print " \n \n"; my ($hour_j); for ($hour_j=0;$hour_j<24;$hour_j++) { $pad_hour=$hour_j; $pad_hour="0$pad_hour" if ($pad_hour<10); print " \n"; } print " \n \n \n"; for ($val=0;$val<24;$val++) { $pad_val=$val; $pad_val="0$pad_val" if ($pad_val<10); $hits=sprintf("%.1f",($hour{$pad_val}/$total_days)); print " \n"; } print " \n
 \n"; print "
\n
\n
Hour$pad_hour\h
Visits\n
$hits
\n
\n
\n"; }