buildstats-plot.sh 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #!/usr/bin/env bash
  2. #
  3. # Copyright (c) 2011, Intel Corporation.
  4. #
  5. # SPDX-License-Identifier: GPL-2.0-or-later
  6. #
  7. # DESCRIPTION
  8. #
  9. # Produces script data to be consumed by gnuplot. There are two possible plots
  10. # depending if either the -S parameter is present or not:
  11. #
  12. # * without -S: Produces a histogram listing top N recipes/tasks versus
  13. # stats. The first stat defined in the -s parameter is the one taken
  14. # into account for ranking
  15. # * -S: Produces a histogram listing tasks versus stats. In this case,
  16. # the value of each stat is the sum for that particular stat in all recipes found.
  17. # Stats values are in descending order defined by the first stat defined on -s
  18. #
  19. # EXAMPLES
  20. #
  21. # 1. Top recipes' tasks taking into account utime
  22. #
  23. # $ buildstats-plot.sh -s utime | gnuplot -p
  24. #
  25. # 2. Tasks versus utime:stime
  26. #
  27. # $ buildstats-plot.sh -s utime:stime -S | gnuplot -p
  28. #
  29. # 3. Tasks versus IO write_bytes:IO read_bytes
  30. #
  31. # $ buildstats-plot.sh -s 'IO write_bytes:IO read_bytes' -S | gnuplot -p
  32. #
  33. # AUTHORS
  34. # Leonardo Sandoval <leonardo.sandoval.gonzalez@linux.intel.com>
  35. #
  36. set -o nounset
  37. set -o errexit
  38. BS_DIR="tmp/buildstats"
  39. N=10
  40. RECIPE=""
  41. TASKS="compile:configure:fetch:install:patch:populate_lic:populate_sysroot:unpack"
  42. STATS="utime"
  43. ACCUMULATE=""
  44. SUM=""
  45. OUTDATA_FILE="$PWD/buildstats-plot.out"
  46. function usage {
  47. CMD=$(basename $0)
  48. cat <<EOM
  49. Usage: $CMD [-b buildstats_dir] [-t do_task]
  50. -b buildstats The path where the folder resides
  51. (default: "$BS_DIR")
  52. -n N Top N recipes to display. Ignored if -S is present
  53. (default: "$N")
  54. -r recipe The recipe mask to be searched
  55. -t tasks The tasks to be computed
  56. (default: "$TASKS")
  57. -s stats The stats to be matched. If more that one stat, units
  58. should be the same because data is plot as histogram.
  59. (see buildstats.sh -h for all options) or any other defined
  60. (build)stat separated by colons, i.e. stime:utime
  61. (default: "$STATS")
  62. -a Accumulate all stats values for found recipes
  63. -S Sum values for a particular stat for found recipes
  64. -o Output data file.
  65. (default: "$OUTDATA_FILE")
  66. -h Display this help message
  67. EOM
  68. }
  69. # Parse and validate arguments
  70. while getopts "b:n:r:t:s:o:aSh" OPT; do
  71. case $OPT in
  72. b)
  73. BS_DIR="$OPTARG"
  74. ;;
  75. n)
  76. N="$OPTARG"
  77. ;;
  78. r)
  79. RECIPE="-r $OPTARG"
  80. ;;
  81. t)
  82. TASKS="$OPTARG"
  83. ;;
  84. s)
  85. STATS="$OPTARG"
  86. ;;
  87. a)
  88. ACCUMULATE="-a"
  89. ;;
  90. S)
  91. SUM="y"
  92. ;;
  93. o)
  94. OUTDATA_FILE="$OPTARG"
  95. ;;
  96. h)
  97. usage
  98. exit 0
  99. ;;
  100. *)
  101. usage
  102. exit 1
  103. ;;
  104. esac
  105. done
  106. # Get number of stats
  107. IFS=':'; statsarray=(${STATS}); unset IFS
  108. nstats=${#statsarray[@]}
  109. # Get script folder, use to run buildstats.sh
  110. CD=$(dirname $0)
  111. # Parse buildstats recipes to produce a single table
  112. OUTBUILDSTATS="$PWD/buildstats.log"
  113. $CD/buildstats.sh -b "$BS_DIR" -s "$STATS" -t "$TASKS" $RECIPE $ACCUMULATE -H > $OUTBUILDSTATS
  114. # Get headers
  115. HEADERS=$(cat $OUTBUILDSTATS | sed -n -e 's/\(.*\)/"\1"/' -e '1s/ /\\\\\\\\ /g' -e 's/_/\\\\\\\\_/g' -e '1s/:/" "/gp')
  116. echo -e "set boxwidth 0.9 relative"
  117. echo -e "set style data histograms"
  118. echo -e "set style fill solid 1.0 border lt -1"
  119. echo -e "set xtics rotate by 45 right"
  120. # Get output data
  121. if [ -z "$SUM" ]; then
  122. cat $OUTBUILDSTATS | sed -e '1d' -e 's/_/\\\\_/g' | sort -k3 -n -r | head -$N > $OUTDATA_FILE
  123. # include task at recipe column
  124. sed -i -e "1i\
  125. ${HEADERS}" $OUTDATA_FILE
  126. echo -e "set title \"Top task/recipes\""
  127. echo -e "plot for [COL=3:`expr 3 + ${nstats} - 1`] '${OUTDATA_FILE}' using COL:xtic(stringcolumn(1).' '.stringcolumn(2)) title columnheader(COL)"
  128. else
  129. # Construct datatamash sum argument (sum 3 sum 4 ...)
  130. declare -a sumargs
  131. j=0
  132. for i in `seq $nstats`; do
  133. sumargs[j]=sum; j=$(( $j + 1 ))
  134. sumargs[j]=`expr 3 + $i - 1`; j=$(( $j + 1 ))
  135. done
  136. # Do the processing with datamash
  137. cat $OUTBUILDSTATS | sed -e '1d' | datamash -t ' ' -g1 ${sumargs[*]} | sort -k2 -n -r > $OUTDATA_FILE
  138. # Include headers into resulted file, so we can include gnuplot xtics
  139. HEADERS=$(echo $HEADERS | sed -e 's/recipe//1')
  140. sed -i -e "1i\
  141. ${HEADERS}" $OUTDATA_FILE
  142. # Plot
  143. echo -e "set title \"Sum stats values per task for all recipes\""
  144. echo -e "plot for [COL=2:`expr 2 + ${nstats} - 1`] '${OUTDATA_FILE}' using COL:xtic(1) title columnheader(COL)"
  145. fi