Flyctl meets JSON

We’ve just shipped a new version of Flyctl and although there’s only one new flag added, it’s a flag that can change the way you use flyctl forever.

Say hello to --json or -j for short. This new flag attempts to present all output from flyctl as JSON. If a command queries the Fly GraphQL API, you’ll get the JSON data from that call in your output. If a command shows you logs, you’ll get the logs as structured JSON. When you are deploying, nearly all (we’ll talk about that nearly later) the output of the command comes in the form of JSON formatted messages.

You may wonder what this can do for you. Well, we hope it’ll let you create your own automation solutions for your workflow with Fly.

Getting the JSON out

Let’s start with an example:

$ flyctl list apps --json

[
    {
        "ID": "Z0zYDgDjg2V3mul",
        "Name": "apienterprise",
        "Status": "running",
        "Deployed": true,
        "Hostname": "apienterprise.fly.dev",
        "Organization": "dj"
    },
    {
        "ID": "GqXY09mQ7Rwyauq4",
        "Name": "red-paper-8243",
        "Status": "running",
        "Deployed": true,
        "Hostname": "red-paper-8243.fly.dev",
        "Organization": "dj"
    },
...

With JSON output enabled, the list apps command returns a JSON array of objects with the id, name, status, deployment, hostname and organization of each Fly application you have access to.

Any application which accepts JSON can work with this data. If you’re scripting, you’ll most likely want to process, filter and reorganize the JSON data. For that we recommend jq. With jq you get a tool that can slice and dice JSON files into the data you want.

For example, say you just wanted a list of hostnames and status to feed into your management platform, and your management platform only accepted CSV files.

$ flyctl list apps --json | jq -r '.[] | [ .Hostname,.Status ] | @csv'
"apienterprise.fly.dev","running"
"red-paper-8243.fly.dev","running"
...

Get in the jq

We aren’t going to go into jq in depth today. It’s a tool that is rich with features. Working through the jq tutorial and browsing the jq manual will get you started using jq to filter JSON content. Most useful is the jq playground where you can experiment with jq queries.

As an aside, the question with web tools like jq playground is how do you get command line data into it. Well, on the mac, you can pipe output to pbcopy which takes output and puts it on the clipboard. On Linux, you can use xsel --clipboard --input to do the same. Then it’s just a matter of pasting your data into the appropriate web form. Therefore:

$ flyctl list apps --json | pbcopy

Will load up your clipboard with a list of all your apps that you can paste into the JSON text box in jq playground. Enter something like .[] | select(.Status=="running") and watch only the apps with running status appear in the Result box. You are now in a great place to start experimenting.

Making it happen

Finally, let’s have an example which runs commands. In this example we want to find all the apps which may not have deployed for whatever reason. For each one, we want all the application’s info, as per the flyctl info command. In fact thats what we actually run - flyctl info and then we’ll turn all that data into a JSON array for some unspecified app to process:

flyctl list apps --json | jq -c ".[] | select(.Deployed==false) | .Name" | xargs -n 1 fly info --json -a | jq -s "."

Let’s work this through, command by command:

flyctl list apps --json

This lists out, as we already know, all the apps available in JSON format. That JSON gets fed to:

jq -c ".[] | select(.Deployed==false) | .Name"

Take the array and work through it element by element (.[]) copying it all through the pipe. Then for everything that matches the select criteria (.Deployed==false) copy it through the pipe to the final stage. .Name simply says to jq, write out the Name property. So this makes a list of names we can run flyctl info on. For that we turn to the buzz saw of Unix, xargs:

xargs -n 1 flyctl info --json -a 

This command takes each line from the input (in this case, app names) and for each one runs flyctl info --json -a with the input argument appended. This will generate a stream of JSON info objects but, for this example, we want them gathered up in an array. We can turn to jq again:

jq -s "."

This uses the jq “slurp” option - yes, it really is called that - to slurp up all the input which is passed through untouched with the “.” query, but wrapped in an array. That’s ready to feed into another application (in this case, a database, but thats another story).

Deploy watching

Deployment, unlike other commands, doesn’t produce a single JSON object. As an ongoing process, it’ll produce a stream of JSON “Source/Status/Message” objects reflecting the progress of the deployment. Currently, there’s also a stream on non-JSON messages mixed with the JSON stream, so although you can, we don’t recommend following the JSON output to monitor deployments. Instead, run the flyctl deploy command with --detach and then poll flyctl status for the application’s deployment status or run flyctl monitor to track deployments on an application.

Wrapping Up

The new Flyctl --json support should make automating Fly a breeze and we can’t wait to hear what you are building with it.

Want to learn more about Fly? Head over to our Fly Docs for lots more, including a Hands On where you can get a free account and deploy your first app today.