Instream v1.0.0 Instream.Series behaviour View Source

Defines a series.

Series Definition

If you do not want to define the raw maps for writing data you can pre-define a series module for later usage:

defmodule MySeries do
  use Instream.Series

  series do
    database "my_database_optional"
    measurement "cpu_load"

    tag :host, default: "www"
    tag :core

    field :value, default: 100
    field :value_desc
  end
end

The macros tag/2 and field/2 both accept a keyword tuple with a :default entry. This value will be pre-assigned when using the data struct with all other fields or tags being set to nil.

Metadata

The metadata of a series (e.g. the measurement) can be retrieved using the __meta__/1 method.

Struct

Every series will be registered as a struct. Following the above usage example you will get the following struct:

%MySeries{
  fields: %MySeries.Fields{value: 100, value_desc: nil},
  tags: %MySeries.Tags{host: "www", core: nil},
  timestamp: nil
}

:timestamp is expected to be a unix nanosecond timestamp.

Series Hydration

Whenever you want to convert a plain map or a query result into a specific series you can use the built-in hydration methods:

MySeries.from_map(%{
  timestamp: 1234567890,
  some_tag: "hydrate",
  some_field: 123
})

~S("SELECT * FROM "my_measurement")
|> MyConnection.query()
|> MySeries.from_result()

The timestamp itself is kept "as is" for integer values, timestamps in RFC3339 format (e.g. "1970-01-01T01:00:00.000+01:00") will be converted to :nanosecond integer values.

Please be aware that when using an OTP release prior to 21.0 the time will be truncated to :microsecond precision due to :calendar.rfc3339_to_system_time/2 not being available and DateTime.from_iso8601/1 only supporting microseconds.

Writing Series Points

You can then use your series module to assemble a data point (one at a time) for writing:

data = %MySeries{}
data = %{data | fields: %{data.fields | value: 17}}
data = %{data | tags: %{data.tags | bar: "bar", foo: "foo"}}

And then write one or many at once:

MyConnection.write(point)
MyConnection.write([point_1, point_2, point_3])

If you want to pass an explicit timestamp to the database you can use the key :timestamp:

data = %MySeries{}
data = %{data | timestamp: 1439587926000000000}

The timestamp is (by default) expected to be a nanosecond unix timestamp. To use different precision (for all points in this write operation!) you can change this value by modifying your write call:

data = %MySeries{}
data = %{data | timestamp: 1439587926}

MyConnection.write(data, precision: :second)

Supported precision types are:

  • :hour
  • :minute
  • :second
  • :millisecond
  • :microsecond
  • :nanosecond

Please be aware that the UDP protocol writer does not support custom timestamp precisions. All UDP timestamps are implicitly expected to already be at nanosecond precision.

Note: While it is possible to write multiple points a once it is currently not supported to write them to individual databases. The first point written defines the database, other values are silently ignored!

Link to this section Summary

Functions

Defines the database for the series.

Defines a field in the series.

Defines the measurement of the series.

Defines the series.

Defines a tag in the series.

Callbacks

Provides metadata access for a series.

Creates a series dataset from any given map.

Creates a list of series datasets from a query result map.

Link to this section Functions

Link to this macro

database(name)

View Source (macro)

Defines the database for the series.

Link to this macro

field(name, opts \\ [])

View Source (macro)

Defines a field in the series.

Link to this macro

measurement(name)

View Source (macro)

Defines the measurement of the series.

Defines the series.

Link to this macro

tag(name, opts \\ [])

View Source (macro)

Defines a tag in the series.

Link to this section Callbacks

Specs

__meta__(atom()) :: any()

Provides metadata access for a series.

Available information

  • :database - the database where the series is stored (optional)
  • :fields - the fields in the series
  • :measurement - the measurement of the series
  • :tags - the available tags defining the series

Specs

from_map(map()) :: struct()

Creates a series dataset from any given map.

Keys not defined in the series are silently dropped.

Specs

from_result(map()) :: [struct()]

Creates a list of series datasets from a query result map.

Keys not defined in the series are silently dropped.