TSM kliens riport shell szkript

TSM kliens ütemezések sikerességét riportoló szkript. A riport szabályokat a „tsm_kliens_riport.<TSM sztanza>” fájlokból veszi, aminek a formátuma:

email cím; (sql WHERE feltétel az events, mint „e” táblából) order by <rendező mező> Pl:

fonok@cegem.hu; (e.node_name='FONOK_SZERVERE' or e.schedule_name like 'NAPI_INCR_%') ORDER BY e.schedule_name

Ha egy email címhez több sor is van, azokat külön szekcióba teszi a riportban. A szabály fájlokat külön dolgozza fel, tehát ha nekem 2 sztanzához tartozó szabály fájlban is van sor az email címemmel, akkor TSM szerverenként külön emailben kapom a riportokat majd. A TSM_SZERVEREK változóban fel kell sorolni a TSM sztanzákat, amiket akarunk, hogy vizsgáljon. Az ebben beállított sztanzák szabályfájljait fogja keresni a „tsm_kliens_riport.<TSM sztanza>” néven.

tsm_kliens_report.sh
#!/bin/sh
PATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
################################################################
#                                                              #
#  TSM kliens riport - tsm_kliens_riport.sh v1.3 (2022.06.16.) #
#  Keszitette: Agoston Peter (agoston.peter@gmail.com)         #
#                                                              #
################################################################
        SCRIPT_VER="v1.3 (2022.06.16.)"
# Riport cimzett(ek)
# Milyen email cim(ek)re menjen a riport
        MAILTO=$1
# TSM admin
        TSM_FELH="report"
        TSM_JELSZO="report"
# Riportolando TSM szerver sztanzak
        TSM_SZERVEREK="tsma1 tsmg1"
# HTML formatumu legy-e a level (0/1)
        HTML_EMAIL=1
# Csatolmanykent el legyen-e kuldve a HTML riport, ha egyebkent szoveges levelkent megy a riport (0/1)
        HTML_EMAIL_CSAT=1
# Munkafajl a futas idejere
        TMP_FILE='/tmp/tsm_kliens_riport.tmp'
        TMP_HTML_FILE='/tmp/tsm_kliens_riport.tmp.html'
# Mappa, ahova a futasi eredmenyeket elmenti
        LOG_DIR='/opt/tsm_kliens_riport/riportok'
# Konfig resz vege #########################################################################################################################
# Hasznalt SQL selectek TSM-hez
SQL_Q_FAILED_EVENTS="select substr(e.node_name,1,20) as \"NODE NAME\", e.schedule_name, cast ( SUBSTR ( CHAR ( e.actual_start ) , 1 , 19 ) as char ( 20 ) ) AS \"ACTUAL START\", case when e.status='Missed' then '' else TRANSLATE('a bc:de:fg', DIGITS(e.completed - e.actual_start), '_______abcdefgh_____',' ') end as \"RUNTIME  \", case when e.result=0 then '  0-Successful' when e.result=4 then '  4-Skipped Files' when e.result=8 then '  8-Warnings' when e.result=12 then ' 12-Failed' when e.result is NULL then '   -' || substr(e.status,1,12) else ( case when length(cast(e.result as char))=1 then '  ' || cast(e.result as char) || '-' || substr(e.status,1,12) when length(cast(e.result as char))=2 then ' ' || cast(e.result as char) || '-' || substr(e.status,1,12) else cast(e.result as char) || '-' || substr(e.status,1,11) end ) end as \"RESULT\" from events e where (current_timestamp - 24 hours)<e.scheduled_start and e.scheduled_start<current_timestamp and e.node_name is not NULL and e.status not in ('Pending') "
# HTML kodok
HTML_VONAL="<hr align=center noshade style=\"color: #D2D2D2; width: 100%;\" size=\"1\">"
HTML_MODUL_LABLEC="</pre></div>"
HTML_TABLA_FEJLEC="<table style=\"width: auto; border: 2px solid #D2D2D2;background-color:#F1F1F1; padding: 15px; font-size: 14px; font-family: courier;\"><tr><td style=\"display: inline; text-align: center\">"
HTML_TABLA_LABLEC="</td></tr></table>"
# Fuggvenyek, egyeb valtozok
SSH_OPT="-o BatchMode=yes -o ConnectTimeout=5 -i $SSH_KEY_FILE"
export LANG=en_US
 
