Agent skill

Telemetry Essentials

by j-morgan6 in j-morgan6/elixir-phoenix-guide

A skill your agent uses when adding logging, metrics, or instrumentation — structured Logger usage, telemetry handler attachment, Ecto/Phoenix telemetry events.

MITAuto-check passedDevOps & Cloud

Install Telemetry Essentials

skills CLI
$ npx skills add j-morgan6/elixir-phoenix-guide --skill telemetry-essentials -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install j-morgan6/elixir-phoenix-guide telemetry-essentials --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/j-morgan6/elixir-phoenix-guide.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/telemetry-essentials .claude/skills/telemetry-essentials && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
telemetry-essentials
GitHub stars
166
Token cost
~2.7k tokens
SKILL.md length
385 words
Files
1
Skills in repo
19
Repo updated
First seen
Licence
MIT

At a glance

A skill your agent uses when adding logging, metrics, or instrumentation — structured Logger usage, telemetry handler attachment, Ecto/Phoenix telemetry events.

  • Works in 6 steps: Use structured logging… → Attach telemetry handlers in… → Use Ecto.Repo telemetry events for query… → …
  • Instrumentation — structured Logger usage
  • SKILL.md covers RULES — Follow these with no…, Structured Logging, :telemetry Basics and Ecto Telemetry Events, plus 5 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Telemetry Essentials is an agent skill from j-morgan6/elixir-phoenix-guide. Use when adding logging, metrics, or instrumentation — structured Logger usage, telemetry handler attachment, Ecto/Phoenix telemetry events.

Its SKILL.md is about 2.7k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in DevOps & Cloud, covering Observability and LLM observability. The licence is MIT.

When your agent uses it

  • Instrumentation — structured Logger usage
  • Telemetry handler attachment
  • Ecto/Phoenix telemetry events

Example prompts

  • “/telemetry-essentials”

Workflow steps

6 steps, taken from the first numbered list in SKILL.md.

  1. Use structured logging (Logger.info("action", key: value)) — never string interpolation in log messages; structured logs are searchable…
  2. Attach telemetry handlers in Application.start/2 — :telemetry.attach/4 with an existing handler ID returns {:error, :already_exists}, so…
  3. Use Ecto.Repo telemetry events for query monitoring — don't wrap every query manually; Ecto already emits events
  4. Use Phoenix.LiveDashboard in dev/staging — it's free observability with zero code
  5. Tag telemetry events with metadata (user_id, request_id) — without correlation IDs, distributed traces are useless
  6. Never log at :debug level in production — it includes query parameters and PII

What it can do on your machine

Read from SKILL.md and the folder at commit cdfddac. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are elixir).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Telemetry Essentials loads about 2.7k tokens when it runs. Until then it costs about 40 tokens; SKILL.md has 385 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~40
When it runs · the whole SKILL.md, loaded when a task matches
~2.7k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from j-morgan6/elixir-phoenix-guide at commit cdfddac, republished under its MIT licence (© j-morgan6). 385 words, ~2,707 tokens.

