Segmentry
A non-official Elixir client for Segment, built on Req. Supports batched delivery with automatic retries.
This is a fork of stueccles/analytics-elixir maintained by Rabbet, modernized to use Req in place of Tesla/hackney.
Installation
Add segmentry to your list of dependencies in mix.exs:
def deps do
[
{:segmentry, "~> 0.3"}
]
end
Usage
Start the Segmentry agent with your write key from a Segment HTTP API Server Source.
Segmentry.start_link("YOUR_WRITE_KEY")
There are two ways to call methods on the API. The basic way is via Segmentry.Analytics,
which delegates to the configured GenServer (Segmentry.Analytics.Batcher by default) so
events are queued and batched. The lower-level way is to use Segmentry.Http.send/2 and
Segmentry.Http.batch/2 directly with a client built via Segmentry.Http.client/1 or
Segmentry.Http.client/2.
Track
Segmentry.Analytics.track(user_id, event, %{property1: "", property2: ""})
Or with the full struct:
%Segmentry.Analytics.Track{userId: "abc", event: "Signed Up", properties: %{plan: "pro"}}
|> Segmentry.Analytics.track()
Identify
Segmentry.Analytics.identify(user_id, %{trait1: "", trait2: ""})
Screen
Segmentry.Analytics.screen(user_id, name)
Alias
Segmentry.Analytics.alias(user_id, previous_id)
Group
Segmentry.Analytics.group(user_id, group_id)
Page
Segmentry.Analytics.page(user_id, name)
Setting Context
context = Segmentry.Analytics.Context.new(%{active: false})
Segmentry.Analytics.track(user_id, event, %{property1: ""}, context)
Configuration
config :segmentry, :sender_impl— sender implementation. Defaults toSegmentry.Analytics.Batcher. Set toSegmentry.Analytics.Senderto send each event immediately (asynchronously).config :segmentry, :max_batch_size— maximum events per batch. Default100.config :segmentry, :batch_every_ms— interval (ms) between batches. Default2000.config :segmentry, :retry_attempts— retry count for failed requests. Default3.config :segmentry, :retry_expiry— maximum delay (ms) between retries. Default10_000.config :segmentry, :retry_start— base delay (ms) for the first retry. Default100.config :segmentry, :send_to_http— whenfalse, replaces the HTTP client with a no-op adapter that logs at:debugand returns200. Useful for dev/test. Defaulttrue.config :segmentry, :req_options— keyword list merged into everyReqclient. Useful for injectingReq.Testplug stubs or overriding:receive_timeout.config :segmentry, :api_url— Segment-compatible endpoint. Defaults tohttps://api.segment.io/v1/. Override for Segment's EU instance or compatible APIs like Rudderstack.
Usage in Phoenix
Add a config variable for your write key (typically loaded from the environment):
config :segmentry, write_key: System.get_env("SEGMENT_WRITE_KEY")
Then start Segmentry under your application supervisor (in application.ex):
{Segmentry, Application.get_env(:segmentry, :write_key)}
Testing with Req.Test
Because Segmentry uses Req, you can stub out HTTP using Req.Test:
Req.Test.stub(MySegmentStub, fn conn ->
Plug.Conn.send_resp(conn, 200, "")
end)
{:ok, _pid} = Segmentry.Analytics.Batcher.start_link("test-key", plug: {Req.Test, MySegmentStub})
Telemetry
Segmentry wraps each Segment call in :telemetry.span/3.
You can attach to:
[:segmentry, :send, :start][:segmentry, :send, :stop][:segmentry, :send, :exception][:segmentry, :batch, :start][:segmentry, :batch, :stop][:segmentry, :batch, :exception]
Measurements (in :native time units):
system_timeon:starteventsdurationon:stopand:exceptionevents
Metadata:
- the original
eventorevents status(:ok|:error) and theReqresulton:stopeventserrormatchingresultwhen it isn't{:ok, response}kind,reason,stacktraceon:exceptionevents