#!/usr/bin/ksh
#
# $Id: nmon2WLE,v 1.1 2023/03/27 19:56:31 root Exp root $
#
#& nmon2WLE formatting script.
#& Assumes AIX nmon files and ignores more then 150 disks
#
MODE=$1 	# possible values are average,  max and 95 (meaning 95th percentile)
ORIGINAL=$2	# input file
INPUT=/tmp/nmon2WLE.input.$$
INFO=/tmp/nmon2WLE.info.$$
DEBUG=0  	# 0=off  1=some  99=lots of output

if [[ "$MODE" == "-h" ]]
then
echo  nmon2WLE formatting script for nmon files to IBM Workload Estimator format.
echo
echo  Testing Limit: Assumes AIX nmon files  - Linux may work at your own risk
echo  Limitation: only includes stats from the first 150 disks
echo
echo  Version 12, Nigel Griffiths, code example i.e. Copyright is impossibe.
echo
echo  "Usage nmon2WLE {-h | -c}"
echo  "-h = this help info"
echo  "-c = output the 16 WLE column names - useful to check the output"
echo
echo  "Usage nmon2WLE {average | max | 95} filename.nmon"
echo  "o average - Average of the stats - Good if you captured a busy period (hour)"
echo  "o max - Maximum peak stats - Good if captured whole day with idle periods"
echo  "o 95 - Calculate 95th percentile - Like max but ignores top 5% peaks"
echo
echo IBM Workload Estimator Colunm names are:
echo Name, Quantity, ConsolidateTo, System, ActiveCores, CPUutilization, MemoryMB, DiskReadsPerSecond, BytesPerReadOp, DiskWritesPerSecond, BytesPerWriteOp, StorageGB, NetworkMBPerSecond, NetworkOpsPerSecond, OverheadPercent, ConcurrencyPercent
exit
fi

if [[ "$MODE" == "-c" ]]
then
echo "'Name', 'Quantity', 'ConsolidateTo', 'System', 'ActiveCores', 'CPUutilization', 'MemoryMB', 'DiskReadsPerSecond', 'BytesPerReadOp', 'DiskWritesPerSecond', 'BytesPerWriteOp', 'StorageGB', 'NetworkMBPerSecond', 'NetworkOpsPerSecond', 'OverheadPercent', 'ConcurrencyPercent'"
exit
fi

if [[ "$MODE" != "average" && "$MODE" != "max" && "$MODE" != "95" && "$MODE" != "-h" ]]
then
echo Error
echo Option: $MODE not valid it should be average or max or 95 
echo Use: nmon2WLM -h for help information
echo
exit
fi

sed -e 's/
//' -e 's/,,$//' -e 's/,$//' -e 's/,,/,0,/g' -e 's/-0.0/0.0/g' -e 's/-1.0/0.0/g' <$ORIGINAL >$INPUT
grep ^AAA $INPUT >$INFO

grep "AAA,AIX,5.3" <$INFO >/dev/null
if [[ $? == 0 ]]
then
echo nmon2WLE ERROR: AIX 5.3 is not supported file=$ORIGINAL
exit
fi

grep "AAA,OS,Linux" <$INFO >/dev/null
if [[ $? == 0 ]]
then
echo nmon2WLE ERROR: Linux nmon data is not supported file=$ORIGINAL
exit
fi

grep "AAA,progname,topas_nmon" <$INFO >/dev/null
if [[ $? == 1 ]]
then
echo "nmon2WLE ERROR: nmon classic (only topas_nmon) data is not supported file=$ORIGINAL"
exit
fi

grep "^DISKRIO,D" <$INPUT >/dev/null
if [[ $? == 1 ]]
then
echo "nmon2WLE ERROR: No DISKRIO records possible old nmon version is not supported file=$ORIGINAL"
exit
fi

# This is used in all 95 Percentile calculations so do it once
if [[ $MODE == "95" ]]
then
	integer RECORDS
	integer PERCENTILE
	RECORDS=`grep ^CPU_ALL,T $INPUT | wc -l`
	PERCENTILE=$RECORDS-$RECORDS/20
fi


if (( "$DEBUG" == 1 ))
then 
echo "1=Name, 2=Quantity, 3=ConsolidateTo, 4=System"
fi

# Name is hostnames plus data
grep "AAA,host,"  $INFO | awk -F, '{ printf "%s-", $3 }'
grep "AAA,date,"  $INFO | awk -F, '{ printf "%s, ", $3 }'
# Quantity=1 and ConsolidateTo=0 - these are fields for users to change later
print "1, 0, \c"
# Serial Number we can find in the nmon file
grep "AAA,SerialNumber,"  $INFO | awk -F, '{ printf "%s, ", $3 }'
#cleanup
rm $INFO

#    _        _   _            ____
#   / \   ___| |_(_)_   _____ / ___|___  _ __ ___  ___
#  / _ \ / __| __| \ \ / / _ \ |   / _ \| '__/ _ \/ __|
# / ___ \ (__| |_| |\ V /  __/ |__| (_) | | |  __/\__ \
#/_/   \_\___|\__|_| \_/ \___|\____\___/|_|  \___||___/

