added debianizated version of bfha.pl

master
Evgeniy Kozhuhovskiy 20 years ago
parent 252fcf6717
commit 2d9618e6fd

@ -0,0 +1,575 @@
#!/usr/bin/perl
#
# bfha -- binkleyforce history analyzer
#
# Copyright (C) 2000 Serge N. Pokhodyaev
#
# E-mail: snp@ru.ru
# Fido: 2:5020/1838
#
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
#
# $Id$
#
#
# çÅÎÅÒÉÔ ÓÔÁÔÉÓÔÉËÕ ÚÁ ÐÒÅÄÙÄÕÝÉÊ ÄÅÎØ
#
#
# TODO:
#
# 1. õÞÅÓÔØ ÓÌÕÞÁÊ, ËÏÇÄÁ ÌÏÇ ÐÏ×£ÒÎÕÔ logrotate'ÏÍ
#
# Known bugs:
#
# 1. HÅÐÒÁ×ÉÌØÎÏ ÓÞÉÔÁÅÔ cps (ÚÁ×ÙÛÁÅÔ) ÅÓÌÉ ÔÒÁÆÉË × ÏÂÅ ÓÔÏÒÏÎÙ
#
use strict;
use Time::Local;
use POSIX qw(strftime);
my $PROGNAME = 'bfha';
my $VERSION = '$Revision$ ';
######## Configurable part ###################################################
#my $inews = "/usr/bin/inews -h -O -S";
#my $log = "/var/log/fido/history";
#my $rep_newsgroups = "ftn.1838.stat";
#my $rep_from = "\"Statistics generator\" <snp\@gloom.intra.eu.org>";
#my $rep1_subj = "Sessions history";
#my $rep2_subj = "Sessions history";
#my $rep3_subj = "Links statistics";
my $count_failed = 1;
#my %line_names = (
# "ttyS1" => "Modem",
# "tcpip" => "IP"
#);
##############################################################################
my $devel = 0;
my (%st, %lines, %nodes, @nodes_sorted);
my @tm;
my $time;
die "Usage: $PROGNAME [-d]\n" if (!((0 == $#ARGV) && ($ARGV[0] eq '-d')) && !(-1 == $#ARGV));
$devel = 1 if ((0 == $#ARGV) && ($ARGV[0] eq '-d'));
$log = "./history" if ($devel);
# Make version string
#
$VERSION =~ s/(\$Rev)ision:\s([\d.]+).*/$PROGNAME\/$2/;
# Get time of 0:00:00 of yesterday
#
@tm = localtime(time - 86400);
$tm[0] = 0; # sec
$tm[1] = 0; # min
$tm[2] = 0; # hours
$time = timelocal(@tm);
# At first read logs
#
undef %st;
undef %lines;
undef %nodes;
die "Log reading error\n" if (0 != log_read($time));
@nodes_sorted = sort(node_cmp keys(%nodes));
# Now generate statistics
#
out_close();
#rep1();
rep2();
rep3();
sub log_read
{
my $i;
my $t;
my @l;
die if (0 != $#_);
$t = $_[0];
open(LOG, "< $log") || die("Can't open $log: $!\n");
while (<LOG>)
{
chomp;
@l = split(/,/);
return 1 if ($#l != 11);
return 1 if (! ($l[4] =~ /[IO]/));
# Check date
#
next if ($l[2] < $t);
last if ($l[2] >= ($t + 86400));
# Entries without address
#
if ($l[1] eq '')
{
next if (0 == $count_failed);
$l[1] = 'failed' if (0 != $count_failed);
}
# Remove domain
#
$l[1] =~ s/@.*$//;
# Add statistics
#
$i = $#{$st{beg}} + 1;
$lines{$l[0]}[$#{$lines{$l[0]}} + 1] = $i;
$nodes{$l[1]}[$#{$nodes{$l[1]}} + 1] = $i;
$st{beg}[$i] = $l[2];
$st{len}[$i] = $l[3];
$st{addr}[$i] = $l[1];
$st{line}[$i] = $l[0];
$st{rc}[$i] = $l[5];
$st{snt_nm}[$i] = $l[6];
$st{snt_am}[$i] = $l[7];
$st{snt_f}[$i] = $l[8];
$st{rcv_nm}[$i] = $l[9];
$st{rcv_am}[$i] = $l[10];
$st{rcv_f}[$i] = $l[11];
$st{islst}[$i] = 0;
$st{islst}[$i] = 1 if ($l[4] =~ /L/);
$st{isprot}[$i] = 0;
$st{isprot}[$i] = 1 if ($l[4] =~ /P/);
$st{type}[$i] = 'I' if ($l[4] =~ /I/);
$st{type}[$i] = 'O' if ($l[4] =~ /O/);
}
}
######## rep1 ################################################################
sub rep1
{
my ($i, $j);
my (%se, %se_t);
my $node;
out_open($rep1_subj);
printf "Date: %s\n\n", strftime("%a, %e %b %Y", localtime($time));
$~ = "rep1_header";
write;
$~ = "rep1_body";
$se_t{num_in} = 0;
$se_t{num_out} = 0;
$se_t{snt} = 0;
$se_t{rcv} = 0;
$se_t{len} = 0;
foreach $node (@nodes_sorted)
{
$se{num_in} = 0;
$se{num_out} = 0;
$se{snt} = 0;
$se{rcv} = 0;
$se{len} = 0;
for ($i = 0; $i <= $#{$nodes{$node}}; ++$i)
{
$j = $nodes{$node}[$i];
++$se{num_in} if ($st{type}[$j] eq 'I');
++$se{num_out} if ($st{type}[$j] eq 'O');
$se{snt} += $st{snt_am}[$j] + $st{snt_nm}[$j] + $st{snt_f}[$j];
$se{rcv} += $st{rcv_am}[$j] + $st{rcv_nm}[$j] + $st{rcv_f}[$j];
$se{len} += $st{len}[$j];
}
$se{time} = time_int2str($se{len});
# FIXME (cps)
$se{cps} = div_int(($se{snt} + $se{rcv}), $se{len});
write;
$se_t{num_in} += $se{num_in};
$se_t{num_out} += $se{num_out};
$se_t{snt} += $se{snt};
$se_t{rcv} += $se{rcv};
$se_t{len} += $se{len};
}
$~ = "rep1_footer";
$se_t{time} = time_int2str($se_t{len});
# FIXME (cps)
$se_t{cps} = div_int(($se_t{snt} + $se_t{rcv}), $se_t{len});
write;
print "\n";
out_close();
format rep1_header =
¥                                                                    ¨
¡ System <EFBFBD> Sessions <EFBFBD> Sent <EFBFBD> Received <EFBFBD> Time <EFBFBD> CPS ¡
¡ address <EFBFBD> in out <EFBFBD> bytes <EFBFBD> bytes <EFBFBD> online <EFBFBD> ¡
±                 ¼          ¼           ¼            ¼           ¼       µ
.
format rep1_body =
¡ @<<<<<<<<<<<<<< <EFBFBD> @>> @>> <EFBFBD> @>>>>>>>> <EFBFBD> @>>>>>>>>> <EFBFBD> @>>>>>>>> <EFBFBD> @>>>> ¡
$node, $se{num_in}, $se{num_out}, $se{snt}, $se{rcv}, $se{time}, $se{cps}
.
format rep1_footer =
°ŠŠŠŠŠ´
¡ TOTAL <EFBFBD> @>> @>> <EFBFBD> @>>>>>>>> <EFBFBD> @>>>>>>>>> <EFBFBD> @>>>>>>>> <EFBFBD> @>>>> ¡
$se_t{num_in}, $se_t{num_out}, $se_t{snt}, $se_t{rcv}, $se_t{time}, $se_t{cps}
«                 ¹          ¹           ¹            ¹           ¹       ®
.
}
######## rep2 ################################################################
sub rep2
{
my ($i, $j);
my @t;
my ($t1, $t2, $str, $lv);
my $node;
my %se;
out_open($rep2_subj);
printf "Date: %s\n\n", strftime("%a, %e %b %Y", localtime($time));
$~ = "rep2_header";
write;
$~ = "rep2_body";
foreach $node (@nodes_sorted)
{
$se{snt} = 0;
$se{rcv} = 0;
$se{len} = 0;
for ($i = 0; $i <= 95; ++$i)
{
$t[$i] = 0;
}
for ($i = 0; $i <= $#{$nodes{$node}}; ++$i)
{
$j = $nodes{$node}[$i];
# Fill array
#
$t1 = $st{beg}[$j] - $time;
$t2 = $t1 + $st{len}[$j];
$t2 = 86399 if ($t2 > 86399);
$t1 = div_int($t1, 900);
$t2 = div_int($t2, 900);
while ($t1 <= $t2)
{
$t[$t1++] = 1;
}
$se{snt} += $st{snt_am}[$j] + $st{snt_nm}[$j] + $st{snt_f}[$j];
$se{rcv} += $st{rcv_am}[$j] + $st{rcv_nm}[$j] + $st{rcv_f}[$j];
$se{len} += $st{len}[$j];
}
$se{time} = time_int2str($se{len});
# FIXME (cps)
$se{cps} = div_int(($se{snt} + $se{rcv}), $se{len});
# Visualize
#
$i = 0;
$str = "";
if ($t[$i++])
{
$str = $str . "<22>";
}
else
{
$str = $str . "<22>";
}
while ($i < $#t)
{
$lv = 0;
$lv += 1 if ($t[$i++]);
$lv += 2 if ($t[$i++]);
if (0 == $lv)
{
if (div_rest(($i - 1), 8) == 0)
{
$str = $str . "<22>";
}
else
{
$str = $str . " ";
}
}
elsif (1 == $lv)
{
$str = $str . "Ž";
}
elsif (2 == $lv)
{
$str = $str . "<22>";
}
elsif (3 == $lv)
{
$str = $str . "<22>";
}
}
if ($t[$i])
{
$str = $str . "Ž";
}
else
{
$str = $str . "<22>";
}
write;
}
$~ = "rep2_footer";
write;
out_close();
format rep2_header =
0 2 4 6 8 10 12 14 16 18 20 22 24
ŠŠŠŠŠŠŠŠŠŠŠ
.
format rep2_body =
@<<<<<<<<<<<<<<@||||||||||||||||||||||||||||||||||||||||||||||||
$node, $str
.
format rep2_footer =
ˆŠˆŠˆŠˆŠˆŠˆŠˆŠˆŠˆŠˆŠˆŠˆ
0 2 4 6 8 10 12 14 16 18 20 22 24
.
}
######## rep3 ################################################################
sub rep3
{
my $node;
my (%se, %se_t);
my ($i, $j);
out_open($rep3_subj);
printf "Date: %s\n\n", strftime("%a, %e %b %Y", localtime($time));
$~ = "rep3_header";
write;
$~ = "rep3_body";
$se_t{num_in} = 0;
$se_t{num_out} = 0;
$se_t{time_in} = 0;
$se_t{time_out} = 0;
$se_t{snt} = 0;
$se_t{rcv} = 0;
$se_t{time} = 0;
foreach $node (@nodes_sorted)
{
$se{num_in} = 0;
$se{num_out} = 0;
$se{time_in} = 0;
$se{time_out} = 0;
$se{snt} = 0;
$se{rcv} = 0;
$se{time} = 0;
for ($i = 0; $i <= $#{$nodes{$node}}; ++$i)
{
$j = $nodes{$node}[$i];
++$se{num_in} if ($st{type}[$j] eq 'I');
++$se{num_out} if ($st{type}[$j] eq 'O');
$se{time_in} += $st{len}[$j] if ($st{type}[$j] eq 'I');
$se{time_out} += $st{len}[$j] if ($st{type}[$j] eq 'O');
$se{snt} += $st{snt_am}[$j] + $st{snt_nm}[$j] + $st{snt_f}[$j];
$se{rcv} += $st{rcv_am}[$j] + $st{rcv_nm}[$j] + $st{rcv_f}[$j];
$se{time} += $st{len}[$j];
}
# Total counters
#
$se_t{num_in} += $se{num_in};
$se_t{num_out} += $se{num_out};
$se_t{snt} += $se{snt};
$se_t{rcv} += $se{rcv};
$se_t{time} += $se{time};
$se_t{time_out} += $se{time_out};
$se_t{time_in} += $se{time_in};
# Output string
#
# FIXME (cps)
$se{cps} = dash_if_zero(div_int(($se{snt} + $se{rcv}), $se{time}));
$se{time} = time_int2str($se{time});
$se{time_in} = time_int2str($se{time_in});
$se{time_out} = time_int2str($se{time_out});
$se{num_in} = dash_if_zero($se{num_in});
$se{num_out} = dash_if_zero($se{num_out});
$se{rcv} = shrink_size(dash_if_zero($se{rcv}));
$se{snt} = shrink_size(dash_if_zero($se{snt}));
write;
}
$~ = "rep3_footer";
# FIXME (cps)
$se_t{cps} = dash_if_zero(div_int(($se_t{snt} + $se_t{rcv}), $se_t{time}));
$se_t{time} = time_int2str($se_t{time});
$se_t{time_in} = time_int2str($se_t{time_in});
$se_t{time_out} = time_int2str($se_t{time_out});
$se_t{num_in} = dash_if_zero($se_t{num_in});
$se_t{num_out} = dash_if_zero($se_t{num_out});
$se_t{rcv} = shrink_size(dash_if_zero($se_t{rcv}));
$se_t{snt} = shrink_size(dash_if_zero($se_t{snt}));
$~ = "rep3_footer";
write;
print "\n";
out_close();
format rep3_header =
¥                ¸                           ¸          ¸             ¸       ¨
¡ ¡ Sessions/Online ¡ Time ¡ Traffic ¡ ¡
¡ Address ±             ¸             µ online ±      ¸      µ CPS ¡
¡ ¡ Incoming ¡ Outgoing ¡ ¡ Rcvd ¡ Sent ¡ ¡
±                ¾            ¾            ¾          ¾      ¾      ¾       µ
.
format rep3_body =
¡ @<<<<<<<<<<<<<<¡@>><EFBFBD>@>>>>>>> ¡@>><EFBFBD>@>>>>>>> ¡@>>>>>>>> ¡@>>>>>¡@>>>>>¡@>>>>> ¡
$node, $se{num_in}, $se{time_in}, $se{num_out}, $se{time_out}, $se{time}, $se{rcv}, $se{snt}, $se{cps}
.
format rep3_footer =
°½Š½Š½½½½´
¡ TOTAL ¡@>><EFBFBD>@>>>>>>> ¡@>><EFBFBD>@>>>>>>> ¡@>>>>>>>> ¡@>>>>>¡@>>>>>¡@>>>>> ¡
$se_t{num_in}, $se_t{time_in}, $se_t{num_out}, $se_t{time_out}, $se_t{time}, $se_t{rcv}, $se_t{snt}, $se_t{cps}
«                »   ¹         »   ¹         »          »      »      »       ®
.
}
##############################################################################
sub shrink_size
{
die if (0 != $#_);
return $_[0] if ($_[0] < 1024);
return sprintf("%.1fk", $_[0] / 1024) if ($_[0] < 1048576);
return sprintf("%.1fM", $_[0] / 1048576);
}
sub dash_if_zero
{
die if (0 != $#_);
return "-" if (0 == $_[0]);
return $_[0];
}
sub time_int2str
{
my $time;
my $h;
my $m;
my $s;
die if (0 != $#_);
die if (86399 < $time);
return "-:--:--" if (0 == $_[0]);
$time = $_[0];
$h = div_int($time, 3600);
$time = div_rest($time, 3600);
$m = div_int($time, 60);
$s = div_rest($time, 60);
return sprintf("%d:%2.2d:%2.2d", $h, $m, $s);
}
# ãÅÌÏÞÉÓÌÅÎÎÏÅ ÄÅÌÅÎÉÅ
sub div_int
{
use integer;
die if (1 != $#_);
return 0 if ($_[1] == 0);
return $_[0] / $_[1];
}
# ïÓÔÁÔÏË ÏÔ ÃÅÌÏÞÉÓÌÅÎÎÏÇÏ ÄÅÌÅÎÉÑ
sub div_rest
{
die if (1 != $#_);
return 0 if ($_[1] == 0);
return $_[0] - (div_int($_[0], $_[1]) * $_[1]);
}
sub out_open
{
die if (0 != $#_);
open(STDOUT, "| $inews") || die("Can't pipe to inews: $!\n") if (! $devel);
printf "Newsgroups: %s\n", $rep_newsgroups;
printf "From: %s\n", $rep_from;
printf "Subject: %s\n", $_[0];
printf "X-FTN-Tearline: %s\n\n", $VERSION;
}
sub out_close
{
close(STDOUT) if (! $devel);
}
sub node_cmp
{
my (@na, @nb);
@na = split('[:/.]', $::a);
@nb = split('[:/.]', $::b);
# zone
return -1 if ($na[0] < $nb[0]);
return 1 if ($na[0] > $nb[0]);
# net
return -1 if ($na[1] < $nb[1]);
return 1 if ($na[1] > $nb[1]);
# node
return -1 if ($na[2] < $nb[2]);
return 1 if ($na[2] > $nb[2]);
#point
return -1 if ($na[3] < $nb[3]);
return 1 if ($na[3] > $nb[3]);
return 0;
}
Loading…
Cancel
Save