The OSC number remain high, and it's useful to understand how much
time we spend making OSC calls, especially to surface it relative to
other items. The way we embed this in our code makes it hard to
instrument.
This patch creates a wrapper function for OSC which collects the timings
then aliases `openstack` to that function. This means any invocations of
the openstack utility goes through our function while devstack is
running. Because this is an alias it only affects the stack.sh shell and
any subshells.
This also moves the time tracking infrastructure to count in ms,
instead of s, because some of these operations are close enough to a
second that rounding early is losing way to many significant
digits. We divide by 1000 before reporting to the user.
Change-Id: Ic5f1844ce732d447ee980b3c9fdc417f72482609
... | ... |
@@ -2459,7 +2459,7 @@ function time_start { |
2459 | 2459 |
if [[ -n "$start_time" ]]; then |
2460 | 2460 |
die $LINENO "Trying to start the clock on $name, but it's already been started" |
2461 | 2461 |
fi |
2462 |
- _TIME_START[$name]=$(date +%s) |
|
2462 |
+ _TIME_START[$name]=$(date +%s%3N) |
|
2463 | 2463 |
} |
2464 | 2464 |
|
2465 | 2465 |
# time_stop $name |
... | ... |
@@ -2480,7 +2480,7 @@ function time_stop { |
2480 | 2480 |
if [[ -z "$start_time" ]]; then |
2481 | 2481 |
die $LINENO "Trying to stop the clock on $name, but it was never started" |
2482 | 2482 |
fi |
2483 |
- end_time=$(date +%s) |
|
2483 |
+ end_time=$(date +%s%3N) |
|
2484 | 2484 |
elapsed_time=$(($end_time - $start_time)) |
2485 | 2485 |
total=${_TIME_TOTAL[$name]:-0} |
2486 | 2486 |
# reset the clock so we can start it in the future |
... | ... |
@@ -2488,6 +2488,49 @@ function time_stop { |
2488 | 2488 |
_TIME_TOTAL[$name]=$(($total + $elapsed_time)) |
2489 | 2489 |
} |
2490 | 2490 |
|
2491 |
+function oscwrap { |
|
2492 |
+ local out |
|
2493 |
+ local rc |
|
2494 |
+ local start |
|
2495 |
+ local end |
|
2496 |
+ # Cannot use timer_start and timer_stop as we run in subshells |
|
2497 |
+ # and those rely on modifying vars in the same process (which cannot |
|
2498 |
+ # happen from a subshell. |
|
2499 |
+ start=$(date +%s%3N) |
|
2500 |
+ out=$(command openstack "$@") |
|
2501 |
+ rc=$? |
|
2502 |
+ end=$(date +%s%3N) |
|
2503 |
+ echo $((end - start)) >> $OSCWRAP_TIMER_FILE |
|
2504 |
+ |
|
2505 |
+ echo "$out" |
|
2506 |
+ return $rc |
|
2507 |
+} |
|
2508 |
+ |
|
2509 |
+function install_oscwrap { |
|
2510 |
+ # File to accumulate our timing data |
|
2511 |
+ OSCWRAP_TIMER_FILE=$(mktemp) |
|
2512 |
+ # Bash by default doesn't expand aliases, allow it for the aliases |
|
2513 |
+ # we want to whitelist. |
|
2514 |
+ shopt -s expand_aliases |
|
2515 |
+ # Remove all aliases that might be expanded to preserve old unexpanded |
|
2516 |
+ # behavior |
|
2517 |
+ unalias -a |
|
2518 |
+ # Add only the alias we want for openstack |
|
2519 |
+ alias openstack=oscwrap |
|
2520 |
+} |
|
2521 |
+ |
|
2522 |
+function cleanup_oscwrap { |
|
2523 |
+ local total=0 |
|
2524 |
+ if python3_enabled ; then |
|
2525 |
+ local python=python3 |
|
2526 |
+ else |
|
2527 |
+ local python=python |
|
2528 |
+ fi |
|
2529 |
+ total=$(cat $OSCWRAP_TIMER_FILE | $python -c "import sys; print(sum(int(l) for l in sys.stdin))") |
|
2530 |
+ _TIME_TOTAL["osc"]=$total |
|
2531 |
+ rm $OSCWRAP_TIMER_FILE |
|
2532 |
+} |
|
2533 |
+ |
|
2491 | 2534 |
# time_totals |
2492 | 2535 |
# Print out total time summary |
2493 | 2536 |
function time_totals { |
... | ... |
@@ -2506,6 +2549,8 @@ function time_totals { |
2506 | 2506 |
fi |
2507 | 2507 |
done |
2508 | 2508 |
|
2509 |
+ cleanup_oscwrap |
|
2510 |
+ |
|
2509 | 2511 |
xtrace=$(set +o | grep xtrace) |
2510 | 2512 |
set +o xtrace |
2511 | 2513 |
|
... | ... |
@@ -2517,6 +2562,8 @@ function time_totals { |
2517 | 2517 |
echo |
2518 | 2518 |
for t in ${!_TIME_TOTAL[*]}; do |
2519 | 2519 |
local v=${_TIME_TOTAL[$t]} |
2520 |
+ # because we're recording in milliseconds |
|
2521 |
+ v=$(($v / 1000)) |
|
2520 | 2522 |
printf "%-${len}s %3d\n" "$t" "$v" |
2521 | 2523 |
done |
2522 | 2524 |
echo "=========================" |
... | ... |
@@ -493,6 +493,11 @@ function exit_trap { |
493 | 493 |
kill 2>&1 $jobs |
494 | 494 |
fi |
495 | 495 |
|
496 |
+ #Remove timing data file |
|
497 |
+ if [ -f "$OSCWRAP_TIMER_FILE" ] ; then |
|
498 |
+ rm "$OSCWRAP_TIMER_FILE" |
|
499 |
+ fi |
|
500 |
+ |
|
496 | 501 |
# Kill the last spinner process |
497 | 502 |
kill_spinner |
498 | 503 |
|
... | ... |
@@ -903,6 +908,10 @@ else |
903 | 903 |
pip_install_gr python-openstackclient |
904 | 904 |
fi |
905 | 905 |
|
906 |
+# Installs alias for osc so that we can collect timing for all |
|
907 |
+# osc commands. Alias dies with stack.sh. |
|
908 |
+install_oscwrap |
|
909 |
+ |
|
906 | 910 |
if [[ $TRACK_DEPENDS = True ]]; then |
907 | 911 |
$DEST/.venv/bin/pip freeze > $DEST/requires-post-pip |
908 | 912 |
if ! diff -Nru $DEST/requires-pre-pip $DEST/requires-post-pip > $DEST/requires.diff; then |