if (( $DEBUG == 1 ))
then 
echo
echo "5=ActiveCores"
fi

grep ",lparstat -i," $INPUT | sed 's/ //g' | sed 's/\"//g' >$INFO
CAPPED=$(grep Mode $INFO | grep -v Memory | grep -v Saving | awk -F: '{printf "%s", $2}')

if (( "$DEBUG" > 9 ))
then
printf "CPU Mode is %s  Note:If Uncapped then ActiveCores=VirtualCPUs If Capped then ActiveCores=Entitlement\n", $CAPPED
fi
if [[ "$CAPPED" == "Capped" ]]
then
grep "EntitledCapacity"  $INFO | grep -v "Pool"   | awk -F: '{printf "%s,", $2}'
else
grep "OnlineVirtualCPUs" $INFO |                    awk -F: '{printf "%s,", $2}'
fi
# remove the temporary file
#clean up
rm  $INFO

#  ____ ____  _   _
# / ___|  _ \| | | |
#| |   | |_) | | | |
#| |___|  __/| |_| |
# \____|_|    \___/

if (( $DEBUG == 1 ))
then 
echo
echo "6=CPUutilization"
fi

if [[ $MODE == "average" ]]
then
	grep ^CPU_ALL,T $INPUT | awk -F"," 'BEGIN { COUNT=0.0; LINES=0; } {LINES+=1; COUNT+=($3+$4); } END {printf "%6.1f, ", COUNT/LINES}'
fi

if [[ $MODE == "max" ]]
then
	grep ^CPU_ALL,T $INPUT | awk -F"," 'BEGIN { MAX=0; } { if( MAX < ($3+$4)) MAX=$3+$4; } END {printf "%6.1f, ", MAX}'
fi

if [[ $MODE == "95" ]]
then
	grep ^CPU_ALL,T $INPUT | awk -F"," '{ printf "%6.1f,\n", $3+$4 }' | sort -nr | tail -$PERCENTILE | read result 
	echo  " " $result "\c"
fi

# ____      _    __  __
#|  _ \    / \  |  \/  |
#| |_) |  / _ \ | |\/| |
#|  _ <  / ___ \| |  | |
#|_| \_\/_/   \_\_|  |_|
if (( $DEBUG == 1 ))
then 
echo
echo "7=MemoryMB,"
fi

grep ",online Memory," $INPUT | awk -F, '{ printf "%s, ", $4 }'

# ____  _     _
#|  _ \(_)___| | _____
#| | | | / __| |/ / __|
#| |_| | \__ \   <\__ \
#|____/|_|___/_|\_\___/

if (( "$DEBUG" == 1 ))
then
echo
echo 8=DiskReadsPerSecond, 9=BytesPerReadOp, 10=DiskWritesPerSecond, 11=BytesPerWriteOp, 
fi

grep "^DISK" $INPUT >$INFO
READS=$(grep ^DISKRIO,T $INFO | awk -F"," 'BEGIN { COUNT=0.0; LINES=0 } {LINES+=1; for(i=3; i<=NF; i++){COUNT+=$i } } END {printf "%.1f\n", COUNT/LINES}' )
READKB=$(grep ^DISKREAD,T $INFO | awk -F"," 'BEGIN { COUNT=0.0; LINES=0 } {LINES+=1; for(i=3; i<=NF; i++){COUNT+=$i } } END {printf "%.1f\n", COUNT/LINES}' )

WRITES=$(grep ^DISKWIO,T $INFO | awk -F"," 'BEGIN { COUNT=0.0; LINES=0; } {LINES+=1; for(i=3; i<=NF; i++){COUNT+=$i } } END {printf "%.1f", COUNT/LINES}' )
WRITEKB=$(grep ^DISKWRITE,T $INFO | awk -F"," 'BEGIN { COUNT=0.0; LINES=0; } {LINES+=1; for(i=3; i<=NF; i++){COUNT+=$i } } END {printf "%.1f", COUNT/LINES}' )

if [[ $MODE == "max" ]]
then
READSMAX=$(grep ^DISKRIO,T $INFO | awk -F"," 'BEGIN { COUNT=0.0; LINES=0 } {LINES+=1; for(i=3; i<=NF; i++){if(COUNT < $i) COUNT=$i ; } } END {printf "%.1f\n", COUNT}' )
WRITESMAX=$(grep ^DISKWIO,T $INFO | awk -F"," 'BEGIN { COUNT=0.0 } {LINES+=1; for(i=3; i<=NF; i++){if(COUNT < $i) COUNT=$i ; } } END {printf "%.1f", COUNT}' )
fi
if [[ $MODE == "95" ]]
then
	grep ^DISKRIO,T $INFO | awk -F"," ' BEGIN{XXXX=0.0;} {for(i=3; i<=NF; i++){ XXXX+=$i; } ; printf "%6.1f\n", XXXX ; XXXX=0 }'| sort -nr | tail -$PERCENTILE | read READ95 
	grep ^DISKWIO,T $INFO | awk -F"," ' BEGIN{XXXX=0.0;} {for(i=3; i<=NF; i++){ XXXX+=$i; } ; printf "%6.1f\n", XXXX ; XXXX=0 }'| sort -nr | tail -$PERCENTILE | read WRITE95 
