ELK Interaction

We’re System Administrators and we want to interrogate our local ELK ElasticSearch ElasticStack instance.

Idio doesn’t have any immediate HTTP capabilities so we’ll use curl.

This example will use non-TLS connections.

We’re going to use using the JSON output so remember to put import json5 at the top of the script (or type it in at the console).

Elastic Basic Security

A little digression. Later releases of v7 have encouraged even the free tier to use authentication to connect. That’s good but we don’t want to use a http://user:pass@host:9200/path format because we can’t guarantee that curl can successfully prevent other users from seeing user and pass.

curl does support the use of both --netrc and, more usefully, --netrc-file for which we can make use of Process Substitution.

Our command line will therefore include:

curl --netrc --netrc-file (named-pipe-from print-netrc) ...

where the function print-netrc can be set up along the lines of:

ELK-HOST := "elk1.example.com"
ELK-USER := "elk-username"
ELK-PASS := "elk-password"

define* (print-netrc (:host host ELK-HOST)
                     (:user user ELK-USER)
                     (:pass pass ELK-PASS)) {
  printf #S{
machine ${host}
login ${user}
password ${pass}
  }
}

which gives us a bit of wiggle-room to alter the host, user and pass by passing optional parameters (see define*).

Calling curl

We can create a similar function for parameterising the call the curl:

define* (CURL
         (res "")
         (:method method "GET")
         (:host host ELK-HOST)
         (:user user ELK-USER)
         (:pass pass ELK-PASS)) {

  (collect-output curl
                  -sX method
                  --netrc
                  --netrc-file (named-pipe-from print-netrc
                                                :host host
                                                :user user
                                                :pass pass)
                  #S{http://${ELK-HOST}:9200/${res}})

}

ELK APIs

Looking at some simple APIs, we can check we successfully talk to ELK at all by invoking CURL with no res option:

printf "%s\n" (CURL)

to get something like:

{
  "name" : "elk2.example.com",
  ...
  "version" : {
    "number" : "7.15.1",
    ...
  },
  "tagline" : "You Know, for Search"
}

_cat/nodes

The cat nodes API can give us some JSON output:

;; nodes is an array
nodes := parse-string (CURL "_cat/nodes?format=json")

parse-string, here, is json5/parse-string from the import json5 line you added.

nodes is an array of as many objects as you have ElasticSearch nodes in your cluster.

For interest, we can get the member names of the first object:

hash-keys (array-ref nodes 0)

which will result in a list, something like:

("ip" "master" "load_15m" "load_5m" "heap.percent" "cpu" "node.role" "name" "load_1m" "ram.percent")

based on which, we should be able to iterate over the array printing out the name, IP address and cpu usage:

for-each (function (n) {
            printf "%-30s %15s %s\n" n."name" n."ip" n."cpu"
}) nodes

to get:

elk1.example.com                 192.0.2.101  8
elk2.example.com                 192.0.2.102  17

Last built at 2026-01-04T22:40:02Z+0000 from da47fd3 (dev)