Skip to content

Commit 589ca18

Browse files
committed
Add GenServer.format_status/1 callback
1 parent a019425 commit 589ca18

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

lib/elixir/lib/gen_server.ex

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,38 @@ defmodule GenServer do
758758
| {:error, reason :: term}
759759
when old_vsn: term | {:down, term}
760760

761+
@doc """
762+
This function is called by a `GenServer` process in the following situations:
763+
764+
* `sys:get_status/1,2` is invoked to get the `GenServer` status.
765+
* The `GenServer` process terminates abnormally and logs an error.
766+
767+
This callback is used to limit the status of the process returned by
768+
`sys:get_status/1,2` or sent to logger.
769+
770+
The callback gets a map `status` describing the current status and shall return
771+
a map `new_status` with the same keys, but it may transform some values.
772+
773+
Two possible use cases for this callback is to remove sensitive information
774+
from the state to prevent it from being printed in log files, or to compact
775+
large irrelevant status items that would only clutter the logs.
776+
777+
## Example
778+
779+
@impl GenServer
780+
def format_status(status) do
781+
Map.new(status, fn
782+
{:state, state} -> {:state, Map.delete(state, :private_key)}
783+
{:message, {:password, _} -> {:message, {:password, "redacted"}}
784+
key_value -> key_value
785+
end)
786+
end
787+
788+
"""
789+
@doc since: "1.17.0"
790+
@callback format_status(status :: :gen_server.format_status()) ::
791+
new_status :: :gen_server.format_status()
792+
761793
@doc """
762794
Invoked in some cases to retrieve a formatted version of the `GenServer` status:
763795
@@ -775,6 +807,7 @@ defmodule GenServer do
775807
list of `{key, value}` tuples representing the current process dictionary of
776808
the `GenServer` and `state` is the current state of the `GenServer`.
777809
"""
810+
@doc deprecated: "Use format_status/1 callback instead"
778811
@callback format_status(reason, pdict_and_state :: list) :: term
779812
when reason: :normal | :terminate
780813

@@ -783,6 +816,7 @@ defmodule GenServer do
783816
handle_info: 2,
784817
handle_cast: 2,
785818
handle_call: 3,
819+
format_status: 1,
786820
format_status: 2,
787821
handle_continue: 2
788822

lib/elixir/pages/references/typespecs.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ Optional callbacks can be defined through the `@optional_callbacks` module attri
371371
@optional_callbacks non_vital_fun: 0, non_vital_macro: 1
372372
end
373373

374-
One example of optional callback in Elixir's standard library is `c:GenServer.format_status/2`.
374+
One example of optional callback in Elixir's standard library is `c:GenServer.format_status/1`.
375375

376376
### Inspecting behaviours
377377

0 commit comments

Comments
 (0)