Skip to content

Commit 004d27c

Browse files
Merge pull request #27 from cheerfulstoic/debug-logs
feat: Add debug logging option
2 parents e4b196c + bba671c commit 004d27c

File tree

8 files changed

+262
-16
lines changed

8 files changed

+262
-16
lines changed

guides/introduction/Debugging.md

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
It is possible to get debug logs from EctoWatch by setting the `debug?` option, either globally:
2+
3+
```elixir
4+
# setup
5+
{EctoWatch,
6+
repo: MyApp.Repo,
7+
pub_sub: MyApp.PubSub,
8+
debug?: true
9+
watchers: [
10+
# ...
11+
{Comment, :deleted, extra_columns: [:post_id]},
12+
# ...
13+
]}
14+
```
15+
16+
Or on specific watchers:
17+
18+
```elixir
19+
# setup
20+
{EctoWatch,
21+
repo: MyApp.Repo,
22+
pub_sub: MyApp.PubSub,
23+
watchers: [
24+
# ...
25+
{Comment, :deleted, debug?: true, extra_columns: [:post_id]},
26+
# ...
27+
]}
28+
```
29+
30+
Debug logs will be written to the `:debug` log level. They will output when:
31+
32+
* A watcher server is starting up
33+
* A watcher server receives a message from PostgreSQL via a `pg_notify` channel
34+
* A watcher server broadcasts a message to `Phoenix.PubSub`
35+
* A process subscribes to a watcher
36+
37+
All debug logs have a PID associated as well as the identifier for the watcher server (either the label or a `{ecto_schema, update_type}` tuple).

lib/ecto_watch.ex

+7-1
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,10 @@ defmodule EctoWatch do
147147
validate_ecto_watch_running!()
148148

149149
with :ok <- validate_identifier(watcher_identifier),
150-
{:ok, {pub_sub_mod, channel_name}} <-
150+
{:ok, {pub_sub_mod, channel_name, debug?}} <-
151151
WatcherServer.pub_sub_subscription_details(watcher_identifier, id) do
152+
if(debug?, do: debug_log(watcher_identifier, "Subscribing to watcher"))
153+
152154
Phoenix.PubSub.subscribe(pub_sub_mod, channel_name)
153155
else
154156
{:error, error} ->
@@ -291,4 +293,8 @@ defmodule EctoWatch do
291293
|> Enum.filter(fn {_, values} -> length(values) >= 2 end)
292294
|> Enum.map(fn {_, [value | _]} -> value end)
293295
end
296+
297+
defp debug_log(watcher_identifier, message) do
298+
EctoWatch.Helpers.debug_log(watcher_identifier, message)
299+
end
294300
end

lib/ecto_watch/helpers.ex

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
defmodule EctoWatch.Helpers do
22
@moduledoc false
33

4+
require Logger
5+
46
def label(schema_mod_or_label) do
57
if ecto_schema_mod?(schema_mod_or_label) do
68
module_to_label(schema_mod_or_label)
@@ -39,4 +41,8 @@ defmodule EctoWatch.Helpers do
3941
def validate_list(_, _) do
4042
{:error, "should be a list"}
4143
end
44+
45+
def debug_log(watcher_identifier, message) do
46+
Logger.debug("EctoWatch | #{inspect(watcher_identifier)} | #{inspect(self())} | #{message}")
47+
end
4248
end

lib/ecto_watch/options.ex

+10-2
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ defmodule EctoWatch.Options do
33

44
alias EctoWatch.Options.WatcherOptions
55

6-
defstruct [:repo_mod, :pub_sub_mod, :watchers]
6+
defstruct [:repo_mod, :pub_sub_mod, :watchers, :debug?]
77

88
def new(opts) do
99
%__MODULE__{
1010
repo_mod: opts[:repo],
1111
pub_sub_mod: opts[:pub_sub],
12-
watchers: Enum.map(opts[:watchers], &WatcherOptions.new/1)
12+
watchers:
13+
Enum.map(opts[:watchers], fn watcher_opts ->
14+
WatcherOptions.new(watcher_opts, opts[:debug?])
15+
end)
1316
}
1417
end
1518

@@ -26,6 +29,11 @@ defmodule EctoWatch.Options do
2629
watchers: [
2730
type: {:custom, WatcherOptions, :validate_list, []},
2831
required: true
32+
],
33+
debug?: [
34+
type: :boolean,
35+
required: false,
36+
default: false
2937
]
3038
]
3139

lib/ecto_watch/options/watcher_options.ex

+11-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ defmodule EctoWatch.Options.WatcherOptions do
33

44
alias EctoWatch.Helpers
55