read -r -d '' JS_CODE << EOF
<head>
<script language="JavaScript" type="text/javascript">
<!-- Copyright 2005, Sandeep Gangadharan -->
<!-- For more free scripts go to http://www.sivamdesign.com/scripts/ -->
<!--
if (document.getElementById) {
document.writeln('<style type="text/css"><!--')
document.writeln('.texter {display:block} @media print {.texter {display:block;}}')
document.writeln('//--></style>') }
 
function openClose(theID) {
if (document.getElementById(theID).style.display == "block") { document.getElementById(theID).style.display = "none" }
else { document.getElementById(theID).style.display = "block" } }
 
function Collapse(ez) {
if (ez.style.color == "gray") { ez.style.color = "#006DC7"; ez.innerHTML=ez.innerHTML.replace("[+]","[-]"); ez.innerHTML=ez.innerHTML.replace("gray","#006DC7")}
else { ez.style.color = "gray"; ez.innerHTML=ez.innerHTML.replace("[-]","[+]"); ez.innerHTML=ez.innerHTML.replace("#006DC7","gray") } }
// -->
</script>
</head>
EOF
 
function html_vonal () {
        echo "<div style=\"width: 100%; height: 20px; border-bottom: 1px solid black; text-align: center\"><span style=\"font-size: 30px; background-color: #F3F5F6; padding: 0 10px;\">$1</span></div>"
}
 
function szerverver {
        I=0
        for TSM_SZERVER in $TSM_SZERVEREK; do
                I=$((I+1))
                if [ $1 = $TSM_SZERVER ]; then echo $TSM_SZERVER_VER | cut -d" " -f $I; fi
        done
}
 
function level_fejlec {
    STARTTIME=`date "+%s"`
    >$TMP_FILE
    >$TMP_HTML_FILE
    echo "$HTML_TABLA_FEJLEC" >> $TMP_HTML_FILE
    echo '<div style="font-size: 48px; font-weight: bold;">' >> $TMP_HTML_FILE
    echo "TSM kliens riport" | tee -a $TMP_HTML_FILE >> $TMP_FILE
    echo '</div>' >> $TMP_HTML_FILE
    date | tee -a $TMP_HTML_FILE >> $TMP_FILE
    echo "<br>" >> $TMP_HTML_FILE
}
 
function fejlec {
        FEJLEC=`echo $1 | tr '[:lower:]' '[:upper:]'`
        echo "___:: $FEJLEC ::___" >> $TMP_FILE
        RAND_ID=`date '+%s%N'`
        echo "<div onClick=\"openClose('${RAND_ID}');Collapse(this)\" style=\"cursor:hand; cursor:pointer; color: #006DC7;\">___:: [-] $FEJLEC ::___</div>\n<div id=\"${RAND_ID}\" class=\"texter\" style=\"display: block\"><pre style=\"width: 960px; display: inline; margin: 0px 20px 0px 20px; text-align: left\">$HTML_VONAL" >> $TMP_HTML_FILE
}
 
control_c()
# run if user hits control-c
{
        echo -en "\n*** Ouch! Ertem a celzast, maris takaritok... ***\n"
        rm $TMP_FILE 2>/dev/null
        rm $TMP_HTML_FILE 2>/dev/null
        exit 1
}
 
# trap keyboard interrupt (control-c)
trap control_c SIGINT
 
