#!/usr/local/bin/perl

# This software is Copyright (c) 1996 Jeff Weisberg <jaw@op.net>
# Permission is granted to use, copy and distribute this software
# under the following conditions:
#     -   This license covers the original software, as well as
#         modified or derived works.
#     -   All modified or derived works must contain this notice
#         unmodified and in its entirety.
#     -   This software is not to be used for any purpose which
#         may be considered illegal, immoral, or unethical.
#     -   This software is provided as is and without warranty.


# this program generates stats on incoming/outgoing feeds
# by analyzing the news syslog file

# here at OpNet this runs daily on the past days log file
# (a separate script rotates the logs...)


while( <> ){

    if( /nntplink.*: (.*) stats (.*) offered (.*) accepted (.*) rejected (.*) failed (.*) connects/ ){
	($site, $offr, $givn, $rej, $fail, $conn) = ($1, $2, $3, $4, $5, $6);

	$totalout += $givn;
	$site = canon( $site );
	$osites{$site} = 1;
	
	$nntp_offr{ $site } += $offr;
	$nntp_givn{ $site } += $givn;
	$nntp_offr{ 'Total:' } += $offr;
	$nntp_givn{ 'Total:' } += $givn;
    }
    if( /innxmit.*: (.*) stats offered (.*) accepted (.*) refused (.*) rejected (.*)/ ){
	($site, $offr, $givn, $refu, $rej) = ($1, $2, $3, $4, $5);

	$totalout += $givn;
	$site = canon( $site );
	$osites{$site} = 1;
	
	# sometimes innxmit reports more accepted than offered, why?
	$offr = $givn + $refu + $rej;
	
	$innx_offr{ $site } += $offr;
	$innx_givn{ $site } += $givn;
	$innx_offr{ 'Total:' } += $offr;
	$innx_givn{ 'Total:' } += $givn;
    }
# innfeed[8778]: nntp.netaxs.com.0:1 final seconds 3736 offered 2290 accepted 930 refused 1095 rejected 282

    if( /innfeed.*: (.*) final.*offered (.*) accepted (.*) refused (.*) rejected (.*)/ ){
	($site, $offr, $givn, $refu, $rej) = ($1, $2, $3, $4, $5);

	$site =~ s/:[0-9]$//;
	$site =~ s/\.[0-9]$//;
	
	$totalout += $givn;
	$site = canon( $site );
	$osites{$site} = 1;

	$offr = $givn + $refu + $rej;

	$innf_offr{ $site } += $offr;
	$innf_givn{ $site } += $givn;
	$innf_offr{ 'Total:' } += $offr;
	$innf_givn{ 'Total:' } += $givn;
    }

    if( /innd.*: (.*):.*closed seconds (.*) accepted (.*) refused (.*) rejected (.*)/ ){
	($site, $secs, $takn, $refu, $rej) = ($1, $2, $3, $4, $5);

	$totalin += $takn;
	$site = canon( $site );
	$isites{$site} = 1;
	
	$innd_offr{ $site } += $takn + $refu + $rej;
	$innd_takn{ $site } += $takn;
	$innd_offr{ 'Total:' } += $takn + $refu + $rej;
	$innd_takn{ 'Total:' } += $takn;
    }
}

printf <<EOH;
Incoming Feed Stats:
site                      offer  taken
=======================================
EOH
    ;

foreach $site ( (sort keys %isites), 'Total:' ){

    printf "%-24s %6d %6d\n", $site, $innd_offr{$site}, $innd_takn{$site};
}

printf <<EOH;

Outgoing Feed Stats:
                            NNTPLINK      INNXMIT       INNFEED        TOTAL
site                      offer  accpt  offer  accpt  offer  accpt   offer accpt
================================================================================
EOH
    ;

foreach $site ( (sort keys %osites), 'Total:' ){
    printf "%-24s %6d %6d %6d %6d %6d %6d   %6d %6d\n", $site, $nntp_offr{$site}, $nntp_givn{$site},
    $innx_offr{$site}, $innx_givn{$site},
    $innf_offr{$site}, $innf_givn{$site},
  
    $nntp_offr{$site}+$innx_offr{$site}+$innf_offr{$site}, $nntp_givn{$site}+$innx_givn{$site}+$innf_givn{$site};
}

print <<EOH;

Feed Ratio Stats:
                            Prcnt Accpt     Prcnt of Total        IN/OUT
site                         IN     OUT        IN     OUT      Offr    Accpt
============================================================================
EOH
    ;

foreach $site ( (sort keys %osites), 'Total:' ){
    printf "%-24s %6.2f  %6.2f    %6.2f  %6.2f    %6.2f   %6.2f\n", $site,
    ($innd_offr{$site} ? $innd_takn{$site}/$innd_offr{$site} * 100 : 0),
    (($nntp_offr{$site}+$innx_offr{$site})?
     ($nntp_givn{$site}+$innx_givn{$site})/($nntp_offr{$site}+$innx_offr{$site}) * 100 : 0),
    $innd_takn{$site}/$totalin * 100,
    ($nntp_givn{$site}+$innx_givn{$site})/$totalout * 100,

    (($nntp_offr{$site}+$innx_offr{$site})?
     $innd_offr{$site}/($nntp_offr{$site}+$innx_offr{$site}) : 1),
	    
    (($nntp_givn{$site}+$innx_givn{$site})?
     $innd_takn{$site}/($nntp_givn{$site}+$innx_givn{$site}) : 1);
}

print "\n";

# END

# canonicalize hostname (since log file will usually have different names
# for the same site (incoming will be canon, outgoing will usu. be a cname))

sub canon {
    local( $h ) = @_;
    local ($name, $aliases, $addrtype, $length, $address);

    $h =~ s/:.*//;
    $h =~ s/news[0-9]/news/;	# collapse news1, news2 -> news
   
    $name = $canon{$h};
    return $name if $name; 
    
    ($name, $aliases, $addrtype, $length, $address) = gethostbyname($h);
    if( length $address){
	($name, $aliases, $addrtype, $length, $address) = gethostbyaddr($address, 2);
	($name, $aliases, $addrtype, $length, $address) = gethostbyaddr($address, 2) unless $name;
    }else{
	$name = $h;
    }
    $name = $h unless $name;
    $name =~ s/news[0-9]/news/;	# collapse news1, news2 -> news
    
    $name = substr($name, 0, 24);
    $canon{$h} = $name;		# memoize
    return $name;
}

