Link to home
Start Free TrialLog in
Avatar of TAF2000
TAF2000

asked on

Simple log script

I am making a script to log hits on my webpage (Yes I know that there are already a million out there).  Anyway..  how do i make the log entries be written to the top of the log file?  Also how can I limit the number of entries?  Some sample code would be nice.

Since this is kindof a double question I will increase the points some if I get a good answer.
Avatar of Kim Ryan
Kim Ryan
Flag of Australia image

This should be OK, so long as your log file isn't huge.

open(IN_FH "<$log_name");
open(OUT_FH ">$tmp_log_name");
@all_lines = <IN_FH>;
unshift(@all_lines,$log_entry);
#Only savethe last x most recent records
foreach $line (1 .. $MAX_ENTRIES)
{  
    print(OUT_FH $line);
}
close(IN_FH);
close(OUT_FH);
rename($tmp_log_name,$log_name);

This should be OK, so long as your log file isn't huge.

open(IN_FH "<$log_name");
open(OUT_FH ">$tmp_log_name");
@all_lines = <IN_FH>;
unshift(@all_lines,$log_entry);
#Only savethe last x most recent records
foreach $line (1 .. $MAX_ENTRIES)
{  
    print(OUT_FH $line);
}
close(IN_FH);
close(OUT_FH);
rename($tmp_log_name,$log_name);

Just realized I forgot something!

foreach $line (1 .. $MAX_ENTRIES)
{    
    print(OUT_FH $line);
    eof and last; # file hasn't reached max size yet
}

Sorry, I rushed the first answers a bit. Here is a more complete version.

$max_lines = 1000;
open(IN_FH "<$log_name");
open(OUT_FH ">$tmp_log_name");
@all_lines = <IN_FH>;
unshift(@all_lines,$log_entry);
#Only save the last x most recent records
$lines = 0;
foreach $line (@all_lines)
{
    ($lines > $max_lines) and last;  
    print(OUT_FH $line);
    $lines++;
}
close(IN_FH);
close(OUT_FH);
rename($tmp_log_name,$log_name);


Avatar of ozo
without a lock, that could miss some entrys is two people try to add to the log at the same time.
(but that may be ok, since you don't mind missing entrys after receiving 1000 new ones)
Avatar of TAF2000
TAF2000

ASKER

Okay, I am sorry I have not responeded sooner.  I am still trying to get that to work.  Where do I put the part that actually gets the information?

This part:

 print "Content-type: text/html\n\n ";
    print LOG " [ <B>Time:</B> $getdate ] - \n";
    print LOG " [ <B>User IP:</B> $ENV{'REMOTE_ADDR'} ] - \n";
    print LOG " [ <B>With:</B> $ENV{'HTTP_USER_AGENT'} ] - \n";
    print LOG " [ <B>Host:</B> $ENV{'REMOTE_HOST'} ] - \n";
    print LOG "[ <B>From:</B> <A HREF=$ENV{'HTTP_REFERER'}>$ENV{'HTTP_REFERER'}</A> ]<BR><HR><BR>\n\n";


Thanks.
Not completely sure what you mean. When you create the file handle LOG, you must assign it a full path name. This is the same name you should use for $log_name in the line:

open(IN_FH "<$log_name");

Avatar of TAF2000

ASKER

I don't understand your answer, I don't think that it is what I am looking for.  
$max_lines = 1000;
open(OLD_LOG "<$log_name");
open(LOG ">$tmp_log_name");
@all_lines = <OLD_LOG>;

# This adds the latest entry
$latest = " [ <B>Time:</B> $getdate ] - \n";
$latest .= " [ <B>User IP:</B> $ENV{'REMOTE_ADDR'} ] - \n";
$latest .= " [ <B>With:</B> $ENV{'HTTP_USER_AGENT'} ] - \n";
$latest .= " [ <B>Host:</B> $ENV{'REMOTE_HOST'} ] - \n";
$latest .= "[ <B>From:</B> <A HREF=$ENV{'HTTP_REFERER'}>$ENV{'HTTP_REFERER'}</A> ]<BR><HR><BR>\n\n";
unshift(@all_lines,$latest);

#Only save the last x most recent records
$lines = 0;
foreach $line (@all_lines)
{
    ($lines > $max_lines) and last;    
    print(LOG $line);
    $lines++;
}
close(OLD_LOG);
close(LOG);
rename($tmp_log_name,$log_name);

#
# Let me know of any problems



Avatar of TAF2000

ASKER

what is wrong with this?  It still isn't working...The logfile is blank.


#!/usr/bin/perl


$log_name = "/web2/seek-it/public_html/stats/newmp3.html";
$tmp_log_name = "/web2/seek-it/public_html/stats/newmp3tmp.html";


$getdate = `date +"%D %T %Z"`;
chop ($getdate);

$max_lines = 1000;
open(OLD_LOG "<$log_name");
open(LOG ">$tmp_log_name");
@all_lines = <OLD_LOG>;

# This adds the latest entry
$latest = " [ <B>Time:</B> $getdate ] - \n";
$latest .= " [ <B>User IP:</B> $ENV{'REMOTE_ADDR'} ] - \n";
$latest .= " [ <B>With:</B> $ENV{'HTTP_USER_AGENT'} ] - \n";
$latest .= " [ <B>Host:</B> $ENV{'REMOTE_HOST'} ] - \n";
$latest .= "[ <B>From:</B> <A HREF=$ENV{'HTTP_REFERER'}>$ENV{'HTTP_REFERER'}</A> ]<BR><HR><BR>\n\n";
unshift(@all_lines,$latest);

#Only save the last x most recent records
$lines = 0;
foreach $line (@all_lines)
{
    ($lines > $max_lines) and last;    
    print(LOG $line);
    $lines++;
}
close(OLD_LOG);
close(LOG);
rename($tmp_log_name,$log_name);

exit;


I am getting these errors:
Missing comma after first argument to open function at /web2/seek-it/public_html/cgi-bin/newmp3.pl line 26, near ""<$log_name")"
Missing comma after first argument to open function at /web2/seek-it/public_html/cgi-bin/newmp3.pl line 26, near ""<$log_name")"
Missing comma after first argument to open function at /web2/seek-it/public_html/cgi-bin/newmp3.pl line 27, near "">$tmp_log_name")"
Missing comma after first argument to open function at /web2/seek-it/public_html/cgi-bin/newmp3.pl line 27, near "">$tmp_log_name")"
Execution of /web2/seek-it/public_html/cgi-bin/newmp3.pl aborted due to compilation errors.
Execution of /web2/seek-it/public_html/cgi-bin/newmp3.pl aborted due to compilation errors.
[Mon Aug  2 07:27:35 1999] [error] [client 171.212.249.107] Premature end of script headers: /web2/seek-it/public_html/cgi-bin/newmp3.pl
open(OLD_LOG,"<$log_name");
Thanks ozo, also
open(LOG, ">$tmp_log_name");

Avatar of TAF2000

ASKER

Yeah, I figured the second one out.  I have modified it alot more and it works good now.  Thanks.  Go ahead and answer it again so I can give you my points.
ASKER CERTIFIED SOLUTION
Avatar of Kim Ryan
Kim Ryan
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of TAF2000

ASKER

Yeah..like I said I have it working fine now..  What is file locking?
It gives you exclusive rights to read and/or update a file, preventing any other processes from updating until you release the lock. Makes sense for highly trafficed web sites where you get many hits at almost the same time.
Unfortunately, the way you've used the locks, it looks like you've left room between the unlock and the rename for someone to come in and replace your new entry.