# Hasznlat sztanzak ellenorzese
fejlec "Vizsgalando TSM sztanza konfigok mukodesenek ellenorzese"
for TSM_SZERVER in $TSM_SZERVEREK; do
        VER=$((`dsmadmc -id=$TSM_FELH -pa=$TSM_JELSZO -se=$TSM_SZERVER q opt | sed -n -e 's/Server Version \([0-9]\),.*/\1/p' -e 's/[\t\s]*//g'`))
        LONG_VER=$(dsmadmc -id=$TSM_FELH -pa=$TSM_JELSZO -se=$TSM_SZERVER q opt | sed -n -e  's/Server Version \([0-9]\), Release \([0-9]\), Level \([0-9]\)\.\([0-9]\).*/\1.\2.\3.\4/p' | sed -e 's/^[^0-9]*//g')
        LONG_VER=$(dsmadmc -id=$TSM_FELH -pa=$TSM_JELSZO -se=$TSM_SZERVER q opt | sed -n -e  's/Server Version \([0-9]\), Release \([0-9]\), Level \([0-9]\+\)\.\([0-9]\+\).*/\1.\2.\3.\4/p' | sed -e 's/^[^0-9]*//g')
        TSM_SZERVERNEV[$TSM_SZERVER]=$(dsmadmc -id=$TSM_FELH -pa=$TSM_JELSZO -se=$TSM_SZERVER q opt | sed -n -e 's/Session established with server \([^:]*\):.*/\1/p')
        if [ "$VER" != "0" ]; then
                OK="OK! (v${LONG_VER} - ${TSM_SZERVERNEV[$TSM_SZERVER]})"
                TSM_SZERVERNEVEK_TMP="$TSM_SZERVERNEVEK_TMP ${TSM_SZERVERNEV[$TSM_SZERVER]}"
                TSM_SZERVEREK_TMP="$TSM_SZERVEREK_TMP $TSM_SZERVER"
                TSM_SZERVER_VER="$TSM_SZERVER_VER $VER"
        else
                OK="Sikertelen! A szerver kihagyasra kerul a riportbol."
        fi
        echo "${TSM_SZERVER}: $OK" | awk -F'|' '{printf "> @%-35s %-12s\n",$1,$2}' | tee -a $TMP_HTML_FILE | tee -a $TMP_FILE
done
# Program torzs
if [ `echo $TSM_SZERVEREK | grep -c '[a-zA-Z]'` -eq 0 ]; then
        echo "$(date) Nincs hasznalhato sztanza a konfigomban." >> "$(dirname $0)/tsm_kliens_riport.err"
    rm $TMP_FILE 2>/dev/null
    rm $TMP_HTML_FILE 2>/dev/null
    exit 1
fi
 
# Vegigmegyunk az osszes konfig fajlon, ami a TSM_SZERVEREK valtozoban fel van sorolva
for TSM_SZERVER in $TSM_SZERVEREK; do
    KONFIG_FILE="$(dirname $0)/tsm_kliens_riport.$TSM_SZERVER"
    # Minden riport cimzettet felolvasunk az aktualis konfig fajlbol
    awk -F';' '/^[^#]/{print $1}' "$KONFIG_FILE" | sort -u | while read MAILTO; do
        level_fejlec;
        fejlec "${TSM_SZERVER}"
        html_vonal "Sikertelen utemezesek" >> $TMP_HTML_FILE
        echo "NODE NAME                 SCHEDULE NAME                        ACTUAL START             RUNTIME     RESULT" | tee -a $TMP_HTML_FILE >> $TMP_FILE
        echo "---------------------     --------------------------------     --------------------     --------    --------------"| tee -a $TMP_HTML_FILE >> $TMP_FILE
        # Minden adott email cimhez tartozo SQL feltetelt feldolgozunk, először csak a nem sikereseket, aztán alá a teljes listát is
        awk -F';' "/^[^#]*$MAILTO/"'{print $2}' $KONFIG_FILE | sort -u | while read SQL_FELTETEL; do
            FSIZE=$(ls -l $TMP_FILE | awk '{print $5}')
            if [[ "$SQL_FELTETEL" = "" ]]; then continue; fi
            dsmadmc -id=$TSM_FELH -pa=$TSM_JELSZO -se=${TSM_SZERVER} -dataonly=y -displ=tabl "$SQL_Q_FAILED_EVENTS AND $SQL_FELTETEL" | egrep -v '(ANS|ANR)' | egrep '(Failed|Missed|Severed|Started)' | tee -a $TMP_HTML_FILE >> $TMP_FILE
