#!/bin/bash
#-------------------------------------------------------------------------------
# charon_cfglogmon
#-------------------------------------------------------------------------------
# Script is running within crontab that periodically check for log size
#-------------------------------------------------------------------------------
# Copyright (C) 2013-2023 STROMASYS.
# All rights reserved.
# Products: AXP/VAX + PAR
#
VERSION=2.0

for P in $(ls /etc/profile.d/charon*);do . $P;done
. $(dirname $0)/charon_common

BOOTLIST="${CHARONDIR}/utils/charon_gstart.boot"
CFGLASTUPDFILE=${ETCCHARON}/CharonToolkit.cfglastupdate
LOGSIZALERTFILE=${ETCCHARON}/CharonToolkit.logsizealert
LOGINCALERTFILE=${ETCCHARON}/CharonToolkit.logincralert
DEBUG=0

test "$1" = "--debug" && DEBUG=1

#-------------------------------------------------------------------------------
# Function: check log file
#-------------------------------------------------------------------------------
function check_logfile
{
  typeset -i SIZDIF=0
  get_logfile ${GCFG} ${ITEM}
  test -n "${ITEM}" && LOGF=${LOGCONS}
  test ${DEBUG} -eq 1 && echo "DEBUG:   LOGF=<${LOGF}> (ITEM=<${ITEM:-SESSION}>)"
  LOGSIZM=0
  if test -n "${LOGF}"
  then
    if test -L ${LOGF}
    then
      #--- Log file is a symbolic link
      LOGF="$(dirname ${LOGF})/$(readlink -f ${LOGF})"
      if test -e ${LOGF}
      then
        LOGSIZB=$(find ${LOGF} -printf '%s')
        if test -n "$(echo ${LOGSIZB} | tr -d [:digit:])"
        then
          #--- DEBUG
          echo "ERROR/rotating file:"
          echo "LOGF=<${LOGF}>"
          echo "LOGSIZB=<${LOGSIZB}>"
        fi
      else
        LOGSIZB=0
      fi
      LOGSIZK=$(echo ${LOGSIZB}/1024 | bc)
      LOGSIZM=$(echo ${LOGSIZB}/1024/1024 | bc)
      test ${DEBUG} -eq 1 && echo "DEBUG:     -> ${LOGF} = ${LOGSIZB}b (${LOGSIZM}Mb)"
    else
      #--- Log file is a plain file
      if test -e ${LOGF}
      then
        LOGSIZB=$(find ${LOGF} -printf '%s')
        if test -n "$(echo ${LOGSIZB} | tr -d [:digit:])"
        then
          #--- DEBUG
          echo "ERROR/plain file:"
          echo "LOGF=<${LOGF}>"
          echo "LOGSIZB=<${LOGSIZB}>"
        fi
      else
        LOGSIZB=0
      fi
      LOGSIZK=$(echo ${LOGSIZB}/1024 | bc)
      LOGSIZM=$(echo ${LOGSIZB}/1024/1024 | bc)
      test ${DEBUG} -eq 1 && echo "DEBUG:     == ${LOGF} = ${LOGSIZB}b (${LOGSIZM}Mb)"
    fi
    if test ${LOGSIZM} -ge ${MONLOGFILESIZE}
    then
      if test -z "$(grep "^${GCFG};${ITEM:-SESSION};1$" ${LOGSIZALERTFILE} 2>/dev/null)"
      then
        test ${DEBUG} -eq 1 && echo "DEBUG:       $(tput bold)Alert size > ${MONLOGFILESIZE}Mb$(tput sgr0)"

        test -x ${CHARONDIR}/utils/charon_check.alertcmd && \
          echo ${CHARONDIR}/utils/charon_check.alertcmd LOGFILESIZE ${VMNAME} ${LOGF} ${LOGSIZM} ${MONLOGFILESIZE} | at now >/dev/null 2>&1

      else
        test ${DEBUG} -eq 1 && echo "DEBUG:       Alert size already sent"
      fi
      echo "${GCFG};${ITEM:-SESSION};1" >>${LOGSIZALERTFILE}.tmp
    else
      test ${DEBUG} -eq 1 && echo "DEBUG:       no size alert (< ${MONLOGFILESIZE}Mb)"
      echo "${GCFG};${ITEM:-SESSION};0" >>${LOGSIZALERTFILE}.tmp
    fi

    #--- Check log file size increase
    if test ${MONLOGFILEINCR:-0} -gt 0
    then
      #--- For session log only
      if test -z "${ITEM}"
      then
        if test -s ${LOGINCALERTFILE}-${VMNAME}
        then
          #--- Compare the last entry with the current size
          LSIZ=$(tail -1 ${LOGINCALERTFILE}-${VMNAME} | cut -f2 -d';')
          if test ${LOGSIZK} -le ${LSIZ}
          then
            #--- If the current size is lower or equivalent to the last entry then send a counter alert
            if test -e ${LOGINCALERTFILE}-${VMNAME}.alertsent
            then
              test -x ${CHARONDIR}/utils/charon_check.alertcmd && \
                  echo ${CHARONDIR}/utils/charon_check.alertcmd LOGFILEINCROK ${VMNAME} ${LOGF} | at now >/dev/null 2>&1
              
              rm -f ${LOGINCALERTFILE}-${VMNAME}.alertsent 2>/dev/null
              echo "$(date +%s);${LOGSIZK}" >${LOGINCALERTFILE}-${VMNAME}
            fi
          fi

          #--- Search back 1h
          HOURAGO=$(date +%s -d "-1 hour")
          LASTSIZ=""
          test ${DEBUG} -eq 1 && echo "DEBUG        looking in <${LOGINCALERTFILE}-${VMNAME}>"
          for DATSIZ in $(cat ${LOGINCALERTFILE}-${VMNAME})
          do
            test ${DEBUG} -eq 1 && echo "DEBUG        DATSIZ=<${DATSIZ}>"
            LDAT=$(echo ${DATSIZ} | cut -f1 -d';')
            LSIZ=$(echo ${DATSIZ} | cut -f2 -d';')
            test ${DEBUG} -eq 1 && echo "DEBUG        LDAT=<${LDAT}> HOURAGO=<${HOURAGO}>"

            if test -z "$(echo ${LDAT} | tr -d [:digit:])"
            then
              if test ${LDAT} -gt ${HOURAGO}
              then
                test ${DEBUG} -eq 1 && echo "DEBUG        LASTSIZ=<${LASTSIZ}>"
                if test -n "${LASTSIZ}"
                then
                  SIZDIF=${LOGSIZK}-${LASTSIZ}
                  test ${DEBUG} -eq 1 && echo "DEBUG        SIZDIF=<${SIZDIF}>  LOGSIZK=<${LOGSIZK}>"
                  if test ${SIZDIF} -gt ${MONLOGFILEINCR}
                  then
                    if test -e ${LOGINCALERTFILE}-${VMNAME}.alertsent
                    then
                      test ${DEBUG} -eq 1 && echo "DEBUG        $(tput smso) ALERT INCREASE already sent $(tput rmso)"
                    else
                      test ${DEBUG} -eq 1 && echo "DEBUG        $(tput smso) ALERT INCREASE $(tput rmso)"
                      touch ${LOGINCALERTFILE}-${VMNAME}.alertsent

                      test -x ${CHARONDIR}/utils/charon_check.alertcmd && \
                          echo ${CHARONDIR}/utils/charon_check.alertcmd LOGFILEINCR ${VMNAME} ${LOGF} ${LOGSIZK} ${SIZDIF} ${MONLOGFILEINCR} | at now >/dev/null 2>&1
                    fi
                  fi
                fi
                break
              fi
              LASTSIZ=${LSIZ}
            else
              test ${DEBUG} -eq 1 && echo "DEBUG        Not numeric, skipped"
            fi
          done
          cp -f ${LOGINCALERTFILE}-${VMNAME} ${LOGINCALERTFILE}-${VMNAME}.tmp
        else
          rm -f ${LOGINCALERTFILE}-${VMNAME}.tmp 2>/dev/null
          touch ${LOGINCALERTFILE}-${VMNAME}.tmp
          rm -f ${LOGINCALERTFILE}-${VMNAME}.alertsent 2>/dev/null
        fi
        echo "$(date +%s);${LOGSIZK}" >>${LOGINCALERTFILE}-${VMNAME}.tmp
        tail -60 ${LOGINCALERTFILE}-${VMNAME}.tmp >${LOGINCALERTFILE}-${VMNAME}
        if test ${DEBUG} -eq 1
        then
          echo -n "DEBUG:        ${LOGINCALERTFILE}-${VMNAME} lines count:"
          cat ${LOGINCALERTFILE}-${VMNAME} | wc -l
        fi
        rm -f ${LOGINCALERTFILE}-${VMNAME}.tmp 2>/dev/null
      fi
    fi
  fi
}


