brintos

brintos / linux-shallow public Read only

0
0
Text · 4.7 KiB · 873a892 Raw
269 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.0-only3 4# Sergey Senozhatsky, 20155# sergey.senozhatsky.work@gmail.com6#7 8 9# This program is intended to plot a `slabinfo -X' stats, collected,10# for example, using the following command:11#   while [ 1 ]; do slabinfo -X >> stats; sleep 1; done12#13# Use `slabinfo-gnuplot.sh stats' to pre-process collected records14# and generate graphs (totals, slabs sorted by size, slabs sorted15# by size).16#17# Graphs can be [individually] regenerate with different ranges and18# size (-r %d,%d and -s %d,%d options).19#20# To visually compare N `totals' graphs, do21# slabinfo-gnuplot.sh -t FILE1-totals FILE2-totals ... FILEN-totals22#23 24min_slab_name_size=1125xmin=026xmax=027width=150028height=70029mode=preprocess30 31usage()32{33	echo "Usage: [-s W,H] [-r MIN,MAX] [-t|-l] FILE1 [FILE2 ..]"34	echo "FILEs must contain 'slabinfo -X' samples"35	echo "-t 			- plot totals for FILE(s)"36	echo "-l 			- plot slabs stats for FILE(s)"37	echo "-s %d,%d		- set image width and height"38	echo "-r %d,%d		- use data samples from a given range"39}40 41check_file_exist()42{43	if [ ! -f "$1" ]; then44		echo "File '$1' does not exist"45		exit 146	fi47}48 49do_slabs_plotting()50{51	local file=$152	local out_file53	local range="every ::$xmin"54	local xtic=""55	local xtic_rotate="norotate"56	local lines=200000057	local wc_lines58 59	check_file_exist "$file"60 61	out_file=`basename "$file"`62	if [ $xmax -ne 0 ]; then63		range="$range::$xmax"64		lines=$((xmax-xmin))65	fi66 67	wc_lines=`cat "$file" | wc -l`68	if [ $? -ne 0 ] || [ "$wc_lines" -eq 0 ] ; then69		wc_lines=$lines70	fi71 72	if [ "$wc_lines" -lt "$lines" ]; then73		lines=$wc_lines74	fi75 76	if [ $((width / lines)) -gt $min_slab_name_size ]; then77		xtic=":xtic(1)"78		xtic_rotate=9079	fi80 81gnuplot -p << EOF82#!/usr/bin/env gnuplot83 84set terminal png enhanced size $width,$height large85set output '$out_file.png'86set autoscale xy87set xlabel 'samples'88set ylabel 'bytes'89set style histogram columnstacked title textcolor lt -190set style fill solid 0.1591set xtics rotate $xtic_rotate92set key left above Left title reverse93 94plot "$file" $range u 2$xtic title 'SIZE' with boxes,\95	'' $range u 3 title 'LOSS' with boxes96EOF97 98	if [ $? -eq 0 ]; then99		echo "$out_file.png"100	fi101}102 103do_totals_plotting()104{105	local gnuplot_cmd=""106	local range="every ::$xmin"107	local file=""108 109	if [ $xmax -ne 0 ]; then110		range="$range::$xmax"111	fi112 113	for i in "${t_files[@]}"; do114		check_file_exist "$i"115 116		file="$file"`basename "$i"`117		gnuplot_cmd="$gnuplot_cmd '$i' $range using 1 title\118			'$i Memory usage' with lines,"119		gnuplot_cmd="$gnuplot_cmd '' $range using 2 title \120			'$i Loss' with lines,"121	done122 123gnuplot -p << EOF124#!/usr/bin/env gnuplot125 126set terminal png enhanced size $width,$height large127set autoscale xy128set output '$file.png'129set xlabel 'samples'130set ylabel 'bytes'131set key left above Left title reverse132 133plot $gnuplot_cmd134EOF135 136	if [ $? -eq 0 ]; then137		echo "$file.png"138	fi139}140 141do_preprocess()142{143	local out144	local lines145	local in=$1146 147	check_file_exist "$in"148 149	# use only 'TOP' slab (biggest memory usage or loss)150	let lines=3151	out=`basename "$in"`"-slabs-by-loss"152	`cat "$in" | grep -A "$lines" 'Slabs sorted by loss' |\153		grep -E -iv '\-\-|Name|Slabs'\154		| awk '{print $1" "$4+$2*$3" "$4}' > "$out"`155	if [ $? -eq 0 ]; then156		do_slabs_plotting "$out"157	fi158 159	let lines=3160	out=`basename "$in"`"-slabs-by-size"161	`cat "$in" | grep -A "$lines" 'Slabs sorted by size' |\162		grep -E -iv '\-\-|Name|Slabs'\163		| awk '{print $1" "$4" "$4-$2*$3}' > "$out"`164	if [ $? -eq 0 ]; then165		do_slabs_plotting "$out"166	fi167 168	out=`basename "$in"`"-totals"169	`cat "$in" | grep "Memory used" |\170		awk '{print $3" "$7}' > "$out"`171	if [ $? -eq 0 ]; then172		t_files[0]=$out173		do_totals_plotting174	fi175}176 177parse_opts()178{179	local opt180 181	while getopts "tlr::s::h" opt; do182		case $opt in183			t)184				mode=totals185				;;186			l)187				mode=slabs188				;;189			s)190				array=(${OPTARG//,/ })191				width=${array[0]}192				height=${array[1]}193				;;194			r)195				array=(${OPTARG//,/ })196				xmin=${array[0]}197				xmax=${array[1]}198				;;199			h)200				usage201				exit 0202				;;203			\?)204				echo "Invalid option: -$OPTARG" >&2205				exit 1206				;;207			:)208				echo "-$OPTARG requires an argument." >&2209				exit 1210				;;211		esac212	done213 214	return $OPTIND215}216 217parse_args()218{219	local idx=0220	local p221 222	for p in "$@"; do223		case $mode in224			preprocess)225				files[$idx]=$p226				idx=$idx+1227				;;228			totals)229				t_files[$idx]=$p230				idx=$idx+1231				;;232			slabs)233				files[$idx]=$p234				idx=$idx+1235				;;236		esac237	done238}239 240parse_opts "$@"241argstart=$?242parse_args "${@:$argstart}"243 244if [ ${#files[@]} -eq 0 ] && [ ${#t_files[@]} -eq 0 ]; then245	usage246	exit 1247fi248 249case $mode in250	preprocess)251		for i in "${files[@]}"; do252			do_preprocess "$i"253		done254		;;255	totals)256		do_totals_plotting257		;;258	slabs)259		for i in "${files[@]}"; do260			do_slabs_plotting "$i"261		done262		;;263	*)264		echo "Unknown mode $mode" >&2265		usage266		exit 1267	;;268esac269