#            FSIZE2=$(ls -l $TMP_FILE | awk '{print $5}')
        done
        html_vonal "<br>Elmult 3 napban sorozatosan Missed utemezesek" >> $TMP_HTML_FILE
        echo "NODE NAME                 SCHEDULE                       CONTACT                   3 DAY COUNT         LAST SEEN" | tee -a $TMP_HTML_FILE >> $TMP_FILE
        echo "---------------------     --------------------------     ---------------------     ------------     ------------" | tee -a $TMP_HTML_FILE >> $TMP_FILE
        # Minden adott email cimhez tartozo SQL feltetelt feldolgozunk, először csak a nem sikereseket, aztán alá a teljes listát is
        awk -F';' "/^[^#]*$MAILTO/"'{print $2}' $KONFIG_FILE | sort -u | while read SQL_FELTETEL; do
            FSIZE=$(ls -l $TMP_FILE | awk '{print $5}')
            if [[ "$SQL_FELTETEL" = "" ]]; then continue; fi
            SQL_3X_MISSED="select substr(e.node_name,1,20) as \"NODE NAME\", substr(e.schedule_name,1,25) as SCHEDULE, substr(n.contact,1,20) as \"CONTACT\", substr(char(count(*)),1,4) as \"3 DAY COUNT\",(days(current_timestamp)-days(n.lastacc_time)) as \"LAST SEEN\" from EVENTS e, nodes n where (e.scheduled_start >=current_timestamp - 3 days) and e.node_name=n.node_name and e.status='Missed' and e.node_name is not NULL and e.schedule_name not like 'RMAN_%%_LOG%%' and e.schedule_name not like 'SQL_%%_LOG%%' and $(echo ${SQL_FELTETEL} | sed 's/order by [^ ]*//gi') group by e.node_name, e.schedule_name, n.contact, n.lastacc_time having count(*)>=3 " #order by \"3 DAY COUNT\" desc"
            dsmadmc -id=$TSM_FELH -pa=$TSM_JELSZO -se=${TSM_SZERVER} -dataonly=y -displ=tabl "$SQL_3X_MISSED" | egrep -v '(ANS|ANR)' | tee -a $TMP_HTML_FILE >> $TMP_FILE
#            FSIZE2=$(ls -l $TMP_FILE | awk '{print $5}')
        done
        html_vonal "<br>Minden utemezes" >> $TMP_HTML_FILE
        echo "NODE NAME                 SCHEDULE NAME                        ACTUAL START             RUNTIME     RESULT" | tee -a $TMP_HTML_FILE >> $TMP_FILE
        echo "---------------------     --------------------------------     --------------------     --------    --------------"| tee -a $TMP_HTML_FILE >> $TMP_FILE
        awk -F';' "/^[^#]*$MAILTO/"'{print $2}' $KONFIG_FILE | sort -u | while read SQL_FELTETEL; do
