#!/usr/bin/perl # lla.pl v 0.98p14 # Log Analyser for NS 4.11 LDAP # Author : Kris Buytaert # email : kb@ipng.be # Todo : # - Fancy html layout # - Open LDAP Support # - Fixing the 0 line in the foreach loops ... # - Optimize Performance # - Cleanup Code # - Make it possible to run multiple instances on different logfiles # together # - ReImplement speed measurement # 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 use Time::ParseDate; use Date::Calc qw(:all); ########################## Sub Defaults ################################# sub Defaults { # 0 = no debugging # 1 = light debugging # 2 = code debugging # 3 = debugging to file $debug = 0; $debug < 3 or open DEBUG, ">debug.log"; # Could be done better with select() $webbish = 0; # 1 = Results in html $text = 0; # 1 = Results in plain text $mail = 0; # 1 = mail restults to $email $debug < 1 or print "Entering Defaults\n"; $mkdir = `mkdir /tmp/ldaptmp/`; } ########################## Sub Cleanup ################################# sub Cleanup { $debug < 1 or print "Entering Cleanup\n"; #Cleaning up TMP Dir $rm = `rm -rf /tmp/ldaptmp`; $debug < 3 or close DEBUG; } ########################## Sub OnScreen ################################# sub Onscreen { $debug < 1 or print "LDAP Log Analyser\n"; } ########################## Sub FewParam ################################# sub Fewparam { print "LDAP Log Analyser is generating statistics from your LDAP log file\n"; print "Usage : lla.pl -w ()\n"; print "Example. : lla.pl -w access (stats.html)\n"; print "\n"; print "Copyright by Kris Buytaert 2000 kb\@ipng.be \n"; print "This software is released under the terms of the GNU General Public License\n"; print "\n"; print "Main operation mode:\n"; print " -w Generate html output\n"; print " -t Generate flatfile output\n"; print " -m kb\@ipng.be Mail flatfile to emailaddres\n"; print "If no outputfile and the -m parameter is not used output wil be displayed\n"; 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 Output { $debug < 2 or print $outputfile; if ($mail < 1) { if ($outputfile eq "") { print $report; } else { open (OUTPUT,">$outputfile"); print OUTPUT $report; close OUTPUT; } } else { $MailSubject = "LDAP Log Analyse Report"; open (EMAIL , "| /bin/mail -s \"$MailSubject\" $email"); print EMAIL $report; close EMAIL; } sub Report { $debug < 1 or print "\n\nEntering Report\n"; $webbish < 1 or $report = "LDAP Log Analyse Report"; $report .= "Between $starttime and $endtime there were $conntotal sessions started\n"; $webbish < 1 or $report .= "
"; $report .= "Average speed is about $sspeed\n"; $webbish < 1 or $report .= "
"; # Display all originating hosts .. sorted ... foreach $ipnummer (keys %originatinghost) { $report .= "Connections from $ipnummer = $originatinghost{$ipnummer}\n"; $webbish < 1 or $report .= "
"; } $report .= "\n\n\n"; foreach $t (keys %operations) { $debug < 3 or print DEBUG "==============================="; $debug < 3 or print DEBUG "Nr Operations $t : $operations{$t}\n"; } foreach $type ("operations","totaltime","search","bind","result","res0","res32","res65","res103","mod","add") { $tdummy = "\$"; $tdummy .= $type; $tdummy .= "{\$id}"; $evalstring = "foreach \$id (keys \%$type) { \$report .= \"Numbers of $type(s) in Session \$id : $tdummy \\n\"; \$webbish < 1 or \$report .= \"
\"; \$global_$type = \$global_$type + $tdummy; \$counter_$type ++; } \$average_$type = \$global_$type / \$counter_$type; \$report .= \"Average $type(s) per connection = \$average_$type \\n\"; \$webbish < 1 or \$report .= \"
\"; "; $debug < 1 or print "---------------------------\n$evalstring---------\n"; eval $evalstring; } $webbish < 1 or $report .= ""; # Mail plain text if needed ... } } ########################## Sub Analyse_files ################################# sub Analyse_Files { $debug < 1 or print "Using $operationfile\n"; $id = substr ($operationfile,21); $lastline = `tail -1 $operationfile`; $firstline = `head -1 $operationfile`; # Statistics on Originating IP @dummy = split(/from /,$firstline); @dummy = split(/to/,$dummy[1]); $originating_ip = $dummy[0]; # print "Connection coming from $originating_ip\n"; $originatinghost{$originating_ip}++; # Number of operations in a session $lastopline = `grep -v op=-1 $operationfile | tail -1`; $debug < 2 or print "$lastopline\n"; @dummy = split (/ fd=/,$lastopline); @dummy = split (/op=/,$dummy[0]); @dummy = split (/ RESULT/,$dummy[1]); # print "Nr of Operations $dummy[0]\n"; $operations{$id} = $dummy[0]; $debug < 2 or print "Nr Operations : $operations{$id}\n"; $debug < 3 or print DEBUG "Nr Operations : $operations{$id}\n"; # Calculating Session Start $starttime = $firstline; @dummy = split(/\]/,$starttime); @dummy = split(/\[/,$dummy[0]); $starttime = $dummy[1]; $startseconds = parsedate($starttime); # Calculating Session End $endtime = $lastline; @dummy = split(/\]/,$endtime); @dummy = split(/\[/,$dummy[0]); $endtime = $dummy[1]; $endseconds = parsedate($endtime); # Calculating Session Time $totaltime{$id} = $endseconds - $startseconds; # Counting Searches $search{$id} = `grep SRCH $operationfile | wc -l`; # Counting BIND $bind{$id} = `grep BIND $operationfile | wc -l`; # Analysing Bind Types # Analysing Result Type # Error Type Explanation # 0 # 32 # 49 # 65 # 68 # 103 $result{$id} = `grep "RESULT" $operationfile | wc -l`; $res0{$id} = `grep "RESULT err=0" $operationfile | wc -l`; $res32{$id} = `grep "RESULT err=32" $operationfile | wc -l`; $res49{$id} = `grep "RESULT err=49" $operationfile | wc -l`; $res65{$id} = `grep "RESULT err=65" $operationfile | wc -l`; $res68{$id} = `grep "RESULT err=68" $operationfile | wc -l`; $res103{$id} = `grep "RESULT err=103" $operationfile | wc -l`; # MOD $mod{$id} = `grep MOD $operationfile | wc -l`; # ADD $add{$id} = `grep ADD $operationfile | wc -l`; } ########################## Sub Split_files ################################# sub Split_Files { # First find lowest and hightes conn number .. # Then split / connection .. # Then find begin / end points within repeating connections .. # For each of the created files .. Analyse_Files ;-) $workfile = $inputfile; $debug < 1 or print "$workfile\n"; $file = `cat $workfile`; @dummy_n = split (/\n/,$file); $aantallijnen = scalar(@dummy_n); for ($lijn = 0; $lijn <= $aantallijnen ; $lijn ++) { @dummy = split (/conn=/,$dummy_n[$lijn]); @dummy = split (/ op=/,$dummy[1]); @dummy = split (/ fd=/,$dummy[0]); $conn = $dummy[0]; $connection_nr{$conn} = 1; } foreach $connection_nr_id (keys %connection_nr) { $output = "ldaplog"; $output .= "."; $output .= $connection_nr_id; $createfile = `grep conn=\"$connection_nr_id \" $workfile >/tmp/ldaptmp/$output`; # Checking for 2 sequences in 1 file .. $nrseq = `grep \"op=0 BIND\" /tmp/ldaptmp/$output | wc -l `; $debug < 1 or print "Sequences : $nrseq"; if ($nrseq > 1) { # split file again ... $content = `cat /tmp/ldaptmp/$output`; @dummy = split(/closed - U1/,$content); $nrsplits = scalar(@dummy); $debug < 1 or print "Splits : $nrsplits \n"; for ($part = 0 ; $part < $nrsplits -1 ; $part ++) { open (DUMP,">/tmp/ldaptmp/$output.$part"); print DUMP $dummy[$part]; close DUMP; } # remove original file $remove = `rm /tmp/ldaptmp/$output`; } } $remove = `rm /tmp/ldaptmp/ldaplog.`; opendir WORKDIR, "/tmp/ldaptmp"; @allfiles = grep !/^\.\.?$/, readdir WORKDIR; closedir WORKDIR; $nrfiles = scalar @allfiles; for ($filenr = 0 ; $filenr <= $nrfiles ; $filenr++) { $operationfile = "/tmp/ldaptmp/@allfiles[$filenr]"; Analyse_Files; } } ############### Main ####################### # Onscreen; Defaults; $argc = scalar (@ARGV); if ($argc < 2) { Fewparam; } else { # Determining output mode if ( $ARGV[0] eq "-w" ) { $webbish = 1; $inputfile = $ARGV[1]; $outputfile = $ARGV[2]; } if ( $ARGV[0] eq "-t" ) { $text = 1; $inputfile = $ARGV[1]; $outputfile = $ARGV[2]; } if ( $ARGV[0] eq "-m" ) { $text = 1; $inputfile = $ARGV[2]; if ($argc < 3) { Fewparam; } $mail = 1; $email = $ARGV[1]; $outputfile = $ARGV[3]; } # -e $inputfile or $nofile = 1; if ($nofile != 1) { $debug < 1 or print "Analysing $inputfile\n"; # analyse; Split_Files; Report; Output; Cleanup; } else { print "Can't find $inputfile\n"; } }