fi

integer READSIZE
integer WRITESIZE
if(( $READS > 0 ))
then
READSIZE=$READKB/$READS*1024
else
READSIZE=0
fi

integer WRITESIZE
if(( $WRITES > 0 ))
then
WRITESIZE=$WRITEKB/$WRITES*1024
else
WRITESIZE=0
fi

if [[ $MODE == "average" ]]
then
printf "$READS, $READSIZE, $WRITES, $WRITESIZE, "
fi

if [[ $MODE == "max" ]]
then
printf "$READSMAX, $READSIZE, $WRITESMAX, $WRITESIZE, "
fi

if [[ $MODE == "95" ]]
then
printf "$READ95, $READSIZE, $WRITE95, $WRITESIZE, "
fi

#clean up
rm $INFO

# ____  _
#/ ___|| |_ ___  _ __ __ _  __ _  ___
#\___ \| __/ _ \| '__/ _` |/ _` |/ _ \
# ___) | || (_) | | | (_| | (_| |  __/
#|____/ \__\___/|_|  \__,_|\__, |\___|
#                          |___/
if (( "$DEBUG" == 1 ))
then
echo
echo 12=StorageGB
fi

grep ^BBBV $INPUT | grep "TOTAL PPs:" | sed 's/(/,/' | sed 's/ megabytes/,/' | awk -F"," 'BEGIN { COUNT=0.0 } {COUNT+=$4;} END {printf " %.1f, ", COUNT/1024}' 

# _   _      _                      _
#| \ | | ___| |___      _____  _ __| | __
#|  \| |/ _ \ __\ \ /\ / / _ \| '__| |/ /
#| |\  |  __/ |_ \ V  V / (_) | |  |   <
#|_| \_|\___|\__| \_/\_/ \___/|_|  |_|\_\
if (( "$DEBUG" == 1 ))
then
echo
echo 13=NetworkMBPerSecond, 14=NetworkOpsPerSecond
fi

if [[ $MODE == "average" ]]
then
grep ^NET,T $INPUT | awk -F"," 'BEGIN { COUNT=0.0; LINES=0; MAX=0.0; } {LINES+=1; for(i=3; i<=NF; i++){COUNT+=$i; if(MAX < $i) MAX=$i; } } END {printf "%6.1f, ", COUNT/LINES}'
grep ^NETPACKET,T $INPUT | awk -F"," 'BEGIN { COUNT=0.0; LINES=0; MAX=0.0; } {LINES+=1; for(i=3; i<=NF; i++){COUNT+=$i; if(MAX < $i) MAX=$i; } } END {printf "%6.1f, ", COUNT/LINES}'
fi

if [[ $MODE == "max" ]]
then
grep ^NET,T $INPUT | awk -F"," 'BEGIN { COUNT=0.0; LINES=0; MAX=0.0; } {LINES+=1; for(i=3; i<=NF; i++){COUNT+=$i; if(MAX < $i) MAX=$i; } } END {printf "%6.1f, ", MAX}'
grep ^NETPACKET,T $INPUT | awk -F"," 'BEGIN { COUNT=0.0; LINES=0; MAX=0.0; } {LINES+=1; for(i=3; i<=NF; i++){COUNT+=$i; if(MAX < $i) MAX=$i; } } END {printf "%6.1f, ", MAX}'
fi

if [[ $MODE == "95" ]]
then
	grep ^NET,T $INPUT | awk -F"," ' BEGIN{XXXX=0.0;} {for(i=3; i<=NF; i++){ XXXX+=$i; } ; printf "%6.1f\n", XXXX ; XXXX=0 }'| sort -nr | tail -$PERCENTILE | read NET95
#	echo  " " $NET95 "\c"
	grep ^NETPACKET,T $INPUT | awk -F"," ' BEGIN{XXXX=0.0;} {for(i=3; i<=NF; i++){ XXXX+=$i; } ; printf "%6.1f\n", XXXX ; XXXX=0 }'| sort -nr | tail -$PERCENTILE | read PACK95 
#	echo  " " $PACK95 "\c"
	print $NET95, $PACK95, "\c"
fi

#  ___  _   _
# / _ \| |_| |__   ___ _ __ ___
#| | | | __| '_ \ / _ \ '__/ __|
#| |_| | |_| | | |  __/ |  \__ \
# \___/ \__|_| |_|\___|_|  |___/
# place holders
if (( "$DEBUG" == 1 ))
then
echo
echo 15=OverheadPercent, 16=ConcurrencyPercent
fi

print "0, 100"
# the end
