LemonCore.Telemetry (lemon_core v0.1.0)

View Source

Telemetry event helpers for Lemon.

Provides consistent telemetry emission across the umbrella.

Duration convention

New span-style emitters (:start / :stop / :exception) should report duration measured in native units — capture System.monotonic_time() at the start and subtract at the stop, exactly as :telemetry.span/3 does. Derive duration_ms only when a human-facing log needs it, via System.convert_time_unit(duration, :native, :millisecond); never synthesize a native reading by multiplying a millisecond value. Several existing events predate this convention and report duration_us or duration_ms instead — those are catalogued (and not renamed, to avoid breaking attached consumers) in docs/telemetry.md.

Event Names

Runs

  • [:lemon, :run, :submit] - measurements: %{count: 1} meta: %{session_key, origin, engine}. Emitted from LemonRouter.RunOrchestrator when a submission is accepted.
  • [:lemon, :run, :start] - measurements: %{ts_ms: ...} meta: %{run_id, ...}
  • [:lemon, :run, :first_token] - measurements: %{latency_ms: ...} meta: %{run_id}
  • [:lemon, :run, :stop] - measurements: %{duration_ms: ..., ok: boolean()} meta: %{run_id}

:start / :first_token / :stop are emitted from the gateway run process (LemonGateway.Run) via LemonGateway.DependencyManager.emit_telemetry/2, which dispatches here with apply/3. Because the dispatch is dynamic, a literal-name grep for the helpers finds no callers even though the run span fires end-to-end.

Channels

  • [:lemon, :channels, :deliver, :start]
  • [:lemon, :channels, :deliver, :stop]
  • [:lemon, :channels, :deliver, :exception]
  • [:lemon, :channels, :inbound]

Approvals

  • [:lemon, :approvals, :requested]
  • [:lemon, :approvals, :resolved]

Cron

  • [:lemon, :cron, :tick] - measurements: %{job_count: n}. Emitted once per scheduler tick from LemonAutomation.CronManager, as a scheduler-liveness heartbeat.

Memory Ingest (M5)

  • [:lemon, :memory, :ingest, :ok] - measurements: %{duration_us: integer()}, meta: %{run_id, session_key, agent_id}. Emitted after each successful ingest.
  • [:lemon, :memory, :ingest, :failure] - measurements: %{count: 1, duration_us: integer()}, meta: %{run_id, error}. Emitted when an ingest fails (after catching the exception).

Skills

  • [:lemon_skills, :skill, :load] - measurements: %{count: 1, system_time: integer()}, meta includes result, key, view, tool_call_id, session_key, and redacted skill metadata when available. Projected to introspection as :skill_load_observed.
  • [:lemon_skills, :skill, :write] - measurements: %{count: 1, system_time: integer()}, meta includes result, action, name, scope, tool_call_id, session_key, and redacted write metadata. Projected to introspection as :skill_write_observed.
  • [:lemon_skills, :skill, :prompt_render] - measurements: %{count: 1, system_time: integer()}, meta includes surface, skill_count, skill_keys, activation counts, session_key, and redacted prompt-render metadata. Projected to introspection as :skill_prompt_render_observed.

Summary

Functions

Emit channel inbound event.

Emit cron tick event.

Emit run first token event.

Emit run start event.

Emit run stop event.

Execute a function and emit start/stop/exception telemetry.

Functions

approval_requested(approval_id, tool, metadata \\ %{})

@spec approval_requested(approval_id :: binary(), tool :: binary(), metadata :: map()) ::
  :ok

Emit approval requested event.

approval_resolved(approval_id, decision, metadata \\ %{})

@spec approval_resolved(
  approval_id :: binary(),
  decision :: atom(),
  metadata :: map()
) :: :ok

Emit approval resolved event.

channel_inbound(channel_id, metadata \\ %{})

@spec channel_inbound(channel_id :: binary(), metadata :: map()) :: :ok

Emit channel inbound event.

cron_tick(job_count)

@spec cron_tick(job_count :: non_neg_integer()) :: :ok

Emit cron tick event.

emit(event, measurements, metadata \\ %{})

@spec emit(event :: [atom()], measurements :: map(), metadata :: map()) :: :ok

Emit a telemetry event.

run_first_token(run_id, start_ts_ms)

@spec run_first_token(run_id :: binary(), start_ts_ms :: non_neg_integer()) :: :ok

Emit run first token event.

run_start(run_id, metadata \\ %{})

@spec run_start(run_id :: binary(), metadata :: map()) :: :ok

Emit run start event.

run_stop(run_id, duration_ms, ok)

@spec run_stop(run_id :: binary(), duration_ms :: non_neg_integer(), ok :: boolean()) ::
  :ok

Emit run stop event.

run_submit(session_key, origin, engine)

@spec run_submit(session_key :: binary(), origin :: atom(), engine :: binary()) :: :ok

Emit run submit event.

span(event_prefix, metadata, fun)

@spec span(event_prefix :: [atom()], metadata :: map(), fun :: (-> result)) :: result
when result: term()

Execute a function and emit start/stop/exception telemetry.