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  }