Elixir client library for InfluxDB v3 with v2 compatibility.
All public API operations go through this facade module.
Delegates to the configured client implementation
(InfluxElixir.Client.HTTP or InfluxElixir.Client.Local).
Named Connections
All facade functions accept either a keyword config or an atom name.
When an atom is passed, it is resolved via InfluxElixir.Connection.fetch!/1
from the persistent-term registry (populated automatically by
InfluxElixir.ConnectionSupervisor on startup).
# Using a named connection (registered at startup)
InfluxElixir.health(:trading)
InfluxElixir.write(:trading, "cpu value=1.0", database: "prices")
# Using a raw config (e.g. a `Client.Local` connection in tests)
InfluxElixir.health(conn)Configuration
# config/config.exs
config :influx_elixir, :client, InfluxElixir.Client.HTTP
config :influx_elixir, :connections,
trading: [
host: "influx-trading",
token: "...",
database: "prices"
]
# config/test.exs
config :influx_elixir, :client, InfluxElixir.Client.LocalWriting
write/3 sends line protocol, a InfluxElixir.Write.Point or a list of them in one
request. A connection with a batch_writer: option also takes write_batched/3, which
buffers the payload and returns; the writer sends the buffer in batches, retries the
failures a retry can mend, and answers flush/2 and stats/2 while it waits for the
server. See InfluxElixir.Write.BatchWriter.
Telemetry
write/3 and the query functions emit [:influx_elixir, :write | :query, :start | :stop | :exception] events; see InfluxElixir.Telemetry.
Summary
Functions
Adds a new named connection dynamically at runtime.
Returns the configured client implementation module.
Creates a bucket in InfluxDB v2 (backwards compatibility). opts may carry
retention: in seconds and org_id:; see InfluxElixir.Admin.Buckets.create/3.
Creates a database in InfluxDB v3. opts may carry retention: as a
duration string such as "30d"; see InfluxElixir.Admin.Databases.create/3.
Creates a named InfluxDB 3 token; see InfluxElixir.Admin.Tokens.create/3.
Deletes a bucket in InfluxDB v2 (backwards compatibility).
Deletes a database in InfluxDB v3.
Deletes an InfluxDB 3 token by name; see InfluxElixir.Admin.Tokens.delete/2.
Sends a SQL statement to /api/v3/query_sql as it is.
Forces an immediate flush of the batch writer for a connection.
Checks the health of an InfluxDB instance.
Lists all buckets in InfluxDB v2 (backwards compatibility).
Lists all databases in InfluxDB v3.
Constructs a new Point struct.
Executes a Flux query against InfluxDB v2 (backwards compatibility).
Executes an InfluxQL query against InfluxDB v3.
Executes a SQL query against InfluxDB v3.
Executes a streaming SQL query, returning a lazy Stream.
Removes a named connection dynamically at runtime.
Resolves a connection reference to a config keyword list.
Returns batch writer statistics for a connection.
Writes line protocol, or Points, to InfluxDB using the configured client.
Buffers a write on the batch writer of a connection.
Functions
@spec add_connection( atom(), keyword() ) :: Supervisor.on_start_child()
Adds a new named connection dynamically at runtime.
If the connection does not start — a batch_writer: option that
InfluxElixir.Write.BatchWriter refuses, say — the error is returned
and nothing is left behind: the name does not resolve and the client's
connection state is released. The error never holds the :token.
A config the client refuses is {:error, {reason, child_spec}}, never a
raise: under InfluxElixir.Client.HTTP the %NimbleOptions.ValidationError{}
of InfluxElixir.Config.validate/1 (an unknown option such as
default_database:, say), under InfluxElixir.Client.Local the
%ArgumentError{} of InfluxElixir.Client.Local.start/1.
@spec client() :: module()
Returns the configured client implementation module.
@spec create_bucket( InfluxElixir.Client.connection(), binary(), keyword() ) :: :ok | {:error, term()}
Creates a bucket in InfluxDB v2 (backwards compatibility). opts may carry
retention: in seconds and org_id:; see InfluxElixir.Admin.Buckets.create/3.
@spec create_database( InfluxElixir.Client.connection(), binary(), keyword() ) :: :ok | {:error, term()}
Creates a database in InfluxDB v3. opts may carry retention: as a
duration string such as "30d"; see InfluxElixir.Admin.Databases.create/3.
@spec create_token( InfluxElixir.Client.connection(), binary(), keyword() ) :: {:ok, map()} | {:error, term()}
Creates a named InfluxDB 3 token; see InfluxElixir.Admin.Tokens.create/3.
@spec delete_bucket(InfluxElixir.Client.connection(), binary()) :: :ok | {:error, term()}
Deletes a bucket in InfluxDB v2 (backwards compatibility).
@spec delete_database(InfluxElixir.Client.connection(), binary()) :: :ok | {:error, term()}
Deletes a database in InfluxDB v3.
@spec delete_token(InfluxElixir.Client.connection(), binary()) :: :ok | {:error, term()}
Deletes an InfluxDB 3 token by name; see InfluxElixir.Admin.Tokens.delete/2.
@spec execute_sql( InfluxElixir.Client.connection(), binary(), keyword() ) :: {:ok, map() | [map()]} | {:error, term()}
Sends a SQL statement to /api/v3/query_sql as it is.
InfluxDB 3 Core refuses every statement that changes data (verified):
DELETE, INSERT and UPDATE are {:error, %{status: 400, body: "Error during planning: DML not supported: ..."}}, CREATE and DROP
are ... DDL not supported: ..., anything else is a 405. A SELECT
returns {:ok, rows} typed like query_sql/3 rows. Remove data with
delete_database/2 instead. Client.Local answers the same way; under
its :v3_enterprise profile it also runs DELETE FROM m [WHERE ...]
and returns {:ok, %{"rows_affected" => n}}.
Forces an immediate flush of the batch writer for a connection.
Returns :ok on success or {:error, :no_batch_writer} if no
batch writer is configured for the given connection.
The optional timeout is forwarded to BatchWriter.flush/2 and
bounds the underlying GenServer.call. See BatchWriter.flush/2
for the default and semantics.
@spec health(InfluxElixir.Client.connection()) :: {:ok, map()} | {:error, term()}
Checks the health of an InfluxDB instance.
@spec list_buckets(InfluxElixir.Client.connection()) :: {:ok, [map()]} | {:error, term()}
Lists all buckets in InfluxDB v2 (backwards compatibility).
@spec list_databases(InfluxElixir.Client.connection()) :: {:ok, [map()]} | {:error, term()}
Lists all databases in InfluxDB v3.
@spec point( String.t(), %{required(String.t()) => InfluxElixir.Write.Point.field_value()} | nil, keyword() ) :: InfluxElixir.Write.Point.t()
Constructs a new Point struct.
Parameters
measurement- measurement namefields- field key-value pairs (nilis none)opts- optional:tags(nilis none) and:timestamp
See InfluxElixir.Write.Point.new/3.
Examples
InfluxElixir.point("cpu", %{"value" => 0.64},
tags: %{"host" => "server01"}
)
@spec query_flux(InfluxElixir.Client.connection(), binary(), keyword()) :: InfluxElixir.Client.query_result()
Executes a Flux query against InfluxDB v2 (backwards compatibility).
@spec query_influxql( InfluxElixir.Client.connection(), binary(), keyword() ) :: InfluxElixir.Client.query_result()
Executes an InfluxQL query against InfluxDB v3.
@spec query_sql( InfluxElixir.Client.connection(), binary(), keyword() ) :: InfluxElixir.Client.query_result()
Executes a SQL query against InfluxDB v3.
Supports transport: :http | :flight option for transport selection
(InfluxElixir.Client.HTTP only; Client.Local is in-memory and ignores it).
Common Options
:database— overrides the connection-level default database.:timeout— per-call timeout in milliseconds, else the connection's:timeout, else30_000. Over HTTP it is Finch's receive timeout; over Flight it is a wall-clock bound on the call and the streaming of the whole result ({:error, :timeout}past it).:pool_timeout— per-call Finch pool checkout timeout in milliseconds (HTTP transport; default5_000). Applies before:timeout.:params— map of$name => valueplaceholder substitutions (HTTP transport only; Flight returns{:error, :params_unsupported_over_flight}).:transport—:http(default) or:flight(Arrow Flight gRPC).:flight_port— gRPC port for:flight; falls back to the connection's:flight_port, then443. Passtls: falsefor plaintext ports.
Errors
A connection that is neither a keyword list nor a map is
{:error, {:invalid_connection, connection}}. A refused query is
{:error, %{status: http_status, body: message}} on both transports: Flight's gRPC
status is turned into the nearest HTTP one (see InfluxElixir.Flight.Client.query/3), but
the two do not always agree on the status (a schema error is 500 over HTTP and 400 over
Flight; a missing database is 404 and 500) and Flight's message keeps the engine's
prefix (Error while logically planning query: ...).
@spec query_sql_stream( InfluxElixir.Client.connection(), binary(), keyword() ) :: Enumerable.t()
Executes a streaming SQL query, returning a lazy Stream.
Use for large result sets to avoid loading all rows into memory. On the HTTP transport the JSONL response is decoded incrementally with back-pressure, so only one chunk plus a partial line is held in memory regardless of result size.
Because the return value is an Enumerable.t(), errors cannot be returned as
an {:error, reason} tuple. Instead, failure classes — a missing database, a
request its arguments cannot make, a non-success HTTP status, or a transport
error — are raised as an InfluxElixir.StreamError when the stream is
enumerated. This mirrors the
{:error, reason} contract of query_sql/3: an outage surfaces as an
exception, never as a silent empty result.
Options
:database— overrides the connection-level default database.:params— map of$name => valueplaceholder substitutions.:timeout— per-call receive timeout in milliseconds.
Removes a named connection dynamically at runtime.
The connection's batch writer, if any, writes what it still holds
before it stops (see "Shutdown" in InfluxElixir.Write.BatchWriter).
@spec resolve_connection(atom() | InfluxElixir.Client.connection()) :: InfluxElixir.Client.connection()
Resolves a connection reference to a config keyword list.
Accepts either an atom name (looked up via Connection.fetch!/1)
or a keyword/map config (returned as-is).
Examples
resolve_connection(:trading)
resolve_connection(host: "localhost", token: "t")
@spec stats(atom(), timeout()) :: {:ok, map()} | {:error, :no_batch_writer | {:invalid_timeout, term()}}
Returns batch writer statistics for a connection.
Returns {:ok, stats_map} or {:error, :no_batch_writer} if no
batch writer is configured for the given connection. The optional timeout
(default 5_000 ms) bounds the call.
@spec write( InfluxElixir.Client.connection(), iodata() | InfluxElixir.Write.Point.t() | [InfluxElixir.Write.Point.t()], keyword() ) :: InfluxElixir.Client.write_result()
Writes line protocol, or Points, to InfluxDB using the configured client.
Goes through InfluxElixir.Write.Writer, so payloads over 1 KB are
gzipped and a [:influx_elixir, :write, ...] telemetry span is emitted.
The payload may be:
- line protocol, a binary or iodata (a list of binaries and bytes);
- a
InfluxElixir.Write.Point(seepoint/3), or a list of them. They are encoded withInfluxElixir.Write.LineProtocol.encode/2for this call's:precision(aDateTimetimestamp is written in that unit) and the connection's:api_version. A point no server accepts is that function's{:error, reason}and nothing is sent.
Any other body, or options that are not a keyword list, is the client's error
({:error, {:invalid_body, body}} and {:error, {:invalid_options, opts}} over
HTTP), never a raise. To buffer writes and send them in batches, see
write_batched/3.
Options
:database— overrides the connection-level default database.:precision— the unit of the timestamps (default nanoseconds); seeInfluxElixir.Client.Localfor the spellings each server accepts.:accept_partial— InfluxDB 3 only.falsemakes the write all-or-nothing: the first bad line (a parse error or a schema conflict, in line order) rejects the payload, nothing is stored, and the error is{:error, %{status: 400, body: json}}with"line protocol parsing error"and that one line under"data". Defaulttrue: good lines are stored and the bad ones reported as a partial write.:no_sync— InfluxDB 3 only.trueacknowledges the write before it is persisted to the write-ahead log: faster, and a query right after it may not see the points yet (verified).:gzip—truecompresses every payload,falsenone; by default only payloads over 1 KB (seeInfluxElixir.Write.Writer.write/3).
Examples
point = InfluxElixir.point("cpu", %{"value" => 0.64}, tags: %{"host" => "web01"})
{:ok, :written} = InfluxElixir.write(:default, point)
{:ok, :written} = InfluxElixir.write(:default, [point], precision: :millisecond)
@spec write_batched( atom(), iodata() | InfluxElixir.Write.Point.t() | [InfluxElixir.Write.Point.t()], keyword() ) :: :ok | {:error, term()}
Buffers a write on the batch writer of a connection.
connection_name is a connection with a batch_writer: option (see
InfluxElixir.Config). The payload is a InfluxElixir.Write.Point, a list of
them, or line protocol (a binary or iodata); Points are encoded for the writer's
:precision and the connection's :api_version, and one without a timestamp is
stamped with the time of this call. See InfluxElixir.Write.BatchWriter.write/3
for the buffering, the flush triggers and the backpressure.
Returns :ok once the payload is buffered. Other results:
{:error, :no_batch_writer}- the connection has no writer running, or its writer stopped (the connection was removed) before it took this call{:error, :buffer_full}- the writer holds as much as it admits while a batch is being retried{:error, reason}- a point that cannot be encoded, a payload that is none of the forms above ({:invalid_payload, payload}), or, withsync: true, the write's own failure
Options
:sync-truewaits until the batch holding the payload has been written (or has failed all its retries) and returns that result, asInfluxElixir.Write.BatchWriter.write_sync/3does. Defaultfalse.:timeout- bound on the call in milliseconds (default60_000;300_000withsync: true).
Examples
point = InfluxElixir.point("cpu", %{"value" => 0.64}, tags: %{"host" => "web01"})
:ok = InfluxElixir.write_batched(:default, point)
:ok = InfluxElixir.write_batched(:default, "cpu value=0.64", sync: true)
:ok = InfluxElixir.flush(:default)