The official Ruby client library for InfluxDB. Maintained by @toddboom and @dmke.
- Platform support
- Ruby support
- Installation
- Usage
- Advanced Topics
- List of configuration options
- Testing
- Contributing
Support for InfluxDB v0.8.x is now deprecated. The final version of this library that will support the older InfluxDB interface is
v0.1.9
, which is available as a gem and tagged on this repository.If you're reading this message, then you should only expect support for InfluxDB v0.9.1 and higher.
Since v0.4.0, this gem requires Ruby >= 2.2.0. Support for MRI < 2.2 is still available in the v0.3.x series, see stable-03 branch for documentation.
$ [sudo] gem install influxdb
Or add it to your Gemfile
, and run bundle install
.
All examples assume you have a require "influxdb"
in your code.
Connecting to a single host:
influxdb = InfluxDB::Client.new # default connects to localhost:8086
# or
influxdb = InfluxDB::Client.new host: "influxdb.domain.com"
Connecting to multiple hosts (with built-in load balancing and failover):
influxdb = InfluxDB::Client.new hosts: ["influxdb1.domain.com", "influxdb2.domain.com"]
You can also provide a URL to connect to your server. This is particulary useful for 12-factor apps, i.e. you can put the configuration in an environment variable:
url = ENV["INFLUXDB_URL"] || "https://influxdb.example.com:8086/database_name?retry=3"
influxdb = InfluxDB::Client.new url: url
Please note, that the config options found in the URL have a lower precedence than those explicitly given in the options hash. This means, that the following sample will use an open-timeout of 10 seconds:
url = "https://influxdb.example.com:8086/database_name?open_timeout=3"
influxdb = InfluxDB::Client.new url: url, open_timeout: 10
Write some data:
username = 'foo'
password = 'bar'
database = 'site_development'
name = 'foobar'
influxdb = InfluxDB::Client.new database, username: username, password: password
# Enumerator that emits a sine wave
Value = (0..360).to_a.map {|i| Math.send(:sin, i / 10.0) * 10 }.each
loop do
data = {
values: { value: Value.next },
tags: { wave: 'sine' } # tags are optional
}
influxdb.write_point(name, data)
sleep 1
end
Write data with time precision (precision can be set in 2 ways):
username = 'foo'
password = 'bar'
database = 'site_development'
name = 'foobar'
time_precision = 's'
# either in the client initialization:
influxdb = InfluxDB::Client.new database,
username: username,
password: password,
time_precision: time_precision
data = {
values: { value: 0 },
timestamp: Time.now.to_i # timestamp is optional, if not provided point will be saved with current time
}
influxdb.write_point(name, data)
# or in a method call:
influxdb.write_point(name, data, time_precision)
The default precision (in this Rubygem) is
"s"
(second), as Ruby'sTime#to_i
operates on this resolution.If you write data points with sub-second resolution (for example via
Time#to_r
), you need to configure your client instance with an appropiatetime_precision
option and you'll need to provide a timestamp value which reflects this precision:influxdb = InfluxDB::Client.new time_precision: "ms" time = (Time.now.to_r * 10**6).to_i influxdb.write_point("foobar", { values: { n: 42 }, timestamp: time })
Allowed values for time_precision
are:
"ns"
ornil
for nanosecond"u"
for microsecond"ms"
for millisecond"s"
for second"m"
for minute"h"
for hour
Write data with a specific retention policy:
database = 'site_development'
name = 'foobar'
precision = 's'
retention = '1h.cpu'
influxdb = InfluxDB::Client.new database,
username: "foo",
password: "bar"
data = {
values: { value: 0 },
tags: { foo: 'bar', bar: 'baz' },
timestamp: Time.now.to_i
}
influxdb.write_point(name, data, precision, retention)
Write data while choosing the database:
database = 'site_development'
name = 'foobar'
precision = 's'
retention = '1h.cpu'
influxdb = InfluxDB::Client.new {
username: "foo",
password: "bar"
}
data = {
values: { value: 0 },
tags: { foo: 'bar', bar: 'baz' }
timestamp: Time.now.to_i
}
influxdb.write_point(name, data, precision, retention, database)
Write multiple points in a batch (performance boost):
data = [
{
series: 'cpu',
tags: { host: 'server_1', region: 'us' },
values: { internal: 5, external: 0.453345 }
},
{
series: 'gpu',
values: { value: 0.9999 },
}
]
influxdb.write_points(data)
# you can also specify precision in method call
precision = 'm'
influxdb.write_points(data, precision)
Write multiple points in a batch with a specific retention policy:
data = [
{
series: 'cpu',
tags: { host: 'server_1', region: 'us' },
values: { internal: 5, external: 0.453345 }
},
{
series: 'gpu',
values: { value: 0.9999 },
}
]
precision = 'm'
retention = '1h.cpu'
influxdb.write_points(data, precision, retention)
Write asynchronously (note that a retention policy cannot be specified for asynchronous writes):
database = 'site_development'
name = 'foobar'
influxdb = InfluxDB::Client.new database,
username: "foo",
password: "bar",
async: true
data = {
values: { value: 0 },
tags: { foo: 'bar', bar: 'baz' },
timestamp: Time.now.to_i
}
influxdb.write_point(name, data)
Using async: true
is a shortcut for the following:
async_options = {
# number of points to write to the server at once
max_post_points: 1000,
# queue capacity
max_queue_size: 10_000,
# number of threads
num_worker_threads: 3,
# max. time (in seconds) a thread sleeps before
# checking if there are new jobs in the queue
sleep_interval: 5
}
influxdb = InfluxDB::Client.new database, async: async_options
Write data via UDP (note that a retention policy cannot be specified for UDP writes):
influxdb = InfluxDB::Client.new udp: { host: "127.0.0.1", port: 4444 }
name = 'hitchhiker'
data = {
values: { value: 666 },
tags: { foo: 'bar', bar: 'baz' }
}
influxdb.write_point(name, data)
Discard write errors:
influxdb = InfluxDB::Client.new(
udp: { host: "127.0.0.1", port: 4444 },
discard_write_errors: true
)
influxdb.write_point('hitchhiker', { values: { value: 666 } })
database = 'site_development'
influxdb = InfluxDB::Client.new database,
username: "foo",
password: "bar"
# without a block:
influxdb.query 'select * from time_series_1 group by region'
# results are grouped by name, but also their tags:
#
# [
# {
# "name"=>"time_series_1",
# "tags"=>{"region"=>"uk"},
# "values"=>[
# {"time"=>"2015-07-09T09:03:31Z", "count"=>32, "value"=>0.9673},
# {"time"=>"2015-07-09T09:03:49Z", "count"=>122, "value"=>0.4444}
# ]
# },
# {
# "name"=>"time_series_1",
# "tags"=>{"region"=>"us"},
# "values"=>[
# {"time"=>"2015-07-09T09:02:54Z", "count"=>55, "value"=>0.4343}
# ]
# }
# ]
# with a block:
influxdb.query 'select * from time_series_1 group by region' do |name, tags, points|
printf "%s [ %p ]\n", name, tags
points.each do |pt|
printf " -> %p\n", pt
end
end
# result:
# time_series_1 [ {"region"=>"uk"} ]
# -> {"time"=>"2015-07-09T09:03:31Z", "count"=>32, "value"=>0.9673}
# -> {"time"=>"2015-07-09T09:03:49Z", "count"=>122, "value"=>0.4444}]
# time_series_1 [ {"region"=>"us"} ]
# -> {"time"=>"2015-07-09T09:02:54Z", "count"=>55, "value"=>0.4343}
If you would rather receive points with integer timestamp, it's possible to set
epoch
parameter:
# globally, on client initialization:
influxdb = InfluxDB::Client.new database, epoch: 's'
influxdb.query 'select * from time_series group by region'
# [
# {
# "name"=>"time_series",
# "tags"=>{"region"=>"uk"},
# "values"=>[
# {"time"=>1438411376, "count"=>32, "value"=>0.9673}
# ]
# }
# ]
# or for a specific query call:
influxdb.query 'select * from time_series group by region', epoch: 'ms'
# [
# {
# "name"=>"time_series",
# "tags"=>{"region"=>"uk"},
# "values"=>[
# {"time"=>1438411376000, "count"=>32, "value"=>0.9673}
# ]
# }
# ]
Working with parameterized query strings works as expected:
influxdb = InfluxDB::Client.new database
named_parameter_query = "select * from time_series_0 where time > %{min_time}"
influxdb.query named_parameter_query, params: { min_time: 0 }
# compiles to:
# select * from time_series_0 where time > 0
positional_params_query = "select * from time_series_0 where f = %{1} and i < %{2}"
influxdb.query positional_params_query, params: ["foobar", 42]
# compiles to (note the automatic escaping):
# select * from time_series_0 where f = 'foobar' and i < 42
Create a database:
database = 'site_development'
influxdb.create_database(database)
Delete a database:
database = 'site_development'
influxdb.delete_database(database)
List databases:
influxdb.list_databases
Create a user for a database:
database = 'site_development'
new_username = 'foo'
new_password = 'bar'
permission = :write
# with all permissions
influxdb.create_database_user(database, new_username, new_password)
# with specified permission - options are: :read, :write, :all
influxdb.create_database_user(database, new_username, new_password, permissions: permission)
Update a user password:
username = 'foo'
new_password = 'bar'
influxdb.update_user_password(username, new_password)
Grant user privileges on database:
username = 'foobar'
database = 'foo'
permission = :read # options are :read, :write, :all
influxdb.grant_user_privileges(username, database, permission)
Revoke user privileges from database:
username = 'foobar'
database = 'foo'
permission = :write # options are :read, :write, :all
influxdb.revoke_user_privileges(username, database, permission)
Delete a user:
username = 'foobar'
influxdb.delete_user(username)
List users:
influxdb.list_users
Create cluster admin:
username = 'foobar'
password = 'pwd'
influxdb.create_cluster_admin(username, password)
List cluster admins:
influxdb.list_cluster_admins
Revoke cluster admin privileges from user:
username = 'foobar'
influxdb.revoke_cluster_admin_privileges(username)
List continuous queries of a database:
database = 'foo'
influxdb.list_continuous_queries(database)
Create a continuous query for a database:
database = 'foo'
name = 'clicks_count'
query = 'SELECT COUNT(name) INTO clicksCount_1h FROM clicks GROUP BY time(1h)'
influxdb.create_continuous_query(name, database, query)
Additionally, you can specify the resample interval and the time range over which the CQ runs:
influxdb.create_continuous_query(name, database, query, resample_every: "10m", resample_for: "65m")
Delete a continuous query from a database:
database = 'foo'
name = 'clicks_count'
influxdb.delete_continuous_query(name, database)
List retention policies of a database:
database = 'foo'
influxdb.list_retention_policies(database)
Create a retention policy for a database:
database = 'foo'
name = '1h.cpu'
duration = '10m'
replication = 2
influxdb.create_retention_policy(name, database, duration, replication)
Delete a retention policy from a database:
database = 'foo'
name = '1h.cpu'
influxdb.delete_retention_policy(name, database)
Alter a retention policy for a database:
database = 'foo'
name = '1h.cpu'
duration = '10m'
replication = 2
influxdb.alter_retention_policy(name, database, duration, replication)
By default, InfluxDB::Client will denormalize points (received from InfluxDB as
columns and rows). If you want to get raw data add denormalize: false
to
the initialization options or to query itself:
influxdb.query 'select * from time_series_1 group by region', denormalize: false
# [
# {
# "name"=>"time_series_1",
# "tags"=>{"region"=>"uk"},
# "columns"=>["time", "count", "value"],
# "values"=>[
# ["2015-07-09T09:03:31Z", 32, 0.9673],
# ["2015-07-09T09:03:49Z", 122, 0.4444]
# ]
# },
# {
# "name"=>"time_series_1",
# "tags"=>{"region"=>"us"},
# "columns"=>["time", "count", "value"],
# "values"=>[
# ["2015-07-09T09:02:54Z", 55, 0.4343]
# ]
# }
# ]
influxdb.query 'select * from time_series_1 group by region', denormalize: false do |name, tags, points|
printf "%s [ %p ]\n", name, tags
points.each do |key, values|
printf " %p -> %p\n", key, values
end
end
# time_series_1 [ {"region"=>"uk"} ]
# columns -> ["time", "count", "value"]
# values -> [["2015-07-09T09:03:31Z", 32, 0.9673], ["2015-07-09T09:03:49Z", 122, 0.4444]]}
# time_series_1 [ {"region"=>"us"} ]
# columns -> ["time", "count", "value"]
# values -> [["2015-07-09T09:02:54Z", 55, 0.4343]]}
You can also pick the database to query from:
influxdb.query 'select * from time_series_1', database: 'database'
If you expect large quantities of data in a response, you may want to enable
JSON streaming by setting a chunk_size
:
influxdb = InfluxDB::Client.new database,
username: username,
password: password,
chunk_size: 10000
See the official documentation for more details.
By default, InfluxDB::Client will keep trying (with exponential fall-off) to
connect to the database until it gets a connection. If you want to retry only
a finite number of times (or disable retries altogether), you can pass the
:retry
option.
:retry
can be either true
, false
or an Integer
to retry infinite times,
disable retries or retry a finite number of times, respectively. Passing 0
is
equivalent to false
and -1
is equivalent to true
.
$ irb -r influxdb
> influxdb = InfluxDB::Client.new 'database', retry: 8
=> #<InfluxDB::Client:0x00000002bb5ce0 ...>
> influxdb.query 'select * from serie limit 1'
E, [2016-08-31T23:55:18.287947 #23476] WARN -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 0.01s.
E, [2016-08-31T23:55:18.298455 #23476] WARN -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 0.02s.
E, [2016-08-31T23:55:18.319122 #23476] WARN -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 0.04s.
E, [2016-08-31T23:55:18.359785 #23476] WARN -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 0.08s.
E, [2016-08-31T23:55:18.440422 #23476] WARN -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 0.16s.
E, [2016-08-31T23:55:18.600936 #23476] WARN -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 0.32s.
E, [2016-08-31T23:55:18.921740 #23476] WARN -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 0.64s.
E, [2016-08-31T23:55:19.562428 #23476] WARN -- InfluxDB: Failed to contact host localhost: #<Errno::ECONNREFUSED: Failed to open TCP connection to localhost:8086 (Connection refused - connect(2) for "localhost" port 8086)> - retrying in 1.28s.
InfluxDB::ConnectionError: Tried 8 times to reconnect but failed.
This index might be out of date. Please refer to InfluxDB::DEFAULT_CONFIG_OPTIONS
,
found in lib/influxdb/config.rb
for the source of truth.
Category | Option | Default value | Notes |
---|---|---|---|
HTTP connection | :host or :hosts |
"localhost" | can be an array and can include port |
:port |
8086 | fallback port, unless provided by :host option |
|
:prefix |
"" | URL path prefix (e.g. server is behind reverse proxy) | |
:username |
"root" | user credentials | |
:password |
"root" | user credentials | |
:open_timeout |
5 | socket timeout | |
:read_timeout |
300 | socket timeout | |
:auth_method |
"params" | "params", "basic_auth" or "none" | |
Retry | :retry |
-1 | max. number of retry attempts (reading and writing) |
:initial_delay |
0.01 | initial wait time (doubles every retry attempt) | |
:max_delay |
30 | max. wait time when retrying | |
SSL/HTTPS | :use_ssl |
false | whether or not to use SSL (HTTPS) |
:verify_ssl |
true | verify vertificate when using SSL | |
:ssl_ca_cert |
false | path to or name of CA cert | |
Database | :database |
empty | name of database |
:time_precision |
"s" | time resolution for data send to server | |
:epoch |
false | time resolution for server responses (false = server default) | |
Writer | :async |
false | Async options hash, details here |
:udp |
false | UDP connection info, details here | |
:discard_write_errors |
false | suppress UDP socket errors | |
Query | :chunk_size |
empty | details here |
:denormalize |
true | format of result |
git clone git@github.com:influxdata/influxdb-ruby.git
cd influxdb-ruby
bundle
bundle exec rake
- Fork this repository on GitHub.
- Make your changes.
- Add tests.
- Add an entry in the
CHANGELOG.md
in the "unreleased" section on top.
- Run the tests:
bundle exec rake
. - Send a pull request.
- Please rebase against the master branch.
- If your changes look good, we'll merge them.