Impact (Impact v0.0.1)
Copy MarkdownImpact is an OpenTelemetry-native SDK for capturing LLM/AI traces from Elixir applications and exporting them to Impact via OTLP.
The Elixir SDK is the BEAM-side peer of impact-sdk (Python) and impact-sdk-js
(JavaScript/TypeScript). The three SDKs share a canonical attribute schema:
impact.context.<key>for app-supplied request contextimpact.trace.{type,name,path,input,output}for manual spans
Quick start
Impact.init(
api_key: System.fetch_env!("IMPACT_API_KEY"),
endpoint: System.get_env("IMPACT_BASE_URL"),
mode: :auto
)
Impact.context(
user_id: "u_123",
interaction_id: "int_abc",
attributes: %{team: "growth"}
)
Impact.trace [type: :workflow, name: "checkout"] do
do_work()
endRuntime modes
Mirrors the Python and JS SDKs:
:auto(default) — attach to an existing tracer provider if one is configured, otherwise bootstrap.:bootstrap— always (re)configure:opentelemetryexporter + batch processor.:attach— never replace caller-configured providers; raises if no usable provider is found.
Summary
Functions
Add a timestamped event to the currently active span. Useful for marking notable points within a long-running span (state transitions, retries, cache hits, etc).
Attach context to the current execution. Keys are emitted as impact.context.<key>
span attributes for every span created under this process / OTel context.
Flush pending spans synchronously. Useful in scripts, Lambda-style runtimes, and tests.
Initialize Impact. Idempotent — calling twice replays the last configuration.
Returns the deterministic outcome of optional instrumentation activation,
aligned with impact.instrumentationResults in the JS SDK.
Add attributes to the currently active span. Useful for response-side attributes that are only known after an operation completes.
Set the status of the currently active span. code is :ok | :error |
:unset. message is an optional string (typically required for :error).
Flush and shut down Impact's exporter / batch processor. Safe to call from
Application.stop/1.
Wrap an expression in a manual Impact span.
Types
Functions
Add a timestamped event to the currently active span. Useful for marking notable points within a long-running span (state transitions, retries, cache hits, etc).
Impact.add_event("cache_miss", %{key: cache_key})
Attach context to the current execution. Keys are emitted as impact.context.<key>
span attributes for every span created under this process / OTel context.
Reserved keys are flattened from :attributes. The canonical reserved keys are:
:user_id, :interaction_id, :version_id.
@spec flush(timeout :: pos_integer()) :: :ok
Flush pending spans synchronously. Useful in scripts, Lambda-style runtimes, and tests.
Initialize Impact. Idempotent — calling twice replays the last configuration.
Returns the deterministic outcome of optional instrumentation activation,
aligned with impact.instrumentationResults in the JS SDK.
Add attributes to the currently active span. Useful for response-side attributes that are only known after an operation completes.
Impact.trace [type: :llm, name: "bedrock_call", attributes: request_attrs] do
result = call_llm()
Impact.set_attributes(%{"gen_ai.usage.input_tokens" => result.tokens})
result
endThin macro over OpenTelemetry.Tracer.set_attributes/1 — re-exported so
apps don't need to add :opentelemetry_api to their deps just to set
mid-span attributes.
Set the status of the currently active span. code is :ok | :error |
:unset. message is an optional string (typically required for :error).
Impact.trace [type: :task, name: "do_thing"] do
case do_thing() do
{:ok, _} = ok -> ok
{:error, reason} = err ->
Impact.set_status(:error, inspect(reason))
err
end
end
@spec shutdown(timeout :: pos_integer()) :: :ok
Flush and shut down Impact's exporter / batch processor. Safe to call from
Application.stop/1.
Wrap an expression in a manual Impact span.
Both block and function forms are supported. Block form is a macro so the block body is evaluated lazily inside the span:
require Impact
Impact.trace [type: :task, name: "payment.authorize"] do
authorize(order_id)
endFunction form for non-block use:
Impact.trace([type: :task, name: "payment.authorize"], fn ->
authorize(order_id)
end)