Browse code

Provide timings for OSC during devstack run

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

Sean Dague authored on 2017/03/28 04:35:13
Showing 2 changed files
... ...
@@ -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