#            FSIZE=$(ls -l $TMP_FILE | awk '{print $5}')
            if [[ "$SQL_FELTETEL" = "" ]]; then continue; fi
            dsmadmc -id=$TSM_FELH -pa=$TSM_JELSZO -se=${TSM_SZERVER} -dataonly=y -displ=tabl "$SQL_Q_FAILED_EVENTS AND $SQL_FELTETEL" | egrep -v '(ANS|ANR)' | tee -a $TMP_HTML_FILE >> $TMP_FILE
            FSIZE2=$(ls -l $TMP_FILE | awk '{print $5}')
            if [[ $FSIZE -ne $FSIZE2 ]]; then echo "$HTML_VONAL" >> $TMP_HTML_FILE; fi
        done
        ENDTIME=`date "+%s"`
        echo "$HTML_TABLA_LABLEC" >> $TMP_HTML_FILE
        echo "<p style=\"font-size:smaller;\">[A riport $((($ENDTIME-$STARTTIME)/60)) perc $((($ENDTIME-$STARTTIME)%60)) mp alatt keszult el - TSM riporter $SCRIPT_VER]" | tee -a $TMP_HTML_FILE >> $TMP_FILE
        # Riport kuldese
        DATUM=`date +"%F_%H-%M"`
        mkdir -p $LOG_DIR >/dev/null
        if [ $? -eq 0 ]; then
            cp $TMP_FILE $LOG_DIR/tsm_kliens_riport_${DATUM}_${MAILTO}.log
            echo "<br><br>[A riport szoveges valtozata az alabbi utvonalon helyben is le lett tarolva:<br> "`hostname`":$LOG_DIR/tsm_kliens_riport_${DATUM}_${MAILTO}.log]</p>" >> $TMP_HTML_FILE
            ERR=$?
        fi
        if [[ $ERR -ne 0 || ! $ERR ]]; then
            echo "HIBA: A riportot nem sikerult a $LOG_DIR mappaba menteni!" >>$TMP_HTML_FILE
        fi
        echo "$HTML_MODUL_LABLEC" >> $TMP_HTML_FILE
        # Levelkuldes
        sed -i -e 's/^|//' -e 's/|$//' $TMP_HTML_FILE
        sed -i 's/^.*4-Skipped Files.*$/<font color="#B0A100">&<\/font>/' $TMP_HTML_FILE # TSM sztanza szinzes
        sed -i 's/^.*8-Warnings.*$/<font color="#B0A100">&<\/font>/' $TMP_HTML_FILE # TSM sztanza szinzes
        sed -i 's/^.*12-Errors.*$/<font color="#D70109">&<\/font>/' $TMP_HTML_FILE # TSM sztanza szinzes
        sed -i 's/^.*-Failed.*$/<font color="#D70109">&<\/font>/' $TMP_HTML_FILE # TSM sztanza szinzes
        sed -i 's/^.*-Missed.*$/<font color="#D70109">&<\/font>/' $TMP_HTML_FILE # TSM sztanza szinzes
        sed -i 's/^.*-Started.*$/<font color="#FF6600">&<\/font>/' $TMP_HTML_FILE # TSM sztanza szinzes
        sed -i -e "s/___*[^_]*___*/<div style=\"text-align: center; font-family: Verdana; font-weight:bold; font-size: 12px; color: #006DC7; margin-top: 10px; padding: 0px;\">&<\/div>/" -e 's/___//g' $TMP_HTML_FILE # Szekcio fejlec szinezes
 
        echo -e "<html>${JS_CODE}<body><center><div style=\"font-size: 14px; font-family: courier;\">\n$(cat ${TMP_HTML_FILE})</div></td></tr></body></html>" > $TMP_HTML_FILE
        if [ `echo "$MAILTO" | grep "@.*\."` ]; then
        if [[ `which sendmail` && $HTML_EMAIL -eq 1 ]]; then
            echo -e "To: $MAILTO\nMIME-Version: 1.0\nContent-Type: text/html\nContent-Disposition: inline\nSubject: TSM kliens riport ($TSM_SZERVER)\n$(cat ${TMP_HTML_FILE})" > $TMP_HTML_FILE
            cat $TMP_HTML_FILE | sendmail -B 8BITMIME -t -F "TSM riporter"
        elif [[ ! $HTML_EMAIL -eq 1 && $HTML_EMAIL_CSAT -eq 1 ]]; then
            echo -e "To: $MAILTO\nSubject: TSM kliens riport ($TSM_SZERVER)\n$(cat $TMP_FILE)" > $TMP_FILE
            cp $TMP_HTML_FILE /tmp/tsm_kliens_riport_${DATUM}.html
            cat $TMP_FILE | mailx -a /tmp/tsm_kliens_riport_${DATUM}.html -t
        else
            echo -e "To: $MAILTO\nSubject: TSM kliens riport ($TSM_SZERVER)\n$(cat $TMP_FILE)" > $TMP_FILE
            cat $TMP_FILE | mailx -t
        fi
    fi
    done
done
# Regi logok torlese
zip -9rv ${LOG_DIR}/$(date +%Y%m)_archived_backup_logs.zip "${LOG_DIR}/tsm_kliens_riport_${DATUM}_${MAILTO}.log"
find ${LOG_DIR}/tsm_kliens_riport_*.log -type f -mtime +60 -exec rm {} \;
rm -f "$TMP_FILE" "$TMP_HTML_FILE" "/tmp/tsm_kliens_riport_${DATUM}.html"