# `TerminusDB.Telemetry`
[🔗](https://github.com/thanos/terminusdb-client-elixir/blob/v0.3.3/lib/terminus_db/telemetry.ex#L1)

Telemetry event definitions and emission helpers for `terminusdb_ex`.

Every public operation emits a `[:start]` and `[:stop]` event of the form:

    [:terminusdb, <area>, :start]
    [:terminusdb, <area>, :stop]

where `<area>` is one of `:database`, `:document`, `:query`, `:branch`,
`:merge`, `:diff`, `:commit`, `:woql`, `:graphql`, `:prefix`, `:triples`,
`:remote`, or `:connection`.

## Measurements

- `start`: `%{system_time: System.monotonic_time()}`
- `stop`:  `%{duration: native_time, system_time: System.monotonic_time()}`

`duration` is in `:native` time units; convert in handlers with
`System.convert_time_unit(duration, :native, :millisecond)`.

## Metadata

Both events carry `%{config: redacted_config, method: atom, path: String.t(), area: atom}`
plus, on `:stop`, `status: pos_integer | nil` and `error: TerminusDB.Error.t() | nil`.
The caller (typically `TerminusDB.Client`) is responsible for redacting the config via
`TerminusDB.Config.redact/1` before placing it in the meta, so credentials never leak.

## Attaching

    :telemetry.attach_many(
      "my-handler",
      [[:terminusdb, :database, :stop], [:terminusdb, :query, :stop]],
      fn event, measurements, meta, _ctx ->
        # log slow queries, push metrics, ...
      end,
      nil
    )

# `area`

```elixir
@type area() ::
  :database
  | :document
  | :query
  | :branch
  | :merge
  | :diff
  | :commit
  | :woql
  | :graphql
  | :prefix
  | :triples
  | :remote
  | :connection
```

# `event_name`

```elixir
@spec event_name(area(), :start | :stop) :: [atom(), ...]
```

Returns the event name for a given `area` and `stage` (`:start` or `:stop`).

    iex> TerminusDB.Telemetry.event_name(:database, :start)
    [:terminusdb, :database, :start]

# `start`

```elixir
@spec start(area(), map(), TerminusDB.Config.t()) :: integer() | nil
```

Emits the `[:start]` event for `area` with the given metadata.

Returns the monotonic time captured for the measurement, so callers can pass it to
`stop/4`. No-op when `config.telemetry` is `false`.

## Examples

    iex> config = TerminusDB.Config.new(endpoint: "http://localhost:6363")
    iex> meta = %{path: "db/admin/mydb", method: :post}
    iex> start_time = TerminusDB.Telemetry.start(:database, meta, config)
    iex> is_integer(start_time)
    true

# `stop`

```elixir
@spec stop(area(), map(), integer() | nil, TerminusDB.Config.t(), keyword()) ::
  :ok | nil
```

Emits the `[:stop]` event for `area`, computing `duration` from `start_monotonic`.

Accepts an optional `status` (HTTP status code) and `error` (`TerminusDB.Error.t()`)
to include in the metadata. No-op when `config.telemetry` is `false`.

## Examples

    iex> config = TerminusDB.Config.new(endpoint: "http://localhost:6363")
    iex> meta = %{path: "db/admin/mydb", method: :post, config: TerminusDB.Config.redact(config)}
    iex> start_time = TerminusDB.Telemetry.start(:database, meta, config)
    iex> :ok = TerminusDB.Telemetry.stop(:database, meta, start_time, config, status: 200, error: nil)
    iex> :ok
    :ok

---

*Consult [api-reference.md](api-reference.md) for complete listing*
