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