I ran across a cool little utility called jp
that takes JSON input and plots bar, line, histogram, and scatterplot graphs right in the terminal. I’m always looking for ways to hone my jq
skills so I found some time to play around with it.
I figured it would be fun to plot some system stats like CPU and Memory utilization in the terminal, so I started with some simple plots piping jc
, and jp
together. For example, here’s a bar graph of the output of df
:
df | jc --df | jp -type bar -canvas full-escape -x ..filesystem -y ..used

Not super useful, but we’re just having fun here! How about graphing the relative sizes of files in a directory using ls
?
ls -l Documents/lab\ license/ | jc --ls | jp -type bar -canvas full-escape -x ..filename -y ..size

Not bad! Let’s get a little fancier by filtering results through jq
. We’ll plot the output of ps
to see the CPU utilization of processes with more than .5% CPU utilization:
ps axu | jc --ps | jq '[.[] | select (.cpu_percent > 0.5)]' | jp -type bar -canvas full-escape -x ..pid -y ..cpu_percent

That’s a nice static bar chart of the most active PIDs on the system. But we can do better. Let’s make the graph dynamic by enclosing the above in a while true
loop:
while true; do ps axu | jc --ps | jq '[.[] | select (.cpu_percent > 0.5)]' | jp -type bar -canvas full-escape -x ..pid -y ..cpu_percent; sleep 3; done

Fancy! Of course we could have plotted mem_percent
instead to plot memory utilization by PID. By the way, I made the animated GIF above using ttyrec
and ttygif
.
Ok, one last dynamic graph. This time, let’s track system load over time using the output of uptime
. To pull this off we’ll need to keep a history of load values over time, so we’ll move from a one-liner to a small bash script:
#!/bin/bash rm /tmp/load.json SECONDS=0 while true; do uptime | jc --uptime | jq --arg sec "$SECONDS" '{"seconds": $sec | tonumber, "load": .load_1m}' >> /tmp/load.json cat /tmp/load.json | jq -s . | jp -canvas full-escape -x ..seconds -y ..load sleep 2 done

Fun! We got to do a couple of neat things with jq
here.
We pulled in the uptime
output converted to JSON with jc
and rebuilt the JSON to use only the load_1m
value and the SECONDS
environment variable. We used tonumber
to convert the SECONDS
variable into a number that could be plotted by jp
. We redirect the output to a temporary text file called /tmp/load.json
so jp
can read it later and build out the line graph.
I know, I know – I’m piping cat
output into jq
but I just wanted to make the script readable. The interesting thing here is that we are using the -s
or “slurp” option of jq
, which essentially reformats the JSON lines output in /tmp/load.json
into a proper JSON array so jp
can consume it.
By the way, the graphs animate a little nicer in real life since you don’t get the artificial delay between frames you see in the animated GIF.
I thought that was pretty fun and I got to try a couple different things in jq
I haven’t tried before. Happy JSON plotting!
Intriguing, but jp gives me this error: “Incorrect Usage. flag provided but not defined: -type”
Yes, it is a bit confusing – the
jp
that I am referring to in this post is not the jmespathjp
command, which I think you may be using.