Getting Started with the InfluxDB Ruby Client

Navigate to:

Let’s talk about the InfluxDB Ruby client. I love it for a lot of reasons, and mostly because it encapsulates what I love about Ruby: it abstracts away the pieces I don’t need to know and makes it easy to focus on my goal: getting (or writing) some time series data.

There’s also a client library specifically for Rails, but we’re going to focus on plain, delightful Ruby in this post.

Imagine me + you

It’s never a bad idea to revisit the basics, so we’re going to cover setting up and using the Ruby client, as well as a few notes about problems you might run into. Let’s go!

Setup

Install and start the TICK Stack in your development environment (local machine, container, server, etc.). Need directions for that? No problem.

Add the influxdb-ruby gem to your Gemfile. You could use gem install to install it globally, but that’s a personal decision. You do you.

gem 'influxdb'

Don’t forget to bundle!

Reading Data from InfluxDB (local host)

Okay, we’ve got the library. Let’s use it. The docs for influxdb-ruby are great; you can - and should - read them. We’re going to start by querying an existing database. This might seem a little backward, but with the TICK Stack running, we have an influxdb instance running as well: the ‘telegraf’ database, which captures metrics from the machine where it’s hosted.

In our first example, we’ll use a database that lives on our local machine.

database = "telegraf"
client = InfluxDB::Client.new(database: database, retry: 4)

Tada! The client takes an options hash, which take a variable number of key/value pairs. Database indicates which database we want to use. We could have multiple databases set up in our InfluxDB instance, so it’s important we tell the client which one we want. retry sets a limit for the number of times the client attempts to connect before it gives up. This is important because we don’t want to flood the database server with connection attempts when things go wrong.

We can't prepare for everything

There are two options missing from the example above: host and port. These are required, and the good news is that they have preset defaults. host defaults to localhost and port defaults to 8086, which match the defaults for local instances of influxdb. If that’s your use case, you don’t need to add anything else to start reading metrics.

response = client.query("select * from cpu limit 5")
print response

[output]
{"name"=>"cpu", "tags"=>nil, "values"=>[{"time"=>"2018-04-04T00:06:10Z", "cpu"=>"cpu-total", "host"=>"katys-MacBook-Pro.local", "usage_guest"=>0, "usage_guest_nice"=>0, "usage_idle"=>93.90395620801195, "usage_iowait"=>0, "usage_irq"=>0, "usage_nice"=>0, "usage_softirq"=>0, "usage_steal"=>0, "usage_system"=>2.139835780044787, "usage_user"=>3.9562080119432697},...}

We did it!

Reading Data from InfluxDB (external host)

Let’s look at an example where the database is hosted in the cloud and see the differences.

database = 'telegraf'
username = "beeper"
password = "booper"

client = InfluxDB::Client.new(database: database,
                              host: "blorper.influxcloud.net",
                              use_ssl: true,
                              username: username,
                              password: password,
                              retry: 4)

response = client.query("select * from cpu limit 5")

print response

[output]
{"name"=>"cpu", "tags"=>nil, "values"=>[{"time"=>"2018-04-04T00:06:10Z", "cpu"=>"cpu-total", "host"=>"katys-MacBook-Pro.local", "usage_guest"=>0, "usage_guest_nice"=>0, "usage_idle"=>93.90395620801195, "usage_iowait"=>0, "usage_irq"=>0, "usage_nice"=>0, "usage_softirq"=>0, "usage_steal"=>0, "usage_system"=>2.139835780044787, "usage_user"=>3.9562080119432697},...}

Notice that the output remains the same. The only things that change are the options that we pass to our client. We have to pass the host address now that we’ve moved to the wild Internet so that the client knows where to look to find the database named ‘telegraf’. We also have to pass use_ssl as true (default is false) because when we look at the url of the host in its entirety, it’s prefixed by https. However, when we set the value of the host, no prefix is required. We then pass in any login credentials for the server via username and password.

Once the connection is made, querying the database looks exactly the same as it did when running locally. The query strings are always InfluxQL, and although these examples are simple queries, we could run any valid InfluxQL query here, regardless of complexity.

Writing Data to InfluxDB

We’ve learned to read data with the Influxdb Ruby client. Now let’s learn to write. The basics are the same: we need to create a client that’s connected to an InfluxDB instance. While the configuration is different depending on where your instance lives (see the difference between a cloud instance and a local instance above), once the connection is established, the process for writing is the same regardless of where your database is hosted.

username       = 'beeper'
password       = 'booper'
database       = 'happytime'
name           = 'sogreat'
time_precision = 'ms'
time           = (Time.now.to_r * 1000).to_i

influxdb = InfluxDB::Client.new database,
  username: username,
  password: password,
  time_precision: time_precision

data = {
  values: { value: 9 },
  timestamp: time
}

influxdb.write_point(name, data)
response = influxdb.query("select * from sogreat")
puts response

[output]
{"name"=>"sogreat", "tags"=>nil, "values"=>[{"time"=>"2018-04-06T18:11:10.41Z", "value"=>9}, {"time"=>"2018-04-06T19:02:08.544Z", "value"=>9}]}

Some of this should look familiar. We’re creating a new client - only this time we have an additional option: time_precision. The Ruby client defaults to ‘s’ (seconds) for time precision, but I want milliseconds. We pass the time precision to the client, and then we need to adjust the way we capture the timestamp so that the timestamp mirrors the precision. If the time precision doesn’t match, the data point will be squashed.

In this example, name represents the name of the series we’re adding points to. For definitions on series and points, check these docs.

Summary

The Ruby client has great documentation, and I was able to find everything I needed there. There are more advanced features available, and best of all, it’s maintained by a pretty cool community.

I should also admit that I had a typo in my password for an embarrassingly long amount of time, resulting in me nearly collapsing like a dying star. It happens to everyone.

I am become death, the destroyer of passwords

Do you have more questions? Do you want to see specific examples? Let us know.

Find me on the internet:

[email protected]

@thekatertot