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  }