#===============================================================================
# Main script start
#===============================================================================
get_preferences

if test -e ${MAILTOFILE}
then
  MAILTO=$(grep -v "^#" ${MAILTOFILE} | sort -u | tr "\n" ","| sed "s=,$==g")
else
  MAILTO="root@$(hostname),support@stromasys.com"
fi
MAILMODE=$(cat ${MAILMODEFILE} 2>/dev/null)
test "${MAILMODE}" != "TEXT" && MAILMODE="HTML"
MAILFILE="/tmp/$(basename $0).$(date +"%Y%m%d.%H%M%S.%N")"

#--- Read managed guests list and perform checks
rm -f ${CFGLASTUPDFILE}.tmp ${LOGSIZALERTFILE}.tmp 2>/dev/null
cat ${BOOTLIST} 2>/dev/null | while read LINE
do
  GCFG=$(echo ${LINE} | cut -f2 -d';')
  VMNAME=$(basename ${GCFG} | sed "s=\.cfg==g")
  test ${DEBUG} -eq 1 && echo "DEBUG: ${GCFG}"
  if test "${MONCFGFILEUPDATE}" = "enabled"
  then
    CURRCFGUPD=$(date +%s -r ${GCFG})
    DISPCFGUPD=$(date +"%d-%b-%Y %H:%M:%S" -r ${GCFG})
    LASTCFGUPD=$(grep "^${GCFG};" ${CFGLASTUPDFILE} 2>/dev/null | cut -f2 -d';')
    if test -n "${LASTCFGUPD}"
    then
      if test ${CURRCFGUPD} -ne ${LASTCFGUPD}
      then
        test ${DEBUG} -eq 1 && echo "DEBUG:   -> $(tput bold)updated since last check$(tput sgr0)"
        systemctl -q is-active charon_$(basename ${GCFG} | sed "s=\.cfg==g")
        if test $? -eq 0
        then
          test ${DEBUG} -eq 1 && echo "DEBUG:   -> $(tput bold)service is running$(tput sgr0)"
          SVCSTA="running"
        else
          test ${DEBUG} -eq 1 && echo "DEBUG:   -> service is not running"
          SVCSTA="not running"
        fi

        test -x ${CHARONDIR}/utils/charon_check.alertcmd && \
          echo ${CHARONDIR}/utils/charon_check.alertcmd CFGUPDATE ${VMNAME} ${GCFG} \"${DISPCFGUPD}\" \"${SVCSTA}\" | at now >/dev/null 2>&1

      fi
    fi
    echo "${GCFG};${CURRCFGUPD}" >>${CFGLASTUPDFILE}.tmp
  else
    test ${DEBUG} -eq 1 && echo "DEBUG:   -> update time not monitored"
  fi

  GCNF=$(basename ${GCFG} | sed "s=\.cfg$==g")
  if test ${MONLOGFILESIZE} -gt 0
  then
    if test "${KITP}" = "AXP/VAX"
    then
      for ITEM in "" "OPA0"
      do
        check_logfile
      done
    else
      ITEM=""
      check_logfile
    fi
  else
    test ${DEBUG} -eq 1 && echo "DEBUG:       log size monitoring is disabled"
  fi
done
test -e ${CFGLASTUPDFILE}.tmp  && mv -f ${CFGLASTUPDFILE}.tmp  ${CFGLASTUPDFILE}
test -e ${LOGSIZALERTFILE}.tmp && mv -f ${LOGSIZALERTFILE}.tmp ${LOGSIZALERTFILE}

exit
