Packages
snakepit
0.6.7
0.13.0
0.12.0
0.11.1
0.11.0
0.10.1
0.10.0
0.9.1
0.9.0
0.8.9
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.1
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
High-performance pooler and session manager for external language integrations. Supports Python, Node.js, Ruby, and more with gRPC streaming, session management, and production-ready process cleanup.
Current section
Files
Jump to
Current section
Files
lib/snakepit/telemetry/naming.ex
defmodule Snakepit.Telemetry.Naming do
@moduledoc """
Event catalog and naming validation for Snakepit telemetry.
This module ensures atom safety by maintaining a curated catalog of all
valid telemetry events and measurement keys. Python-originated events
must pass through this module to prevent arbitrary atom creation.
"""
# Layer 1: Infrastructure Events (Elixir-originated)
@pool_events [
:initialized,
:status,
:queue_enqueued,
:queue_dequeued,
:queue_timeout,
:worker_spawn_started,
:worker_spawned,
:worker_spawn_failed,
:worker_terminated,
:worker_restarted
]
@session_events [
:created,
:destroyed,
:affinity_assigned,
:affinity_broken
]
# Layer 2: Python Execution Events (Python-originated, folded by Elixir)
@python_events [
:call_start,
:call_stop,
:call_exception,
:memory_sampled,
:cpu_sampled,
:gc_completed,
:error_occurred
]
# Layer 3: gRPC Bridge Events (Elixir-originated)
@grpc_events [
:call_start,
:call_stop,
:call_exception,
:stream_opened,
:stream_message,
:stream_closed,
:connection_established,
:connection_lost,
:connection_reconnected
]
# Valid measurement keys (atom-safe)
@measurement_keys [
:duration,
:system_time,
:queue_depth,
:queue_time,
:available_workers,
:busy_workers,
:total_workers,
:worker_count,
:lifetime,
:total_commands,
:command_count,
:downtime,
:restart_count,
:retry_count,
:request_size,
:response_size,
:message_size,
:sequence_number,
:message_count,
:network_time,
:uptime,
:call_count,
:affinity_duration,
:commands_with_affinity,
:rss_bytes,
:vms_bytes,
:cpu_percent,
:collected,
:generation,
:latency_ms,
:count,
:python_pid
]
@doc """
Convert Python event parts to a valid Elixir telemetry event name.
Returns `{:ok, event_name}` if the parts map to a known event,
`{:error, reason}` otherwise.
## Examples
iex> Snakepit.Telemetry.Naming.from_parts(["python", "call", "start"])
{:ok, [:snakepit, :python, :call, :start]}
iex> Snakepit.Telemetry.Naming.from_parts(["unknown", "event"])
{:error, :unknown_event}
"""
def from_parts(parts) when is_list(parts) do
case parts do
# Python events
["python", "call", "start"] ->
{:ok, [:snakepit, :python, :call, :start]}
["python", "call", "stop"] ->
{:ok, [:snakepit, :python, :call, :stop]}
["python", "call", "exception"] ->
{:ok, [:snakepit, :python, :call, :exception]}
["python", "memory", "sampled"] ->
{:ok, [:snakepit, :python, :memory, :sampled]}
["python", "cpu", "sampled"] ->
{:ok, [:snakepit, :python, :cpu, :sampled]}
["python", "gc", "completed"] ->
{:ok, [:snakepit, :python, :gc, :completed]}
["python", "error", "occurred"] ->
{:ok, [:snakepit, :python, :error, :occurred]}
# Alternative format with dots
["tool", "execution", action] when action in ["start", "stop", "exception"] ->
{:ok, [:snakepit, :python, :tool, :execution, String.to_existing_atom(action)]}
["tool", "result_size"] ->
{:ok, [:snakepit, :python, :tool, :result_size]}
_ ->
{:error, :unknown_event}
end
rescue
ArgumentError -> {:error, :invalid_atom}
end
@doc """
Validate a measurement key and convert to atom if it's in the allowlist.
## Examples
iex> Snakepit.Telemetry.Naming.measurement_key("duration")
{:ok, :duration}
iex> Snakepit.Telemetry.Naming.measurement_key("unknown_key")
{:error, :unknown_measurement_key}
"""
def measurement_key(key) when is_binary(key) do
atom_key = String.to_existing_atom(key)
if atom_key in @measurement_keys do
{:ok, atom_key}
else
{:error, :unknown_measurement_key}
end
rescue
ArgumentError -> {:error, :invalid_atom}
end
def measurement_key(key) when is_atom(key) do
if key in @measurement_keys do
{:ok, key}
else
{:error, :unknown_measurement_key}
end
end
@doc """
Get all valid pool events.
"""
def pool_events, do: @pool_events
@doc """
Get all valid session events.
"""
def session_events, do: @session_events
@doc """
Get all valid Python events.
"""
def python_events, do: @python_events
@doc """
Get all valid gRPC events.
"""
def grpc_events, do: @grpc_events
@doc """
Get all valid measurement keys.
"""
def measurement_keys, do: @measurement_keys
@doc """
Build an event name from components.
## Examples
iex> Snakepit.Telemetry.Naming.event(:pool, :worker, :spawned)
[:snakepit, :pool, :worker, :spawned]
"""
def event(component, resource, action) do
[:snakepit, component, resource, action]
end
@doc """
Build a pool event name.
"""
def pool_event(action) when action in @pool_events do
case action do
:initialized -> [:snakepit, :pool, :initialized]
:status -> [:snakepit, :pool, :status]
:queue_enqueued -> [:snakepit, :pool, :queue, :enqueued]
:queue_dequeued -> [:snakepit, :pool, :queue, :dequeued]
:queue_timeout -> [:snakepit, :pool, :queue, :timeout]
:worker_spawn_started -> [:snakepit, :pool, :worker, :spawn_started]
:worker_spawned -> [:snakepit, :pool, :worker, :spawned]
:worker_spawn_failed -> [:snakepit, :pool, :worker, :spawn_failed]
:worker_terminated -> [:snakepit, :pool, :worker, :terminated]
:worker_restarted -> [:snakepit, :pool, :worker, :restarted]
end
end
@doc """
Build a session event name.
"""
def session_event(action) when action in @session_events do
case action do
:created -> [:snakepit, :session, :created]
:destroyed -> [:snakepit, :session, :destroyed]
:affinity_assigned -> [:snakepit, :session, :affinity, :assigned]
:affinity_broken -> [:snakepit, :session, :affinity, :broken]
end
end
@doc """
Build a Python event name.
"""
def python_event(action) when action in @python_events do
case action do
:call_start -> [:snakepit, :python, :call, :start]
:call_stop -> [:snakepit, :python, :call, :stop]
:call_exception -> [:snakepit, :python, :call, :exception]
:memory_sampled -> [:snakepit, :python, :memory, :sampled]
:cpu_sampled -> [:snakepit, :python, :cpu, :sampled]
:gc_completed -> [:snakepit, :python, :gc, :completed]
:error_occurred -> [:snakepit, :python, :error, :occurred]
end
end
@doc """
Build a gRPC event name.
"""
def grpc_event(resource, action) when action in @grpc_events do
[:snakepit, :grpc, resource, action]
end
end