6-
defstruct [:schema_definition, :update_type, :label, :trigger_columns, :extra_columns]
6+
defstruct [:schema_definition, :update_type, :label, :trigger_columns, :extra_columns, :debug?]
77

88
def validate_list(list) do
99
Helpers.validate_list(list, &validate/1)
@@ -157,6 +157,11 @@ defmodule EctoWatch.Options.WatcherOptions do
157157
type: {:custom, __MODULE__, :validate_columns, [schema_definition]},
158158
required: false,
159159
default: []
160+
],
161+
debug?: [
162+
type: :boolean,
163+
required: false,
164+
default: false
160165
]
161166
]
162167

@@ -198,19 +203,20 @@ defmodule EctoWatch.Options.WatcherOptions do
198203
end)
199204
end
200205

201-
def new({schema_definition, update_type}) do
202-
new({schema_definition, update_type, []})
206+
def new({schema_definition, update_type}, debug?) do
207+
new({schema_definition, update_type, []}, debug?)
203208
end
204209

205-
def new({schema_definition, update_type, opts}) do
210+
def new({schema_definition, update_type, opts}, debug?) do
206211
schema_definition = SchemaDefinition.new(schema_definition)
207212

208213
%__MODULE__{
209214
schema_definition: schema_definition,
210215
update_type: update_type,
211216
label: opts[:label],
212217
trigger_columns: opts[:trigger_columns] || [],
213-
extra_columns: opts[:extra_columns] || []
218+
extra_columns: opts[:extra_columns] || [],
219+
debug?: debug? || opts[:debug?]
214220
}
215221
end
216222
end

lib/ecto_watch/watcher_server.ex

+30-6
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ defmodule EctoWatch.WatcherServer do
4545

4646
@impl true
4747
def init({repo_mod, pub_sub_mod, options}) do
48+
debug_log(options, "Starting server")
49+
4850
unique_label = "#{unique_label(options)}"
4951

5052
update_keyword =
@@ -152,7 +154,7 @@ defmodule EctoWatch.WatcherServer do
152154
"#{state.unique_label}"
153155
end
154156

155-
{:ok, {state.pub_sub_mod, channel_name}}
157+
{:ok, {state.pub_sub_mod, channel_name, state.options.debug?}}
156158
end
157159

158160
{:reply, result, state}
@@ -182,6 +184,11 @@ defmodule EctoWatch.WatcherServer do
182184

183185
@impl true
184186
def handle_info({:notification, _pid, _ref, channel_name, payload}, state) do
187+
debug_log(
188+
state.options,
189+
"Received Postgrex notification on channel `#{channel_name}`: #{payload}"
190+
)
191+
185192
details = watcher_details(state)
186193

187194
if channel_name != details.notify_channel do
@@ -210,6 +217,11 @@ defmodule EctoWatch.WatcherServer do
210217
returned_values,
211218
state.identifier_columns
212219
) do
220+
debug_log(
221+
state.options,
222+
"Broadcasting to Phoenix PubSub topic `#{topic}`: #{inspect(message)}"
223+
)
224+
213225
Phoenix.PubSub.broadcast(state.pub_sub_mod, topic, message)
214226
end
215227

@@ -244,11 +256,9 @@ defmodule EctoWatch.WatcherServer do
244256
# that can be used as the watcher process name, trigger name, trigger function name,
245257
# and Phoenix.PubSub channel name.
246258
defp unique_label(%WatcherOptions{} = options) do
247-
if options.label do
248-
unique_label(options.label)
249-
else
250-
unique_label({options.schema_definition.label, options.update_type})
251-
end
259+
options
260+
|> identifier()
261+
|> unique_label()
252262
end
253263

254264
defp unique_label({schema_mod, update_type}) do
@@ -258,4 +268,18 @@ defmodule EctoWatch.WatcherServer do
258268
defp unique_label(label) do
259269
:"ew_for_#{Helpers.label(label)}"
260270
end
271+
272+
defp identifier(%WatcherOptions{} = options) do
273+
if options.label do
274+
options.label
275+
else
276+
{options.schema_definition.label, options.update_type}
277+
end
278+
end
279+
280+
defp debug_log(%{debug?: debug_value} = options, message) do
281+
if debug_value do
282+
Helpers.debug_log(identifier(options), message)
283+
end
284+
end
261285
end

mix.exs

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ defmodule EctoWatch.MixProject do
6969
"guides/introduction/Tracking columns and using labels.md",
7070
"guides/introduction/Getting additional values.md",
7171
"guides/introduction/Watching without a schema.md",
72+
"guides/introduction/Debugging.md",
7273
"guides/introduction/Notes.md",
7374
"guides/howtos/Upgrading Versions.md",
7475
"guides/other/Potental TODOs.md",

0 commit comments

Comments
 (0)