#!/usr/bin/perl -w
# lla.pl v 0.99p1
# Log Analyser for NS 4.11 LDAP and OpenLDAP
# Author : Kris Buytaert
# email : kb@ipng.be
# rewritten: brian harrison <brie@excitehome.net>, 2001-01-03
# Todo :
# - Fancy html layout
# - Open LDAP Support
# - Fixing the 0 line in the foreach loops ...
# - Cleanup Code
# - ReImplement speed measurement
# Done:
# - Optimize Performance
# - Make it possible to run multiple instances on different logfiles
# together
# Requirements
# http://www.cpan.org/doc/FAQs/FAQ/PerlFAQ.html#Data_Dates
# Get the modules from http://www.cpan.org/modules/by-module/Time/
# Time-modules-100.010301.tar.gz
# Get the modules from http://www.cpan.org/modules/by-module/Date/
# DateManip-5.39.tar.gz
require 5.004;
use strict;
use Getopt::Long;
use Time::ParseDate;
use Date::Calc qw(:all);
use IO::File;
use vars qw($debug $webbish);
use vars qw(%originatinghost %tally);
########################## Sub Cleanup #################################
sub Cleanup {
print "Entering Cleanup\n" if $debug;
close DEBUG if $debug >= 3;
}
########################## Sub OnScreen #################################
sub Onscreen {
print "LDAP Log Analyser\n" if $debug;
}
########################## Sub FewParam #################################
sub Fewparam {
print <<'_EOH_';
LDAP Log Analyser is generating statistics from your LDAP log file
Usage : lla.pl -w INPUTFILE [ > OUTPUTFILE ]
Example. : lla.pl -w access > stats.html
Copyright by Kris Buytaert 2000 kb@ipng.be
This software is released under the terms of the GNU General Public License
Main operation mode:
-w Generate html output
-t Generate flatfile output
-m=kb@ipng.be Mail flatfile to emailaddress (may be specified multiple times)
_EOH_
exit();
}
# conn nrs herstarten / dag to be implemented
# We will be analysing the log file checking for
# - Originating connections $from[ip] to be implemented
# - Bind dn to be implemented
# - Srch to be implemented
# Actually all possible operations to be implemented
# $conn = Total Number of Connections
# $sspeed = Sessions / Second
# $ospeed = Operations / Second
# $sconn = Connections / Session
########################## Sub Report #################################
sub Report {
my (%total, %average, %counter);
print "\n\nEntering Report\n" if $debug;
if ($webbish) {
print OUTPUT "<html><head><title>LDAP Log Analyse Report</title></head><body bgcolor=\"#ffffff\">";
}
# print OUTPUT "Between $starttime and $endtime there were $conntotal sessions started\n";
# print OUTPUT "<br>" if $webbish;
# print OUTPUT "Average speed is about $sspeed\n";
print OUTPUT "<br>" if $webbish;
# Display all originating hosts .. sorted ...
my $ip;
foreach $ip (sort keys %originatinghost) {
print OUTPUT "Connections from $ip = $originatinghost{$ip}\n";
print OUTPUT "<br>" if $webbish;
}
print OUTPUT "\n\n\n";
if ($debug >= 3) {
my $t;
foreach $t (sort keys %{$tally{operations}}) {
print DEBUG "===============================";
print DEBUG "Nr Operations $t : $tally{operations}->{$t}\n";
}
}
my $type;
foreach $type ("operations","totaltime","search","bind","result","res0","res32","res65","res103","mod","add") {
my $id;
while (($id) = each %{$tally{$type}}) {
my $n = $tally{$type}->{$id};
# print OUTPUT "Numbers of $type in Session $id : $n\n";
# print OUTPUT "<br>" if $webbish;
$total{$type} += $n;
$counter{$type}++;
}
$average{$type} = $counter{$type} ? $total{$type} / $counter{$type} : 'undef';
print OUTPUT "Average $type per connection = $average{$type}\n";
print OUTPUT "<br>" if $webbish;
}
print OUTPUT "</body></html>" if $webbish;
# Mail plain text if needed ...
}
######################### Sub Analyse_File #################################
sub Analyse_File {
my (%firstline, %lastline);
my %session;
while (<>) {
my ($conn) = / conn=(\d+) /;
# Statistics on Originating IP
if (/connection from (.*) to (.*)/) {
# every time we see a new connection it is a new "session",
# even if this conn number has been seen before.
$session{$conn}++;
$originatinghost{$1}++;
}
my $session = $session{$conn} || 0;
my $id = join '.', $conn, $session;
$firstline{$id} = $_ unless $firstline{$id};
$lastline{$id} = $_;
# Counting Searches
if (/SRCH/) {
$tally{search}->{$id}++;
}
# Counting BIND
if (/BIND/) {
$tally{bind}->{$id}++;
}
# Analysing Result Type
if (/RESULT/) {
$tally{result}->{$id}++;
}
if (/RESULT err=(\d+)/) {
$tally{"res" . $1}->{$id}++;
}
# MOD
if (/MOD/) {
$tally{mod}->{$id}++;
}
# ADD
if (/ADD/) {
$tally{add}->{$id}++;
}
}
my $id;
while (($id) = each %lastline) {
# Number of operations in a session
my ($op_count) = ($lastline{$id} =~ / op=(\d+) /);
$tally{operations}->{$id} = $op_count;
print "Nr Operations : $tally{operations}->{$id}\n" if $debug >= 2;
print DEBUG "Nr Operations : $tally{operations}->{$id}\n" if $debug >= 3;
# Calculating Session Start
my ($starttime) = ($firstline{$id} =~ /\[(.*?)\]/);
my $startseconds = parsedate($starttime);
# Calculating Session End
my ($endtime) = ($lastline{$id} =~ /\[(.*?)\]/);
my $endseconds = parsedate($endtime);
# Calculating Session Time
$tally{totaltime}->{$id} = $endseconds - $startseconds;
# Analysing Bind Types
}
undef %firstline;
undef %lastline;
}
############### Main #######################
# Onscreen;
# 0 = no debugging
# 1 = light debugging
# 2 = code debugging
# 3 = debugging to file
$debug = 0;
open DEBUG, ">debug.log" if $debug >= 3;
# Could be done better with select()
my $webbish = 0; # 1 = Results in html
my $text = 0; # 1 = Results in plain text
my @email = ();
my $email;
GetOptions("debug=i" => \$debug,
"w|web|html" => \$webbish,
"t|text" => \$text,
"m|mail=s@" => \@email);
unless ($webbish or $text or @email) {
Fewparam();
}
foreach (@ARGV) {
unless (-e $_) {
die "usage has changed. use \"> $_\" to specify the output file instead.\n";
}
}
if (@email) {
my $MailSubject = "LDAP Log Analyse Report";
my $all_email = join ' ', @email;
open OUTPUT, "| /usr/bin/mail -s \"$MailSubject\" $all_email";
} else {
open OUTPUT, ">&STDOUT";
}
#
print "Analysing input\n" if $debug;
my $analyse_start = time;
Analyse_File();
print "Analyse time: ", time - $analyse_start, "\n" if $debug;
Report();
Cleanup();
syntax highlighted by Code2HTML, v. 0.9.1