Download SKILL.mdSave it as .claude/skills/telemetry-essentials/SKILL.md (or your agent's skills folder).
name
telemetry-essentials
description
Use when adding logging, metrics, or instrumentation — structured Logger usage, telemetry handler attachment, Ecto/Phoenix telemetry events.
file_patterns
**/telemetry.ex, **/application.ex, **/*_web.ex
auto_suggest
true

Telemetry Essentials

RULES — Follow these with no exceptions

  1. Use structured logging (Logger.info("action", key: value)) — never string interpolation in log messages; structured logs are searchable and parseable
  2. Attach telemetry handlers in Application.start/2 — :telemetry.attach/4 with an existing handler ID returns {:error, :already_exists}, so it never double-attaches; attach at boot anyway, since handlers detach permanently if they raise and boot-time attachment gives them a stable lifecycle
  3. Use Ecto.Repo telemetry events for query monitoring — don't wrap every query manually; Ecto already emits events
  4. Use Phoenix.LiveDashboard in dev/staging — it's free observability with zero code
  5. Tag telemetry events with metadata (user_id, request_id) — without correlation IDs, distributed traces are useless
  6. Never log at :debug level in production — it includes query parameters and PII

Structured Logging

Structured logs can be filtered, searched, and aggregated. String-interpolated logs cannot.

Bad:

elixir
# String interpolation — unsearchable, inconsistent format
Logger.info("User #{user.id} created order #{order.id} for $#{order.total}")
Logger.error("Failed to process payment for user #{user.id}: #{inspect(reason)}")

Good:

elixir
# Structured logging — searchable, parseable by log aggregators
Logger.info("Order created", user_id: user.id, order_id: order.id, total: order.total)
Logger.error("Payment failed", user_id: user.id, reason: inspect(reason))

Keyword data goes to Logger metadata and is dropped unless whitelisted — add the keys to config :logger, :default_formatter, metadata: [...] (or metadata: :all in dev). Passing user_id: user.id doesn't help if :user_id isn't in that list — it's silently discarded.

Logger Metadata

Set metadata once per request — it's automatically included in all subsequent log calls.

elixir
# In a Plug (added to your endpoint or router pipeline)
defmodule MyAppWeb.Plugs.RequestMetadata do
  import Plug.Conn

  def init(opts), do: opts

  def call(conn, _opts) do
    Logger.metadata(
      request_id: conn.assigns[:request_id] || Ecto.UUID.generate(),
      remote_ip: to_string(:inet.ntoa(conn.remote_ip))
    )
    conn
  end
end

# In a LiveView mount
@impl true
def mount(_params, _session, socket) do
  if connected?(socket) do
    Logger.metadata(user_id: socket.assigns.current_user.id)
  end
  {:ok, socket}
end
JSON Logging for Production
elixir
# config/prod.exs
config :logger, :console,
  format: {LogfmtEx, :format},  # Or Jason-based formatter
  metadata: [:request_id, :user_id, :module, :function]

:telemetry Basics

The :telemetry library is the standard for metrics in the BEAM ecosystem. Libraries (Ecto, Phoenix, Oban) emit events — you attach handlers.

Event Structure
elixir
# An event has: name (list of atoms), measurements (map), metadata (map)
:telemetry.execute(
  [:my_app, :orders, :created],     # event name
  %{count: 1, total_cents: 4999},    # measurements
  %{user_id: user.id, source: :web}  # metadata
)
Show full SKILL.md (166 more words)Show less
Attaching Handlers

:telemetry.attach/4 called with an existing handler ID returns {:error, :already_exists} — it never double-attaches. Attach at boot anyway: handlers detach permanently if they raise, and boot-time attachment gives them a stable lifecycle instead of one tied to a GenServer that may restart independently.

Bad:

elixir
# In a GenServer init — ties the handler's lifecycle to this process instead of boot;
# if the handler function ever raises, it detaches permanently and silently
defmodule MyApp.MetricsServer do
  def init(_) do
    :telemetry.attach("order-handler", [:my_app, :orders, :created], &handle/4, nil)
    {:ok, %{}}
  end
end

Good:

elixir
# In application.ex — runs once at boot
defmodule MyApp.Application do
  use Application

  @impl true
  def start(_type, _args) do
    MyApp.Telemetry.attach_handlers()

    children = [
      MyApp.Repo,
      MyAppWeb.Endpoint
    ]

    Supervisor.start_link(children, strategy: :one_for_one)
  end
end

# lib/my_app/telemetry.ex
defmodule MyApp.Telemetry do
  require Logger

  def attach_handlers do
    :telemetry.attach_many("my-app-handlers", [
      [:my_app, :orders, :created],
      [:my_app, :payments, :processed],
      [:my_app, :payments, :failed]
    ], &handle_event/4, nil)
  end

  def handle_event([:my_app, :orders, :created], measurements, metadata, _config) do
    Logger.info("Order created",
      total_cents: measurements.total_cents,
      user_id: metadata.user_id
    )
  end

  def handle_event([:my_app, :payments, :failed], _measurements, metadata, _config) do
    Logger.error("Payment failed",
      user_id: metadata.user_id,
      reason: metadata.reason
    )
  end
end
Telemetry Spans

For timing operations:

elixir
def process_order(order) do
  :telemetry.span([:my_app, :orders, :process], %{order_id: order.id}, fn ->
    result = do_process(order)
    {result, %{order_id: order.id, status: :completed}}
  end)
end

# Emits two events:
# [:my_app, :orders, :process, :start] — with measurements: %{system_time: ...}
# [:my_app, :orders, :process, :stop]  — with measurements: %{duration: ...}
# [:my_app, :orders, :process, :exception] — if an exception is raised

Ecto Telemetry Events

Ecto automatically emits telemetry events for every query. You don't need to instrument queries manually.

Built-in Events
elixir
# Ecto emits: [:my_app, :repo, :query]
# Measurements: %{
#   total_time: integer,    # Total time in native units
#   decode_time: integer,   # Time decoding results
#   query_time: integer,    # Time executing the query
#   queue_time: integer,    # Time waiting for a connection
#   idle_time: integer      # Time the connection was idle
# }
# Metadata: %{
#   query: "SELECT ...",
#   source: "users",
#   repo: MyApp.Repo,
#   result: {:ok, %Postgrex.Result{}} | {:error, ...}
# }
Monitoring Slow Queries
elixir
defmodule MyApp.Telemetry do
  require Logger

  def attach_handlers do
    :telemetry.attach(
      "ecto-slow-query",
      [:my_app, :repo, :query],
      &handle_slow_query/4,
      %{threshold_ms: 100}
    )
  end

  def handle_slow_query(_event, measurements, metadata, %{threshold_ms: threshold}) do
    duration_ms = System.convert_time_unit(measurements.total_time, :native, :millisecond)

    if duration_ms > threshold do
      Logger.warning("Slow query",
        duration_ms: duration_ms,
        source: metadata.source,
        query: metadata.query
      )
    end
  end
end

Phoenix Telemetry Events

Phoenix emits events for the request lifecycle.

elixir
# Request events:
# [:phoenix, :endpoint, :start]
# [:phoenix, :endpoint, :stop]
# [:phoenix, :router_dispatch, :start]
# [:phoenix, :router_dispatch, :stop]

# LiveView events:
# [:phoenix, :live_view, :mount, :start]
# [:phoenix, :live_view, :mount, :stop]
# [:phoenix, :live_view, :handle_event, :start]
# [:phoenix, :live_view, :handle_event, :stop]

# Channel events:
# [:phoenix, :channel_joined]
# [:phoenix, :channel_handled_in]

LiveDashboard Setup

Phoenix.LiveDashboard provides free observability with zero code.

elixir
# mix.exs — add dependency (already included in new Phoenix projects)
{:phoenix_live_dashboard, "~> 0.8"}

# router.ex
import Phoenix.LiveDashboard.Router

scope "/" do
  pipe_through :browser

  # Only in dev/staging — never expose in production without auth
  live_dashboard "/dashboard",
    metrics: MyAppWeb.Telemetry,
    ecto_repos: [MyApp.Repo],
    ecto_psql_extras_options: [long_running_queries: [threshold: "200 milliseconds"]]
end
Custom Metrics for LiveDashboard
elixir
# lib/my_app_web/telemetry.ex
defmodule MyAppWeb.Telemetry do
  use Supervisor
  import Telemetry.Metrics

  def start_link(arg) do
    Supervisor.start_link(__MODULE__, arg, name: __MODULE__)
  end

  @impl true
  def init(_arg) do
    children = [
      {:telemetry_poller, measurements: periodic_measurements(), period: 10_000}
    ]
    Supervisor.init(children, strategy: :one_for_one)
  end

  def metrics do
    [
      # Phoenix metrics
      summary("phoenix.endpoint.stop.duration", unit: {:native, :millisecond}),
      summary("phoenix.router_dispatch.stop.duration", unit: {:native, :millisecond}),

      # Ecto metrics
      summary("my_app.repo.query.total_time", unit: {:native, :millisecond}),
      summary("my_app.repo.query.queue_time", unit: {:native, :millisecond}),

      # VM metrics
      summary("vm.memory.total", unit: :byte),
      summary("vm.total_run_queue_lengths.total"),

      # Custom business metrics
      counter("my_app.orders.created.count"),
      summary("my_app.payments.processed.duration", unit: {:native, :millisecond})
    ]
  end

  defp periodic_measurements do
    [
      {MyApp.Metrics, :dispatch_queue_depth, []}
    ]
  end
end

Custom Business Metrics

Emit telemetry events from your contexts for important business operations.

elixir
defmodule MyApp.Orders do
  def create_order(attrs) do
    :telemetry.span([:my_app, :orders, :create], %{}, fn ->
      case %Order{}
           |> Order.changeset(attrs)
           |> Repo.insert() do
        {:ok, order} ->
          :telemetry.execute([:my_app, :orders, :created], %{
            count: 1,
            total_cents: order.total_cents
          }, %{user_id: order.user_id})

          {{:ok, order}, %{status: :ok}}

        {:error, changeset} ->
          {{:error, changeset}, %{status: :error}}
      end
    end)
  end
end

External Tool Integration

Prometheus
elixir
# mix.exs
{:telemetry_metrics_prometheus, "~> 1.1"}

# application.ex children
TelemetryMetricsPrometheus.child_spec(metrics: MyAppWeb.Telemetry.metrics())

# Exposes /metrics endpoint for Prometheus scraping
StatsD / Datadog
elixir
# mix.exs
{:telemetry_metrics_statsd, "~> 0.7"}

# application.ex children
{TelemetryMetricsStatsd, metrics: MyAppWeb.Telemetry.metrics()}

Production Log Levels

Default to :info in production — :debug logs SQL query parameters, which is a PII risk.

Production log level config lives in the deployment-gotchas skill (§7).


See deployment-gotchas skill for production configuration patterns. See security-essentials skill for sensitive data logging rules. See otp-essentials skill for process monitoring patterns.

© j-morgan6, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in skills/telemetry-essentials of j-morgan6/elixir-phoenix-guide.

Open the folder on GitHubat commit cdfddac

Compare with similar skills

Telemetry Essentials next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Telemetry Essentials compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Telemetry Essentials this skillj-morgan6/elixir-phoenix-guide166—~2.7kAutomated safety check: PassMIT
Caveman Gateway SetupJuliusBrussee/caveman110k1 repos~2.6kAutomated safety check: WarnApache-2.0
Agent Platform Alert Configurationgoogle/skills21k—~4.2kAutomated safety check: PassApache-2.0
Agent Observability Experiment Bootstrapdatadog-labs/agent-skills177—~2.3kAutomated safety check: PassMIT
Arize PhoenixArize-ai/phoenix12k1 repos~3.8kAutomated safety check: PassMIT
Arize Instrumentationgithub/awesome-copilot40k—~6.2kAutomated safety check: NotesMIT

Similar skills

  • Caveman Gateway Setup

    JuliusBrussee/caveman

    Routes every LLM call in a repository through the Caveman Cloud gateway in record mode, so requests and costs are measured without changing behavior.

    110k GitHub starsUsed in 1 repo~2.6k tokens
    DevOps & CloudAuto-check: warnings
  • Official

    Writes Terraform alerting policies for AI agents that emit OpenTelemetry metrics, covering reliability, cost, safety, security and quality signals on Google Cloud.

    21k GitHub stars~4.2k tokensUpdated today
    DevOps & CloudAuto-check passed
  • Bootstrap a reproducible LLM Observability experiment through the Python ddtrace SDK or the Node dd-trace SDK.

    177 GitHub stars~2.3k tokensUpdated today
    DevOps & CloudAuto-check passed
  • Arize Phoenix

    Arize-ai/phoenix

    Open-source AI observability platform for tracing, evaluating, and improving LLM applications with OpenTelemetry integration

    12k GitHub starsUsed in 1 repo~3.8k tokens
    DevOps & CloudAuto-check passed
  • Arize Instrumentation

    github/awesome-copilot

    Official

    Adds Arize AX tracing to an LLM application for the first time.

    40k GitHub stars~6.2k tokensUpdated today
    DevOps & CloudAuto-check: notes
  • Google Agents CLI Observability

    pifferologo/cloud-agents-cli

    This skill should be used when the user wants to "set up tracing", "monitor my ADK agent", "configure logging", "add observability", "debug production traffic", or needs guidance on monitoring…

    129 GitHub starsUsed in 1 repo~2.5k tokens
    DevOps & CloudAuto-check passed

More from j-morgan6/elixir-phoenix-guide

All 19 skills in this repo
  • Code Quality

    j-morgan6/elixir-phoenix-guide

    A skill your agent uses when refactoring for duplication, complexity, or dead code — includes the plugin's on-demand analysis scripts.

    166 GitHub stars~1.4k tokensUpdated 3 mo ago
    Auto-check passed
  • Deployment Gotchas

    j-morgan6/elixir-phoenix-guide

    A skill your agent uses when preparing releases or deployment config — runtime.exs vs compile-time config, release migrations, PHXHOST/PHXSERVER, assets, health checks.

    166 GitHub stars~2.6k tokensUpdated 3 mo ago
    Auto-check passed
  • Ecto Changeset Patterns

    j-morgan6/elixir-phoenix-guide

    A skill your agent uses when a resource needs multiple changesets (registration vs update), conditional validation, field transforms, or uniqueness validation — changeset composition.

    166 GitHub stars~2.1k tokensUpdated 3 mo ago
    Auto-check passed
  • Ecto Essentials

    j-morgan6/elixir-phoenix-guide

    A skill your agent uses when defining schemas, writing queries, or creating migrations — schema design, Repo usage, indexes, query composition.

    166 GitHub stars~2.2k tokensUpdated 3 mo ago
    Auto-check passed
  • Ecto Nested Associations

    j-morgan6/elixir-phoenix-guide

    A skill your agent uses when a form or operation manages parent and child records together — castassoc/castembed, onreplace, Ecto.Multi across tables, FK cascade design.

    166 GitHub stars~2.2k tokensUpdated 3 mo ago
    Auto-check passed
  • Elixir Essentials

    j-morgan6/elixir-phoenix-guide

    A skill your agent uses when writing or refactoring core Elixir — pattern matching, case/cond/with, pipes, {:ok, }/{:error, } contracts.

    166 GitHub stars~2.2k tokensUpdated 3 mo ago
    Auto-check passed

Questions about Telemetry Essentials

What does Telemetry Essentials do?

A skill your agent uses when adding logging, metrics, or instrumentation — structured Logger usage, telemetry handler attachment, Ecto/Phoenix telemetry events. Telemetry Essentials is an agent skill from j-morgan6/elixir-phoenix-guide. Use when adding logging, metrics, or instrumentation — structured Logger usage, telemetry handler attachment, Ecto/Phoenix telemetry events.

When should I use Telemetry Essentials?

Telemetry Essentials fits situations like: instrumentation — structured Logger usage; telemetry handler attachment; ecto/Phoenix telemetry events.

How do I install Telemetry Essentials in Claude Code?

Run `npx skills add j-morgan6/elixir-phoenix-guide --skill telemetry-essentials -a claude-code`. Or copy the skill folder (skills/telemetry-essentials in j-morgan6/elixir-phoenix-guide) into .claude/skills/telemetry-essentials in your project. Claude Code loads it when a task matches its description.

How do I install Telemetry Essentials in Codex?

Run `npx skills add j-morgan6/elixir-phoenix-guide --skill telemetry-essentials -a codex`. Or copy the skill folder (skills/telemetry-essentials in j-morgan6/elixir-phoenix-guide) into .agents/skills/telemetry-essentials in your project. Codex loads it when a task matches its description.

Can I use Telemetry Essentials in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add j-morgan6/elixir-phoenix-guide --skill telemetry-essentials -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/telemetry-essentials, .gemini/skills/telemetry-essentials, .github/skills/telemetry-essentials and .opencode/skills/telemetry-essentials in your project.

What does Telemetry Essentials need to run?

SKILL.md names no scripts, command-line tools or credentials: Telemetry Essentials is instructions for the agent only.

Does Telemetry Essentials access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Telemetry Essentials safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Telemetry Essentials use?

Telemetry Essentials is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Telemetry Essentials use?

About 2.7k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Telemetry Essentials?

Skills that share tags, products or a category with Telemetry Essentials: Caveman Gateway Setup (JuliusBrussee/caveman, 110k stars), Agent Platform Alert Configuration (google/skills, 21k stars), Agent Observability Experiment Bootstrap (datadog-labs/agent-skills, 177 stars) and Arize Phoenix (Arize-ai/phoenix, 12k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Telemetry Essentials?

j-morgan6 (a GitHub user) maintains it in j-morgan6/elixir-phoenix-guide, which has 166 GitHub stars. The repository holds 19 skills in this directory. The repository was last updated on July 6, 2026.

Source: j-morgan6/elixir-phoenix-guide on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.