Skip to content

Commit f6c57f0

Browse files
committed
Adding Graph with telemetry
1 parent 73515e9 commit f6c57f0

File tree

7 files changed

+236
-81
lines changed

7 files changed

+236
-81
lines changed

lib/observer_web/apps/port.ex

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ defmodule ObserverWeb.Apps.Port do
55

66
alias ObserverWeb.Rpc
77

8+
@type t :: %{
9+
name: charlist() | String.t(),
10+
id: non_neg_integer(),
11+
connected: pid(),
12+
os_pid: non_neg_integer() | :undefined
13+
}
14+
15+
defstruct [:name, :id, :connected, :os_pid]
16+
817
@doc """
918
Return port information
1019
@@ -16,14 +25,13 @@ defmodule ObserverWeb.Apps.Port do
1625
...> assert :undefined = Port.info(nil)
1726
...> assert :undefined = Port.info("")
1827
"""
19-
@spec info(atom(), port()) ::
20-
:undefined | %{connected: any(), id: any(), name: any(), os_pid: any()}
28+
@spec info(atom(), port()) :: :undefined | __MODULE__.t()
2129
def info(node \\ Node.self(), port)
2230

2331
def info(node, port) when is_port(port) do
2432
case Rpc.call(node, :erlang, :port_info, [port], :infinity) do
2533
data when is_list(data) ->
26-
%{
34+
%__MODULE__{
2735
name: Keyword.get(data, :name, 0),
2836
id: Keyword.get(data, :id, 0),
2937
connected: Keyword.get(data, :connected, 0),

lib/observer_web/apps/process.ex

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,54 @@ defmodule ObserverWeb.Apps.Process do
1111

1212
@default_get_state_timeout 100
1313

14+
@type t :: %{
15+
pid: pid(),
16+
registered_name: atom() | nil,
17+
priority: :low | :normal | :high | :max,
18+
trap_exit: boolean(),
19+
message_queue_len: non_neg_integer(),
20+
error_handler: module() | :none,
21+
relations: %{
22+
group_leader: pid() | nil,
23+
ancestors: [pid()],
24+
links: [pid()] | nil,
25+
monitored_by: [pid()] | nil,
26+
monitors: [pid() | {module(), term()}] | nil
27+
},
28+
memory: %{
29+
total: non_neg_integer(),
30+
stack_and_heap: non_neg_integer(),
31+
heap_size: non_neg_integer(),
32+
stack_size: non_neg_integer(),
33+
gc_min_heap_size: non_neg_integer(),
34+
gc_full_sweep_after: non_neg_integer()
35+
},
36+
meta: %{
37+
init: String.t(),
38+
current: String.t(),
39+
status: :running | :waiting | :exiting | :garbage_collecting | :suspended | :runnable,
40+
class: :supervisor | :application | :unknown | atom()
41+
},
42+
state: String.t(),
43+
dictionary: keyword() | nil,
44+
phx_lv_socket: Phoenix.LiveView.Socket.t() | nil
45+
}
46+
47+
defstruct [
48+
:pid,
49+
:registered_name,
50+
:priority,
51+
:trap_exit,
52+
:message_queue_len,
53+
:error_handler,
54+
:relations,
55+
:memory,
56+
:meta,
57+
:state,
58+
:dictionary,
59+
:phx_lv_socket
60+
]
61+
1462
@process_full [
1563
:registered_name,
1664
:priority,
@@ -36,7 +84,7 @@ defmodule ObserverWeb.Apps.Process do
3684
@doc """
3785
Creates a complete overview of process stats based on the given `pid`.
3886
"""
39-
@spec info(pid :: pid(), timeout :: non_neg_integer()) :: :undefined | map
87+
@spec info(pid :: pid(), timeout :: non_neg_integer()) :: :undefined | __MODULE__.t()
4088
def info(pid, timeout \\ @default_get_state_timeout) do
4189
process_info(pid, @process_full, &structure_full/3, timeout)
4290
end
@@ -119,7 +167,7 @@ defmodule ObserverWeb.Apps.Process do
119167
end
120168
end
121169

122-
%{
170+
%__MODULE__{
123171
pid: pid,
124172
registered_name: Keyword.get(data, :registered_name, nil),
125173
priority: Keyword.get(data, :priority, :normal),

lib/observer_web/monitor.ex

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ defmodule ObserverWeb.Monitor do
1212
@doc """
1313
Starts monitoring a process's memory usage
1414
"""
15-
@spec start_process_monitor(pid :: pid()) :: :ok
15+
@spec start_process_monitor(pid :: pid()) :: {:ok, ObserverWeb.Monitor.Process.t()}
1616
def start_process_monitor(pid), do: Process.start_process_monitor(pid)
1717

1818
@doc """
@@ -24,8 +24,9 @@ defmodule ObserverWeb.Monitor do
2424
@doc """
2525
Checks if memory monitoring is enabled for a process
2626
"""
27-
@spec process_enabled?(pid :: pid()) :: boolean()
28-
def process_enabled?(pid), do: Process.enabled?(pid)
27+
@spec process_info(pid :: pid()) ::
28+
{:ok, ObserverWeb.Monitor.Process.t()} | {:error, :not_found | :rescued}
29+
def process_info(pid), do: Process.process_info(pid)
2930

3031
### ==========================================================================
3132
### Private functions

lib/observer_web/monitor/process.ex

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,17 @@ defmodule ObserverWeb.Monitor.Process do
4141
end
4242

4343
@impl true
44-
def handle_call({:enabled?, pid}, _from, monitored_processes) do
44+
def handle_call({:process_info, pid}, _from, monitored_processes) do
4545
case monitored_processes[pid] do
4646
nil ->
47-
{:reply, false, monitored_processes}
47+
{:reply, {:error, :not_found}, monitored_processes}
4848

49-
_atomized_pid ->
50-
{:reply, true, monitored_processes}
49+
process ->
50+
{:reply, {:ok, process}, monitored_processes}
5151
end
5252
end
5353

54-
@impl true
55-
def handle_cast({:attach_process_pid, pid}, monitored_processes) do
54+
def handle_call({:attach_process_pid, pid}, _from, monitored_processes) do
5655
case monitored_processes[pid] do
5756
nil ->
5857
process = pid_to_struct(pid)
@@ -64,18 +63,18 @@ defmodule ObserverWeb.Monitor.Process do
6463
{[process.metric_summary], nil, Node.self()}
6564
)
6665

67-
{:noreply, Map.put(monitored_processes, pid, process)}
66+
{:reply, {:ok, process}, Map.put(monitored_processes, pid, process)}
6867

69-
_atomized_pid ->
68+
process ->
7069
# Already in the list of monitored processes
71-
{:noreply, monitored_processes}
70+
{:reply, {:ok, process}, monitored_processes}
7271
end
7372
end
7473

75-
def handle_cast({:detach_process_pid, pid}, monitored_processes) do
74+
def handle_call({:detach_process_pid, pid}, _from, monitored_processes) do
7675
case monitored_processes[pid] do
7776
nil ->
78-
{:noreply, monitored_processes}
77+
{:reply, :ok, monitored_processes}
7978

8079
process ->
8180
# Add a gap in the chart to indicate that data sending was disabled
@@ -88,7 +87,7 @@ defmodule ObserverWeb.Monitor.Process do
8887
# Detach the telemetry handler
8988
:telemetry.detach({__MODULE__, process.event, self()})
9089

91-
{:noreply, Map.drop(monitored_processes, [pid])}
90+
{:reply, :ok, Map.drop(monitored_processes, [pid])}
9291
end
9392
end
9493

@@ -121,22 +120,34 @@ defmodule ObserverWeb.Monitor.Process do
121120
### Public APIs
122121
### ==========================================================================
123122

124-
@spec start_process_monitor(pid :: pid()) :: :ok
123+
@spec start_process_monitor(pid :: pid()) :: {:ok, __MODULE__.t()}
125124
def start_process_monitor(pid) do
126125
target_node = node(pid)
127-
GenServer.cast({__MODULE__, target_node}, {:attach_process_pid, pid})
126+
GenServer.call({__MODULE__, target_node}, {:attach_process_pid, pid})
128127
end
129128

130129
@spec stop_process_monitor(pid :: pid()) :: :ok
131130
def stop_process_monitor(pid) do
132131
target_node = node(pid)
133-
GenServer.cast({__MODULE__, target_node}, {:detach_process_pid, pid})
132+
133+
try do
134+
GenServer.call({__MODULE__, target_node}, {:detach_process_pid, pid})
135+
catch
136+
_, _ ->
137+
:ok
138+
end
134139
end
135140

136-
@spec enabled?(pid :: pid()) :: boolean()
137-
def enabled?(pid) do
141+
@spec process_info(pid :: pid()) :: {:ok, map} | {:error, :not_found | :rescued}
142+
def process_info(pid) do
138143
target_node = node(pid)
139-
GenServer.call({__MODULE__, target_node}, {:enabled?, pid})
144+
145+
try do
146+
GenServer.call({__MODULE__, target_node}, {:process_info, pid})
147+
catch
148+
_, _ ->
149+
{:error, :rescued}
150+
end
140151
end
141152

142153
### ==========================================================================

lib/web/pages/apps/identifier.ex

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
defmodule Observer.Web.Apps.Identifier do
2+
@moduledoc """
3+
This module provides Identifier Structure
4+
"""
5+
6+
# NOTE: Debouncing for reading the selected process
7+
@tooltip_debouncing 50
8+
9+
@type t :: %__MODULE__{
10+
info: ObserverWeb.Apps.Process.t() | ObserverWeb.Apps.Port.t() | nil,
11+
id_string: String.t() | nil,
12+
type: nil,
13+
debouncing: non_neg_integer(),
14+
node: atom() | nil,
15+
metric: String.t() | nil
16+
}
17+
18+
defstruct info: nil,
19+
id_string: nil,
20+
type: nil,
21+
debouncing: @tooltip_debouncing,
22+
node: nil,
23+
metric: nil
24+
end

0 commit comments

Comments
 (0)