#!/usr/bin/perl
#
#  $Id$
# -----------------------------------------------------------------------------
#  cache_log - daemon that watches cache status and dumps its content if cache 
#  gets overflown
# -----------------------------------------------------------------------------
#  Author: Alex Tsybylnik
#  QA by:
#  Copyright: videoNEXT LLC
# -----------------------------------------------------------------------------

use strict;
use warnings;

# CONS
my $APL = $ENV{APL};
my $APL_VAR = $ENV{APL_VAR};
my $SLEEP = 60; # Watch every 1 min
my $CACHE_DUMP_TMT = 1200; # Dump cache content every 20 min in case of overflow
my $CACHESTATUS = "$APL/cache/bin/cachestatus";
my $LOG_CNT = 5; # Number of log files
my $LOG_SIZE = 5; # Size of log file (MB)
my $PCT_THRESH = 80; # % of space used when cache content should be logged
my $LOG = "$APL_VAR/log/cache/cache.log";

# VARS
my $Last_Cache_Dump_TS = 0;

# SUBS
sub time2ts {
  my $tm=shift;
  my ($tsec,$tmin,$thour,$tday,$tmon,$tyear)=gmtime($tm);
  my $yymmdd=sprintf("%02d/%02d/%02d",$tyear+1900,$tmon+1,$tday);
  my $hh=sprintf("%02d",$thour);
  my $mi=sprintf("%02d",$tmin);
  my $ss=sprintf("%02d",$tsec);
  return "$yymmdd $hh:$mi:$ss";
}

sub logrotate {
    return unless -f $LOG;
    my $sz = ( (stat $LOG)[7] / (1024 *1024) );
    if ($sz > $LOG_SIZE) {
        for (my $i = $LOG_CNT - 2; $i >= 1; $i--) {
            my $j = $i+1;
            rename("${LOG}.${i}", "${LOG}.${j}") if -f "${LOG}.${i}";
        }
        rename $LOG, "$LOG.1";
    }
}

sub cache_log {
    my $msg = shift;

    logrotate;
    
    my $tm = time2ts time;
    chomp $msg;
    open LOG, ">>$LOG" or die "open(): $!";
    print LOG "$tm $msg\n";
    close LOG or die "close(): $!";
}

sub watch_cache {
    my $out = `$CACHESTATUS 2>/dev/null`;
    return unless $out;
    chomp $out;
    my ($status, $total, $avail) = $out=~/^(\w+)\s+(\d+)\s+(\d+)$/;
    return if not defined $status;
    return if $status ne 'on';

    my $pct_free = int( ($avail / $total) * 100 );
    my $pct_used = 100 - $pct_free;
    my $msg = "FREE=$avail (${pct_free}%)\n";
    if ($pct_used > $PCT_THRESH && (time - $Last_Cache_Dump_TS) > $CACHE_DUMP_TMT) {
        # Dump cache content
        $msg .= "Cache usage limit reached ($pct_used%). Dump content:\n";
        $msg .= `/usr/bin/find /vasm/cache 2>/dev/null`;
        $Last_Cache_Dump_TS = time;
    }
    
    cache_log $msg;
}

# MAIN
while (1) {
    watch_cache;
    sleep $SLEEP;
}
