Silly Terminal Plotting with jc, jq, and jp

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!

Published by kellyjonbrazil

I'm a cybersecurity and cloud computing nerd.

Leave a Reply

RSS
Follow by Email
LinkedIn
LinkedIn
Share
%d bloggers like this: