Encodes Point structs into InfluxDB line protocol format.
Handles tag sorting, field type encoding, escaping, multi-point delimiters, and timestamp conversion.
Line Protocol Format
measurement[,tag_key=tag_val]... field_key=field_val[,field_key=field_val]... [timestamp]Field Type Encoding
- Integers: suffixed with
i(e.g.42i) - Floats: as-is (e.g.
0.64) - Strings: double-quoted (e.g.
"hello") - Booleans:
trueorfalse
Escaping Rules
- Measurement names: spaces, commas, backslashes
- Tag keys/values: spaces, commas, equals, backslashes
- Field keys: spaces, commas, equals, backslashes
- Field string values: double-quotes, backslashes
Validation
A point that no InfluxDB accepts is refused here, with a tagged error,
rather than encoded into a line the server rejects — or worse, one it
misreads. Line protocol has no escape for a newline outside a quoted
string value, so a newline in a measurement, tag key, tag value or field
key ends the line early and the remainder is parsed as a second line:
verified against InfluxDB 3, tags: %{"host" => "a\nb"} stores a bogus
measurement b. The checks, each verified against the engine:
| Problem | Error |
|---|---|
| No fields | :empty_fields |
| Empty measurement | :empty_measurement |
Measurement not a string, containing a newline, or starting with # | {:invalid_measurement, value} |
| Tag key empty, not a string, or containing a newline | {:invalid_tag_key, key} |
| Tag value empty, not a string, or containing a newline | {:invalid_tag_value, key, value} |
Tag key time (reserved on every version) | {:reserved_tag_key, "time"} |
| Field key empty, not a string, or containing a newline | {:invalid_field_key, key} |
| Field value not an integer, float, string or boolean, or an integer outside 64 bits | {:invalid_field_value, key, value} |
Timestamp not a DateTime, integer or nil | {:invalid_timestamp, value} |
A measurement, tag key, tag value or field key that ends in a backslash
is refused with the same error as the other problems with that name:
both versions reject the line even though the backslash is escaped. A
measurement starting with # is a comment line to both, which drop it
silently inside a batch, and escaping it (#) stores the backslash. An
integer field must fit in a signed 64-bit integer; there is no unsigned
field type on a Point.
A field named time is left to the server: InfluxDB 3 rejects it and
InfluxDB 2 drops it silently. So is a tab in a name: InfluxDB 3 refuses
the line and InfluxDB 2 stores the tab. A newline inside a string field
value is fine — it is quoted, and both versions store it.
Summary
Functions
Encodes a Point or list of Points into InfluxDB line protocol binary.
Encodes a Point or list of Points into InfluxDB line protocol binary.
Types
Functions
@spec encode( InfluxElixir.Write.Point.t() | [InfluxElixir.Write.Point.t()], keyword() ) :: encode_result()
Encodes a Point or list of Points into InfluxDB line protocol binary.
Returns {:ok, binary} on success or {:error, reason} on failure; see
"Validation" in the moduledoc for the reasons.
Options
:precision- the unit of the write the line is for (:second,:millisecond,:microsecond,:nanosecond, or the short spellingswrite/3takes::s,"ms","us","u","n", ...). ADateTimetimestamp is written in that unit, truncated; without it (or for:auto) in nanoseconds. ADateTimewritten in nanoseconds to a write withprecision: :secondis out of range on the server (verified), so pass the write's precision here. An integer timestamp is written as given: it is already in the caller's unit.
Examples
iex> point = InfluxElixir.Write.Point.new("cpu", %{"value" => 0.64})
iex> {:ok, lp} = InfluxElixir.Write.LineProtocol.encode(point)
iex> lp
"cpu value=0.64"
iex> point = InfluxElixir.Write.Point.new("cpu", %{"count" => 42},
...> tags: %{"host" => "server01"},
...> timestamp: 1_630_424_257_000_000_000
...> )
iex> {:ok, lp} = InfluxElixir.Write.LineProtocol.encode(point)
iex> lp
"cpu,host=server01 count=42i 1630424257000000000"
iex> point = InfluxElixir.Write.Point.new("cpu", %{"v" => 1}, tags: %{"host" => ""})
iex> InfluxElixir.Write.LineProtocol.encode(point)
{:error, {:invalid_tag_value, "host", ""}}
@spec encode!( InfluxElixir.Write.Point.t() | [InfluxElixir.Write.Point.t()], keyword() ) :: binary()
Encodes a Point or list of Points into InfluxDB line protocol binary.
Raises ArgumentError on failure.
Examples
iex> point = InfluxElixir.Write.Point.new("cpu", %{"value" => 0.64})
iex> InfluxElixir.Write.LineProtocol.encode!(point)
"cpu value=0.64"