Influx-cli: a commandline interface to Influxdb.

Time for another side project: influx-cli, a commandline interface to influxdb.
Nothing groundbreaking, and it behaves pretty much as you would expect if you've ever used the mysql, pgsql, vsql, etc tools before.
But I did want to highlight a few interesting features.

You can do things like user management via SQL, even though influxdb doesn't have an SQL interface for this.
This is much easier than doing curl http requests!

influx> create admin test test
influx> list admin
## 0
                     name root
## 1
                     name test

You can change parameters and re-bind with the new values

influx> \user test
influx> \pass test
influx> \db graphite
influx> bind

Write your variables (user, pass, host, db, ...) to ~/.influxrc

influx> writerc

You can even do inserts via SQL, instead of http posts
I use this often. This is very useful to script test cases for bug reports etc.

influx> create db issue-1234
influx> \db issue-1234
influx> bind
influx> insert into demo (time, value, tag) values (120000, 10, "hi")
influx> insert into demo (time, value, tag) values (180000, 20, "hi again")
influx> select * from demo
## demo
                time sequence_number               value                 tag
       120000.000000      70001.000000                  10                "hi"
       180000.000000      80001.000000                  20          "hi again"
influx> delete db issue-1234

You can send queries on standard input, which is useful in shell commands and scripts.

$ echo 'list series' | influx-cli | wc -l
$ influx-cli <<< 'list series' | wc -l

But even better, from inside an influx-cli session, you can send output from any query into any other command.
In fact you can also write output of queries into external files. All this via familiar shell constructs

$ influx-cli
influx> list series | wc -l
influx> list series > list-series.txt
(note: the discrepancy of one line is due to the Go readline library echoing the query.

You can also toggle options, such as compression or display of timings.
This can be very useful to easily get insights of performance of different operations.

influx> \t
timing is now true
influx> select * from foo | wc -l
query+network: 1.288792048s
displaying   : 457.091811ms
influx> \comp
compression is now disabled
influx> select * from foo | wc -l
query+network: 969.322374ms
displaying   : 670.736018ms
influx> list series >/dev/null
query+network: 3.109178142s
displaying   : 65.712027ms

This has enabled me to pinpoint slow operations and provide evidence when when creating tickets.

Executing queries and debugging their result data format, works too
This is useful when you want to understand the api better or if the database gets support for new queries with a different output format that influx-cli doesn't understand yet.

influx> raw select * from foo limit 1
([]*client.Series) (len=1 cap=4) {
  Name: (string) (len=51) "foo",
  Columns: ([]string) (len=3 cap=4) {
   (string) (len=4) "time",
   (string) (len=15) "sequence_number",
   (string) (len=5) "value"
  Points: ([][]interface {}) (len=1 cap=4) {
   ([]interface {}) (len=3 cap=4) {
    (float64) 1.410148588e+12,
    (float64) 1,
    (float64) 95.549995

And that's about it. I've found this to be a much easier way to interface with InfluxDB then using the web interface and curl, but YMMV.
If you were wondering, this is of course built on top of the influxdb go client library, which was overall pretty pleasant to work with.
Some ideas for future work:

  • bulk insert performance could be better
  • once influxdb can report query execution time and hopefully also serialization time, the timing output can be more useful. Right now we can only measure query execution+serialization+network transfer time combined
  • my gut feeling says that using something like msgpack instead of json, and/or even streaming the resultset as it is being generated (instead of first building the entire result, then serializing it, then sending it over, then having the client deserialize the entire thing) could really help performance, not just here, but basically anywhere you interface with influxdb. Though I don't have hard numbers on this yet.