Jump to content

PERL: Log Housecleaning


Forgotten

Recommended Posts

Hey guys,

This script isn't really meant to be run from a site but rather from the command line/shell/terminal.

I really don't know much about perl at all and I wrote this script by researching and looking at other perl scripts.

This script is meant to perform housecleaning on a log: it opens the log, removes every line containing an ip, and the tells you how many lines were removed. The trouble is that the script breaks and I have no clue what to do.

#!/usr/bin/perl -w

use strict;

my $path = "/var/log/httpd/access_log";
my $ip = "127.0.0.1";

# Call subroutine
remove($path,$ip);

# Define remove subroutine
sub remove {
    # Fix input variables
    my($log,$uip) = @_; 
    # Check for valid path
    if (-e $log) {
        # Open log and turn contents into variable
        open(DATA, "<$log") or die "[-] Error: Logfile could not be opened: $!n";
        my @data = <DATA>;
        close(DATA);
        # Declare status variables
        my $found = 0;
        my $count = 0;
        # Check if data exists
        if(@data) {
            # Run script for every line in $path
            foreach my $line (@data) {
                # For every line that contains the IP
                if($line =~m/$uip/) {
                    open(LOG, ">$log") or die "[-] Error: Logfile could not be opened: $!n";
                    chomp($line) or die "[-] Error: Logfile could not be written to: $!n";
                    close(LOG);
                    # Set find status to found
                    $found = 1;
                    # Increase number of IPs
                    $count++;
                }
            }
            # No lines containing IP regex found
            if (!$found) {
                print "[-] $uip was not found in the logfile. Rest easy!n";
            } else {
                print "[-] Log edit success! Removed $count instances of $uipn";
            }
        } else {
            print "[-] Error: Data error?n";
        }
    } else {
        print "[-] Error: $log does not exist or you have incorrect permissionsn";
    }
}

Link to comment
Share on other sites

                    open(LOG, ">$log") or die "[-] Error: Logfile could not be opened: $!n";
                    chomp($line) or die "[-] Error: Logfile could not be written to: $!n";
                    close(LOG);

Since when does the chomp function write to a file? It should just be removing some characters from $line. See here.

You claim that 'the script breaks'. Could you be a tad more specific?

Link to comment
Share on other sites

Sorry, I was a little tired.

At this point in time, the script cannot open the log, make the data a variable. So when the if(@data) statement is made, it won't continue the script. Again, being tired I forgot the write the line that will replace the line with nothing, then chomp()... I believe that will work?

Link to comment
Share on other sites

Do you really need that if statement? I mean, sure, from the looks of it it should pass it when the file is being read, but if it fails you simply get an empty array, which means no loops through the foreach statement.

Are you sure the $log file exists and contains data?

I don't believe you need to chomp. You want to loop through the array, deleting elements as you go, and end up with writing the whole array back to the file again. So in the foreach you'd use the splice call to cut away the lines, and only after the foreach loop you write the new lines to the file. Unless I'm mistaken your current code dump above opens the file for writing (as opposed to appending using the open(LOG,">>$log") call) on each non-matching element. So in other words your resulting file should never contain more than 1 line. It might explain why the if (@data) fails. Due to the truncating of the file (note, I'm no perl wiz. I don't know if this actually happens here) there is no data to be read.

Am I making any sense here?

Link to comment
Share on other sites

I don't know perl but would it not be easer to put the whole file into memory(or rename it and delete it later) and write line by line back to the file as long as it doesn't have the localhost in that line...

and I'm going to make an ass of you and me by(thinking this is for apache) and say you might want to use use a regex to make sure the IP is at the start so someone can't pass it as a referrer

Link to comment
Share on other sites

How about you use this little perl one-liner :

perl -pi.bak -e "s/127.0.0.1//g" log_file

This should be run from command line . What it does is exactly what you need : it opens log_file ,searches for every occurence of 127.0.0.1 and removes it. The script makes a backup of the log_file , naming it log_file.bak ( just in case ).

Hope this helps

Link to comment
Share on other sites

  • 2 weeks later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...