elixir-telemetry

Telemetry instrumentation and observability patterns for Elixir. Use when adding metrics, tracing, or monitoring to Elixir code, attaching handlers to telemetry events, implementing span events, or integrating with Phoenix/Ecto telemetry.

iksnerd/code-nexus1 installsMITSynced Aug 26

Works with

Claude CodeCursorCodex CLIGitHub CopilotGemini CLI
---
name: elixir-telemetry
description: Telemetry instrumentation and observability patterns for Elixir. Use when adding metrics, tracing, or monitoring to Elixir code, attaching handlers to telemetry events, implementing span events, or integrating with Phoenix/Ecto telemetry.
license: MIT
---

# Telemetry Instrumentation

## Core Concept

Telemetry is a decoupled instrumentation system. Libraries emit events; applications attach handlers. No tight coupling between producers and consumers.

- **Event name**: list of atoms `[:app, :component, :event]`
- **Measurements**: numeric values map `%{duration: 1200, count: 5}`
- **Metadata**: contextual map `%{file: "foo.ex", query: "SELECT..."}`

## Emitting Events

### Point Event

```elixir
start = System.monotonic_time()
result = do_work(file)
duration = System.monotonic_time() - start

:telemetry.execute(
  [:myapp, :pipeline, :file_parsed],
  %{duration: System.convert_time_unit(duration, :native, :millisecond),
    chunk_count: length(result.chunks)},
  %{file: file, status: :ok}
)
```

### Error Event

```elixir
:telemetry.execute(
  [:myapp, :pipeline, :file_error],
  %{count: 1},
  %{file: file, reason: reason}
)
```

### Span Events (start/stop/exception)

Use `:telemetry.span/3` for automatic start + stop timing:

```elixir
:telemetry.span(
  [:myapp, :qdrant, :upsert],
  %{batch_size: length(points)},
  fn ->
    result = Qdrant.upsert(points)
    {result, %{point_count: length(points)}}
  end
)
```

This emits `[:myapp, :qdrant, :upsert, :start]`, `[:myapp, :qdrant, :upsert, :stop]`, and on exception `[:myapp, :qdrant, :upsert, :exception]` automatically.

## Attaching Handlers

```elixir
# In application.ex or a telemetry module
:telemetry.attach(
  "myapp-pipeline-handler",           # unique handler id
  [:myapp, :pipeline, :file_parsed],  # event name
  &MyApp.TelemetryHandler.handle_event/4,
  nil                                 # config passed to handler
)

# Attach multiple events at once
:telemetry.attach_many(
  "myapp-qdrant-handler",
  [
    [:myapp, :qdrant, :upsert],
    [:myapp, :qdrant, :upsert_error],
    [:myapp, :qdrant, :hybrid_search],
  ],
  &MyApp.TelemetryHandler.handle_event/4,
  nil
)
```

## Handler Implementation

```elixir
defmodule MyApp.TelemetryHandler do
  def handle_event([:myapp, :pipeline, :file_parsed], measurements, metadata, _config) do
    Logger.info("Parsed #{metadata.file} in #{measurements.duration}ms " <>
                "(#{measurements.chunk_count} chunks)")
    # Report to StatsD, Prometheus, etc.
  end

  def handle_event([:myapp, :pipeline, :file_error], _measurements, metadata, _config) do
    Logger.warning("Parse error in #{metadata.file}: #{inspect(metadata.reason)}")
  end
end
```

**Critical**: Handler callbacks execute **synchronously** in the process that emitted the event. Never do blocking I/O in a handler — send to a separate process instead:

```elixir
def handle_event(event, measurements, metadata, _config) do
  # Good — async dispatch
  send(MyApp.MetricsAggregator, {:telemetry, event, measurements, metadata})
end
```

## Timing with monotonic_time

Always use `System.monotonic_time/0` for duration measurements (not `DateTime.utc_now/0`):

```elixir
start = System.monotonic_time()
result = expensive_operation()
duration_ms = System.convert_time_unit(
  System.monotonic_time() - start,
  :native,
  :millisecond
)
```

## ElixirNexus Telemetry Events

| Event | Measurements | Metadata |
|---|---|---|
| `[:nexus, :pipeline, :file_parsed]` | `duration_ms`, `chunk_count` | `file` |
| `[:nexus, :pipeline, :file_error]` | `count` | `file`, `reason` |
| `[:nexus, :search, :query]` | `duration_ms`, `result_count` | `query` |
| `[:nexus, :qdrant, :upsert]` | `duration_ms`, `point_count` | — |
| `[:nexus, :qdrant, :upsert_error]` | `batch_size` | `reason` |
| `[:nexus, :qdrant, :hybrid_search]` | `duration_ms`, `limit` | — |
| `[:nexus, :embed_and_store]` | `duration_ms`, `chunk_count` | — |

## Common Mistakes

- Don't block in telemetry handlers — offload to async process
- Don't use wall-clock time for durations — use `System.monotonic_time/0`
- Handler IDs must be globally unique — use namespaced strings like `"myapp-component-action"`
- Detach handlers on teardown to avoid memory leaks in tests: `:telemetry.detach("handler-id")`

More Observability skills

google-agents-cli-observability

google/agents-cli

>

106.1k

azure-observability

microsoft/azure-skills

Azure Observability Services including Azure Monitor, Application Insights, Log Analytics, Alerts, and Workbooks. Provides metrics, APM, distributed tracing, KQL queries, and interactive reports. USE FOR: Azure Monitor, Application Insights, Log Analytics, Alerts, Workbooks, metrics, APM, distributed tracing, KQL queries, interactive reports, observability, monitoring dashboards. DO NOT USE FOR: instrumenting apps with App Insights SDK (use appinsights-instrumentation), querying Kusto/ADX clusters (use azure-kusto), cost analysis (use azure-cost-optimization).

98.1k

social

coreyhaines31/marketingskills

When the user wants help creating, scheduling, or optimizing social media content for LinkedIn, Twitter/X, Instagram, TikTok, Facebook, or other platforms, or wants to do social listening and engagement triage. Also use when the user mentions 'LinkedIn post,' 'Twitter thread,' 'social media,' 'content calendar,' 'social scheduling,' 'engagement,' 'viral content,' 'what should I post,' 'repurpose this content,' 'tweet ideas,' 'LinkedIn carousel,' 'social media strategy,' 'grow my following,' 'TikTok video,' 'Reels,' 'Shorts,' 'video script,' 'video hook,' 'short-form video,' 'create a reel,' 'social listening,' 'brand mentions,' 'competitor monitoring,' 'top posts to comment on,' 'find people asking for,' 'carousel,' 'slide-by-slide,' or 'document post.' Use this for social media content creation, repurposing, scheduling, short-form video scripting, and social listening. For broader content strategy, see content-strategy. For paid ads, see ad-creative. For earned media, see public-relations.

55.7k

← All Observability skills

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY