[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Analize Radius Log files



Rosenberg Yigal wrote:
> 
> Before I seat and do it myself, does anyone know about utility that will
> produce
> nice reports out of the RADIUS log files ....?
> 
> thanks.

Hi,

Here is a basic script I hacked up for Gezernet.  It's probably
a good start for your own hacking.  It requires perl 5.

Cheers,

--Amos

-- 
--Amos Shapira                | "Of course Australia was marked for
133/13 Shlomo Ben Yosef st.   |  glory, for its people had been chosen
Jerusalem 93 805              |  by the finest judges in England."
ISRAEL    amos@gezernet.co.il |                       -- Anonymous
#!/usr/bin/perl

# This routine is called every time the main loop decides that
# it finished reading a record (i.e. the main loop finds the empty
# line after the record).
sub process_details {
    # fetch the reference to the details record from the argument
    local ($DetailsRef) = shift;

    # we are only interested in "Stop" records in this partifular utility
    if ($$DetailsRef{'Acct-Status-Type'} ne 'Stop') {
#	print "process_details: not a Stop record; skipped\n";
	return;
    }

    # The next few conditions check that the essensial fields were
    # found in the record
    if (! exists $$DetailsRef{'User-Name'}) {
	print "process_details: no User-Name given!\n";
	return;
    }

    if (! exists $$DetailsRef{'Acct-Session-Id'}) {
	print "process_details: no Acct-Session-Id!\n";
	return;
    }

    if (! exists $$DetailsRef{'Acct-Session-Time'}) {
	print "process_details: no Acct-Session-Time!\n";
	return;
    }

    # If this is a duplicate record then ignore it (could happen,
    # since the radius-accounting protocol is UDP based, and therefore
    # isn't reliable
    if (exists $Seen{$$DetailsRef{'Acct-Session-Id'}}) {
#	print "process_details: Acct-Session-Id of " .
#	    "$$DetailsRef{'Acct-Session-Id'} allready seen\n";
	return;
    }

    # Remember that we've seen this session ID
    $Seen{$$DetailsRef{'Acct-Session-Id'}} = 1;

    # Cleanup the user name from leading and trainling spaces
    ($username = $$DetailsRef{'User-Name'}) =~ s/^"\s*(\S+)\s*"/\1/;

    # just to show some progress, ADD '#' IN FRONT OF NEXT LINE TO
    # KEEP IT QUIET
    print STDERR "$username: +$$DetailsRef{'Acct-Session-Time'}\n";

    # Sum up the amount of minutes this user was logged in
    $Users{$username} += $$DetailsRef{'Acct-Session-Time'};
}

# This is the main loop.  Usage: acct [details-file....]
# will read the given details files one after the other as one
# large file, or the standard input if no file names are given

# Read all the given details files
while (<>) {

    # remove trailing newline if found
    chomp;

    # if empty line then it's the end of the current record, process
    # it, forget all the fields of the record and go on to the next input
    # line
    if (/^$/) {
#	print keys (%Details), "\n";
	process_details (\%Details);
	%Details = ();
	next;
    }

    # Otherwise remember the record.  NOTE: This script ignores the
    # initial "time" stamps at the beginning of the records.  If you
    # are interested in these then you'll probably have to add another
    # "if" here
    if (/^\s([a-zA-Z-_0-9]+) = (.*)/) {
	($FieldName, $FieldVal) = ($1, $2);
#	print "Field: \"$FieldName\"; Value: \"$FieldVal\"\n";
	$Details{$FieldName} = $FieldVal;
    }
}

# We reach here after the entire input was read, sort the users by name
# and print their usage as fractions of hours.
foreach (sort keys %Users) {
    printf "$_: %.1f\n", $Users{$_} / 3600;
}