Current section

Files

Jump to
instream lib instream.ex
Raw

lib/instream.ex

defmodule Instream do
@moduledoc """
InfluxDB driver for Elixir
## Connections
To connect to an InfluxDB server you need a connection module:
defmodule MyApp.MyConnection do
use Instream.Connection, otp_app: :my_app
end
The `:otp_app` name and the name of the module can be freely chosen but have
to be linked to a corresponding configuration entry. This defined connection
module needs to be hooked up into your supervision tree:
children = [
# ...
MyApp.Connection,
# ...
]
Example of the matching configuration entry:
config :my_app, MyApp.MyConnection,
database: "my_default_database",
host: "localhost",
port: 8086
More details on connections and configuration options can be found with the
`Instream.Connection` module.
## Queries
_Note:_ Most queries require a database to operate on. The following places
will be searched (in order from top to bottom) for a configured database:
1. `opts[:database]` parameter
2. `Instream.Series` struct (if used)
3. `Instream.Connection` configuration
4. No database used!
Write queries can be executed asynchronously by passing `[async: true]` to
`MyApp.MyConnection.write()`. The result will then always be an immediate
`:ok` without waiting for the query to be actually executed.
By default the response of a query will be a map decoded from your
server's JSON response.
Alternatively you can pass `[result_as: format]` to
`MyApp.MyConnection.query/2` to change the result format to
one of the following:
- `:csv` CSV encoded response
- `:json` - JSON encoded response (implicit default)
- `:raw` Raw server format (JSON string)
### Query Language Selection
If not otherwise specified all queries will be sent as `InfluxQL`.
This can be changed to `Flux` by passing the option `[query_language: :flux]`
to `MyApp.MyConnection.query/2`
### Reading Data
# passing database to query/2
MyApp.MyConnection.query(
"SELECT * FROM some_measurement",
database: "my_database"
)
# defining database in the query
MyApp.MyConnection.query(~S(
SELECT * FROM "my_database"."default"."some_measurement"
))
# passing precision (= epoch) for query results
MyApp.MyConnection.query(
"SELECT * FROM some_measurement",
precision: :minutes
)
# using parameter binding
MyApp.MyConnection.query(
"SELECT * FROM some_measurement WHERE field = $field_param",
params: %{field_param: "some_value"}
)
### POST Queries
Some queries require you to switch from the regular `read only context`
(all GET requets) to a `write context` (all POST requests).
When not using the query build you have to pass that information
manually to `query/2`:
MyApp.MyConnection.query(
"CREATE DATABASE create_in_write_mode",
method: :post
)
### Query Timeout Configuration
If you find your queries running into timeouts (e.g. `:hackney` not waiting
long enoug for a response) you can pass an option to the query call:
MyApp.MyConnection.query(query, timeout: 250)
This value can also be set as a default via the `:recv_timeout` value for
your HTTP client configuration (see `Instream.Connection.Config` for details).
A passed configuration will take precedence over the connection configuration.
This does not apply to write requests. They are currently only affected by
configured `:recv_timeout` values. Setting a connection timeout enables you
to have a different timeout for read and write requests.
Write queries are run through a process pool having an additional timeout:
config :my_app, MyApp.MyConnection,
pool_timeout: 500
This configuration will be used to wait for an available worker
to execute a query and defaults to `5_000`.
## Writing Points
Writing data to your InfluxDB server can be done via
`Instream.Series` modules or using raw maps.
Please also refer to `Instream.Connection.write/2` for an overview
of additional options you can use when writing data.
### Writing Points using Series
Each series in your database is represented by a definition module:
defmodule MySeries do
use Instream.Series
series do
database "my_database"
measurement "my_measurement"
tag :bar
tag :foo
field :value
end
end
Using this definition you can use the generated struct to create
a data point and write it to your database:
MyConnection.write(%MySeries{
fields: %MySeries.Fields{value: 17},
tags: %MySeries.Tags{bar: "bar", foo: "foo"}
})
More information about series definitions can be found in the
module documentation of `Instream.Series`.
### Writing Points using Plain Maps
As an alternative you can use a non-struct map to write points to a database:
MyConnection.write(%{
points: [
%{
database: "my_database",
measurement: "my_measurement",
fields: %{answer: 42, value: 1},
tags: %{foo: "bar"},
timestamp: 1439587926000000000
},
# more points possible ...
],
database: "my_database"
})
* The field `timestamp` can be omitted, so InfluxDB will use the receive time.
* The field `database` can be used to write to a custom database.
Please be aware that only the database from the first point
will be used when writing multiple points.
"""
end