github.com/dmaizel/tests@v0.0.0-20210728163746-cae6a2d9cee8/metrics/lib/json.bash (about) 1 #!/bin/bash 2 # 3 # Copyright (c) 2018 Intel Corporation 4 # 5 # SPDX-License-Identifier: Apache-2.0 6 7 # Helper routines for generating JSON formatted results. 8 9 declare -a json_result_array 10 declare -a json_array_array 11 12 # Generate a timestamp in nanoseconds since 1st Jan 1970 13 timestamp_ns() { 14 local t 15 local s 16 local n 17 local ns 18 19 t="$(date +%-s:%-N)" 20 s=$(echo $t | awk -F ':' '{print $1}') 21 n=$(echo $t | awk -F ':' '{print $2}') 22 ns=$(( (s * 1000000000) + n )) 23 24 echo $ns 25 } 26 27 # Generate a timestamp in milliseconds since 1st Jan 1970 28 timestamp_ms() { 29 echo $(($(date +%s%N)/1000000)) 30 } 31 32 # Intialise the json subsystem 33 metrics_json_init() { 34 35 36 # Clear out any previous results 37 json_result_array=() 38 39 despaced_name="$(echo ${TEST_NAME} | sed 's/[ \/]/-/g')" 40 json_filename="${RESULT_DIR}/${despaced_name}.json" 41 42 local json="$(cat << EOF 43 "@timestamp" : $(timestamp_ms) 44 EOF 45 )" 46 metrics_json_add_fragment "$json" 47 48 local json="$(cat << EOF 49 "env" : { 50 "RuntimeVersion": "$RUNTIME_VERSION", 51 "RuntimeCommit": "$RUNTIME_COMMIT", 52 "RuntimeConfig": "$RUNTIME_CONFIG_PATH", 53 "Hypervisor": "$HYPERVISOR_PATH", 54 "HypervisorVersion": "$HYPERVISOR_VERSION", 55 "Shim": "$SHIM_PATH", 56 "ShimVersion": "$SHIM_VERSION", 57 "machinename": "$(uname -n)" 58 } 59 EOF 60 )" 61 62 metrics_json_add_fragment "$json" 63 64 local json="$(cat << EOF 65 "date" : { 66 "ns": $(timestamp_ns), 67 "Date": "$(date -u +"%Y-%m-%dT%T.%3N")" 68 } 69 EOF 70 )" 71 metrics_json_add_fragment "$json" 72 73 local json="$(cat << EOF 74 "test" : { 75 "runtime": "${RUNTIME}", 76 "testname": "${TEST_NAME}" 77 } 78 EOF 79 )" 80 metrics_json_add_fragment "$json" 81 82 # Now add a runtime specific environment section if we can 83 local iskata=$(is_a_kata_runtime "$RUNTIME") 84 if [ "$iskata" == "1" ]; then 85 local rpath="$(command -v kata-runtime)" 86 local json="$(cat << EOF 87 "kata-env" : 88 $($rpath kata-env --json) 89 EOF 90 )" 91 metrics_json_add_fragment "$json" 92 else 93 if [ "$RUNTIME" == "runc" ]; then 94 local output=$(docker-runc -v) 95 local runcversion=$(grep version <<< "$output" | sed 's/runc version //') 96 local runccommit=$(grep commit <<< "$output" | sed 's/commit: //') 97 local json="$(cat << EOF 98 "runc-env" : 99 { 100 "Version": { 101 "Semver": "$runcversion", 102 "Commit": "$runccommit" 103 } 104 } 105 EOF 106 )" 107 metrics_json_add_fragment "$json" 108 else 109 warning "Unrecognised runtime ${RUNTIME} - no env extracted" 110 fi 111 fi 112 113 metrics_json_end_of_system 114 } 115 116 # Save out the final JSON file 117 metrics_json_save() { 118 119 if [ ! -d ${RESULT_DIR} ];then 120 mkdir -p ${RESULT_DIR} 121 fi 122 123 local maxelem=$(( ${#json_result_array[@]} - 1 )) 124 local json="$(cat << EOF 125 { 126 $(for index in $(seq 0 $maxelem); do 127 # After the standard system data, we then place all the test generated 128 # data into its own unique named subsection. 129 if (( index == system_index )); then 130 echo "\"${despaced_name}\" : {" 131 fi 132 if (( index != maxelem )); then 133 echo "${json_result_array[$index]}," 134 else 135 echo "${json_result_array[$index]}" 136 fi 137 done) 138 } 139 } 140 EOF 141 )" 142 143 echo "$json" > $json_filename 144 145 # If we have a JSON URL or host/socket pair set up, post the results there as well. 146 # Optionally compress into a single line. 147 if [[ $JSON_TX_ONELINE ]]; then 148 json="$(sed 's/[\n\t]//g' <<< ${json})" 149 fi 150 151 if [[ $JSON_HOST ]]; then 152 echo "socat'ing results to [$JSON_HOST:$JSON_SOCKET]" 153 socat -u - TCP:${JSON_HOST}:${JSON_SOCKET} <<< ${json} 154 fi 155 156 if [[ $JSON_URL ]]; then 157 echo "curl'ing results to [$JSON_URL]" 158 curl -XPOST -H"Content-Type: application/json" "$JSON_URL" -d "@-" <<< ${json} 159 fi 160 } 161 162 metrics_json_end_of_system() { 163 system_index=$(( ${#json_result_array[@]})) 164 } 165 166 # Add a top level (complete) JSON fragment to the data 167 metrics_json_add_fragment() { 168 local data=$1 169 170 # Place on end of array 171 json_result_array[${#json_result_array[@]}]="$data" 172 } 173 174 # Prepare to collect up array elements 175 metrics_json_start_array() { 176 json_array_array=() 177 } 178 179 # Add a (complete) element to the current array 180 metrics_json_add_array_element() { 181 local data=$1 182 183 # Place on end of array 184 json_array_array[${#json_array_array[@]}]="$data" 185 } 186 187 # Add a fragment to the current array element 188 metrics_json_add_array_fragment() { 189 local data=$1 190 191 # Place on end of array 192 json_array_fragments[${#json_array_fragments[@]}]="$data" 193 } 194 195 # Turn the currently registered array fragments into an array element 196 metrics_json_close_array_element() { 197 198 local maxelem=$(( ${#json_array_fragments[@]} - 1 )) 199 local json="$(cat << EOF 200 { 201 $(for index in $(seq 0 $maxelem); do 202 if (( index != maxelem )); then 203 echo "${json_array_fragments[$index]}," 204 else 205 echo "${json_array_fragments[$index]}" 206 fi 207 done) 208 } 209 EOF 210 )" 211 212 # And save that to the top level 213 metrics_json_add_array_element "$json" 214 215 # Reset the array fragment array ready for a new one 216 json_array_fragments=() 217 } 218 219 # Close the current array 220 metrics_json_end_array() { 221 local name=$1 222 223 local maxelem=$(( ${#json_array_array[@]} - 1 )) 224 local json="$(cat << EOF 225 "$name": [ 226 $(for index in $(seq 0 $maxelem); do 227 if (( index != maxelem )); then 228 echo "${json_array_array[$index]}," 229 else 230 echo "${json_array_array[$index]}" 231 fi 232 done) 233 ] 234 EOF 235 )" 236 237 # And save that to the top level 238 metrics_json_add_fragment "$json" 239 }