Current section
Files
Jump to
Current section
Files
lib/phoenix/session_process/telemetry.ex
defmodule Phoenix.SessionProcess.Telemetry do
@moduledoc """
Telemetry events for Phoenix.SessionProcess.
This module provides telemetry events that can be used to monitor
session lifecycle, performance, and errors.
## Events
The following telemetry events are emitted:
### Session Lifecycle
- `[:phoenix, :session_process, :start]` - When a session starts
- `[:phoenix, :session_process, :stop]` - When a session stops
- `[:phoenix, :session_process, :start_error]` - When session start fails
### Communication
- `[:phoenix, :session_process, :call]` - When a call is made to a session
- `[:phoenix, :session_process, :cast]` - When a cast is made to a session
- `[:phoenix, :session_process, :communication_error]` - When communication fails
### Cleanup
- `[:phoenix, :session_process, :cleanup]` - When a session is cleaned up
- `[:phoenix, :session_process, :cleanup_error]` - When cleanup fails
All events include the following metadata:
- `session_id` - The session ID
- `module` - The session module
- `pid` - The process PID (when applicable)
- `measurements` - Performance measurements
"""
@doc """
Emits a telemetry event for session start.
"""
@spec emit_session_start(String.t(), atom(), pid(), keyword()) :: :ok
def emit_session_start(session_id, module, pid, measurements \\ []) do
:telemetry.execute(
[:phoenix, :session_process, :start],
Map.new(measurements),
%{session_id: session_id, module: module, pid: pid}
)
end
@doc """
Emits a telemetry event for session stop.
"""
@spec emit_session_stop(String.t(), atom(), pid(), keyword()) :: :ok
def emit_session_stop(session_id, module, pid, measurements \\ []) do
:telemetry.execute(
[:phoenix, :session_process, :stop],
Map.new(measurements),
%{session_id: session_id, module: module, pid: pid}
)
end
@doc """
Emits a telemetry event for session start error.
"""
@spec emit_session_start_error(String.t(), atom(), any(), keyword()) :: :ok
def emit_session_start_error(session_id, module, reason, measurements \\ []) do
:telemetry.execute(
[:phoenix, :session_process, :start_error],
Map.new(measurements),
%{session_id: session_id, module: module, reason: reason}
)
end
@doc """
Emits a telemetry event for session call.
"""
@spec emit_session_call(String.t(), atom(), pid(), any(), keyword()) :: :ok
def emit_session_call(session_id, module, pid, message, measurements \\ []) do
:telemetry.execute(
[:phoenix, :session_process, :call],
Map.new(measurements),
%{session_id: session_id, module: module, pid: pid, message: message}
)
end
@doc """
Emits a telemetry event for session cast.
"""
@spec emit_session_cast(String.t(), atom(), pid(), any(), keyword()) :: :ok
def emit_session_cast(session_id, module, pid, message, measurements \\ []) do
:telemetry.execute(
[:phoenix, :session_process, :cast],
Map.new(measurements),
%{session_id: session_id, module: module, pid: pid, message: message}
)
end
@doc """
Emits a telemetry event for communication error.
"""
@spec emit_communication_error(String.t(), atom(), any(), any(), keyword()) :: :ok
def emit_communication_error(session_id, module, operation, reason, measurements \\ []) do
:telemetry.execute(
[:phoenix, :session_process, :communication_error],
Map.new(measurements),
%{session_id: session_id, module: module, operation: operation, reason: reason}
)
end
@doc """
Emits a telemetry event for session cleanup.
"""
@spec emit_session_cleanup(String.t(), atom(), pid(), keyword()) :: :ok
def emit_session_cleanup(session_id, module, pid, measurements \\ []) do
:telemetry.execute(
[:phoenix, :session_process, :cleanup],
Map.new(measurements),
%{session_id: session_id, module: module, pid: pid}
)
end
@doc """
Emits a telemetry event for session cleanup error.
"""
@spec emit_session_cleanup_error(String.t(), atom(), any(), keyword()) :: :ok
def emit_session_cleanup_error(session_id, module, reason, measurements \\ []) do
:telemetry.execute(
[:phoenix, :session_process, :cleanup_error],
Map.new(measurements),
%{session_id: session_id, module: module, reason: reason}
)
end
@doc """
Measures the execution time of a function and emits telemetry events.
"""
@spec measure(String.t(), atom(), fun()) :: {:ok, any()} | {:error, any()}
def measure(session_id, operation, fun) do
start_time = System.monotonic_time()
try do
result = fun.()
end_time = System.monotonic_time()
duration = end_time - start_time
:telemetry.execute(
[:phoenix, :session_process, operation],
%{duration: duration},
%{session_id: session_id}
)
result
rescue
error ->
end_time = System.monotonic_time()
duration = end_time - start_time
:telemetry.execute(
[:phoenix, :session_process, :error],
%{duration: duration},
%{session_id: session_id, operation: operation, error: error}
)
reraise error, __STACKTRACE__
catch
kind, reason ->
end_time = System.monotonic_time()
duration = end_time - start_time
:telemetry.execute(
[:phoenix, :session_process, :error],
%{duration: duration},
%{session_id: session_id, operation: operation, kind: kind, reason: reason}
)
:erlang.raise(kind, reason, __STACKTRACE__)
end
end
end