How to quickly read summary data in k6 from json file
Tags: performance, testing, tutorial, webdev
Published: 2023-12-04 18:49:41


Jq is a lightweight and flexible command-line JSON processor. This means that it allows us to filter, map and edit json data from the command line.

## Installing

First, we need to install jq via the installer available at `https://stedolan.github.io/jq/`.

## Purpose

When running k6 tests through the command:

```
k6 run --out json=results.json script.js
```

A report in json format is generated. As the tests run, results are generated that we can only read from inside the file. There are thousands of them, which makes them difficult to read. In our tests, we use the rule that a tag is set for each request. An example request could look like the following.

```
const statusData = http.get("https://k6.io", { 
    tags: { myTag: "staticStatusContent" } 
});
```

With the above tagged, we will be able to distinguish the results in the .json file based on the tag set. There is ample room for automation here, as we can also filter the results based on the group to which the requests belong. We, however, will focus on the tags themselves for now.

Let’s move on to the commands we will use. Let’s add that in each of the examples we care about getting the times of the requests. In case we want to get other data, we will use, for example, http_req_connecting or http_req_failed. For more on the metrics we can use, see <https://k6.io/docs/using-k6/metrics/>.

## Checking all the tags used

```
jq '. | select(.type=="Point" and .metric == "http_req_duration" and .data.tags.myTag) | .data.tags.myTag' FILE_NAME
```

## Checking the times of requests with the indicated tag

```
jq '. | select(.type=="Point" and .metric == "http_req_duration" and .data.tags.myTag == "TAG_NAME") | .data.value' FILE_NAME 
```

The result is returned in milliseconds.

## The average time of requests with the given tag

```
jq '. | select(.type=="Point" and .metric == "http_req_duration" and .data.tags.myTag == "TAG_NAME") | .data.value' FILE_NAME  | jq -s 'add/length'
```

## Minimum request time with the given tag

```
jq '. | select(.type=="Point" and .metric == "http_req_duration" and .data.tags.myTag == "TAG_NAME") | .data.value' FILE_NAME  | jq -s min
```

## Maximum request time with the given tag

```
jq '. | select(.type=="Point" and .metric == "http_req_duration" and .data.tags.myTag == "TAG_NAME") | .data.value' FILE_NAME  | jq -s max
```

All of the above data can be automated. We use a bash script for this, the code for which is below.

```
#!/bin/bash

 
echo -e "Usage: \`$ bash getMetrics.sh resultsFile.json\`"
echo -e "Checking the results in the $1 file\n"
fileName=$1

# results checking all http_req_duration tags
tagsInFile=`jq '. | select(.type=="Point" and .metric == "http_req_duration" and .data.tags.myTag) | .data.tags.myTag' $fileName`

# clearing tags of quotation marks
clearedTags="${tagsInFile//\"}"
 
# create an array based on the newline character
IFS=$'\n' tags=($clearedTags) 
for tag in "${tags[@]}"; do
 
    # checking all data for each tag
    data="jq '. | select(.type==\"Point\" and .metric == \"http_req_duration\" and .data.tags.myTag == \"$tag\") | .data.value' $fileName"
   
    # specific data
    avg=$(eval "$data | jq -s 'add/length'";)
    min=$(eval "$data | jq -s min";)
    max=$(eval "$data | jq -s max";)

    # outputting data in the console
    echo "tag...: $tag"
    echo -e "data..: avg: ${avg}ms; min: ${min}ms; max: ${max}ms; avg: ${avg}ms;" "\n"
done
echo "Done!"
```

## Sample Usage

We run the created script (named getMetrics.sh) with the code above as follows.

```
$ bash getMetrics.sh resultsFile.json
```