Lotus.Telemetry (Lotus v1.0.0)

Copy Markdown View Source

Telemetry events emitted by Lotus.

Lotus uses :telemetry to emit events for query execution, cache operations, and schema introspection. You can attach handlers to these events for monitoring, logging, or integration with tools like Phoenix LiveDashboard or AppSignal.

Query Events

[:lotus, :query, :start]

Emitted when a query begins execution.

Measurements:

  • :system_time - The system time at the start of the query (in native units)

Metadata:

  • :source - The data source name (e.g. "main", "warehouse")
  • :statement - The Lotus.Query.Statement being executed. Its :body is the adapter-native payload and :params the bound values.
  • :context - The caller-supplied context (or nil)

[:lotus, :query, :stop]

Emitted when a query completes successfully.

Measurements:

  • :duration - The query duration (in native time units)
  • :row_count - The number of rows returned

Metadata:

  • :source - The data source name
  • :statement - The Lotus.Query.Statement that was executed
  • :context - The caller-supplied context (or nil)
  • :result - The Lotus.Result struct

[:lotus, :query, :exception]

Emitted when a query fails with an exception.

Measurements:

  • :duration - The time elapsed before the failure (in native time units)

Metadata:

  • :source - The data source name
  • :statement - The Lotus.Query.Statement that was executed
  • :context - The caller-supplied context (or nil)
  • :kind - The kind of exception (:error, :exit, or :throw)
  • :reason - The exception or error reason
  • :stacktrace - The stacktrace

Cache Events

[:lotus, :cache, :hit]

Emitted when a cache lookup finds an existing entry.

Measurements:

  • :count - Always 1

Metadata:

  • :key - The cache key

[:lotus, :cache, :miss]

Emitted when a cache lookup does not find an entry.

Measurements:

  • :count - Always 1

Metadata:

  • :key - The cache key

[:lotus, :cache, :put]

Emitted when a value is stored in the cache.

Measurements:

  • :count - Always 1

Metadata:

  • :key - The cache key
  • :ttl_ms - The TTL in milliseconds

Schema Introspection Events

[:lotus, :schema, :introspection, :start]

Emitted when a schema introspection operation begins.

Measurements:

  • :system_time - The system time at the start (in native units)

Metadata:

  • :operation - The introspection operation (e.g., :list_schemas, :list_tables, :describe_table, :get_table_stats, :list_relations)
  • :source - The data source name

[:lotus, :schema, :introspection, :stop]

Emitted when a schema introspection operation completes.

Measurements:

  • :duration - The operation duration (in native time units)

Metadata:

  • :operation - The introspection operation
  • :source - The data source name
  • :result - :ok or :error

Example

Attach a handler in your application's start/2 callback:

:telemetry.attach_many(
  "lotus-logger",
  [
    [:lotus, :query, :stop],
    [:lotus, :query, :exception],
    [:lotus, :cache, :hit],
    [:lotus, :cache, :miss]
  ],
  &MyApp.TelemetryHandler.handle_event/4,
  nil
)

A simple logging handler:

defmodule MyApp.TelemetryHandler do
  require Logger

  def handle_event([:lotus, :query, :stop], measurements, metadata, _config) do
    duration_ms = System.convert_time_unit(measurements.duration, :native, :millisecond)
    Logger.info("Lotus query completed in #{duration_ms}ms, rows: #{measurements.row_count}")
  end

  def handle_event([:lotus, :query, :exception], measurements, metadata, _config) do
    duration_ms = System.convert_time_unit(measurements.duration, :native, :millisecond)
    Logger.error("Lotus query failed after #{duration_ms}ms: #{inspect(metadata.reason)}")
  end

  def handle_event([:lotus, :cache, :hit], _measurements, metadata, _config) do
    Logger.debug("Lotus cache hit: #{metadata.key}")
  end

  def handle_event([:lotus, :cache, :miss], _measurements, metadata, _config) do
    Logger.debug("Lotus cache miss: #{metadata.key}")
  end
end