sure. 
here we go:
in this example I use the logger_std_h handler for debugging instead of writing to files.
-module(tseq_logger).
-include_lib("kernel/include/logger.hrl").
%% API
-export([start/2]).
get_id(Number) ->
list_to_atom("proc" ++ integer_to_list(Number)).
start(From, To) ->
lists:foreach(
fun(I) ->
spawn(
fun() ->
launcher(get_id(I))
end)
end,
lists:seq(From,To)).
launcher(Id) ->
ok = logger:set_process_metadata(#{domain => [Id]}),
Parent = self(),
ok = add_tseq_handler(Id),
%% start actual worker
Pid = spawn(
fun() ->
ok = logger:set_process_metadata(#{domain => [Id]}),
%% working
?LOG_NOTICE("the job is done, tell parent ~p", [Parent]),
timer:sleep(200),
Parent ! {done, self()}
end),
?LOG_NOTICE("waiting for ~p",[Pid]),
receive
{done, Pid} ->
?LOG_NOTICE("removing handler ~p",[Id]),
ok = logger:remove_handler(Id)
end.
add_tseq_handler(TseqId) ->
logger:add_handler(
TseqId,
logger_std_h,
#{config => #{type => standard_io},
filter_default => stop,
filters =>
[{tseq_filter,
{fun logger_filters:domain/2, {log, equal, [TseqId]}}}],
formatter =>
{logger_formatter,
#{
legacy_header => false,
single_line => true,
template => [domain, ">", time, " ",level," ", pid,
" ", mfa,":",line,"|",tseq," ",
msg,"\n"]}
},
level => all}).
a launcher process creates a logger handler and starts a worker process which uses this handler via the domain. when the worker is done, the handler is removed.
start() can create multiple launchers. since they share the same code, they end nearly at the same time,
hence the logger:remove_handler() seem to come in a race condition situation.
An example output in my environment looks like this:
ok
2>
[proc2]>2023-10-15T22:37:45.605769+02:00 notice <0.554.0> tseq_logger:launcher/1:35| waiting for <0.565.0>
[proc3]>2023-10-15T22:37:45.605975+02:00 notice <0.555.0> tseq_logger:launcher/1:35| waiting for <0.568.0>
[proc1]>2023-10-15T22:37:45.605165+02:00 notice <0.561.0> tseq_logger:launcher/1:31| the job is done, tell parent <0.553.0>
[proc2]>2023-10-15T22:37:45.605815+02:00 notice <0.565.0> tseq_logger:launcher/1:31| the job is done, tell parent <0.554.0>
[proc3]>2023-10-15T22:37:45.606003+02:00 notice <0.568.0> tseq_logger:launcher/1:31| the job is done, tell parent <0.555.0>
[proc1]>2023-10-15T22:37:45.605300+02:00 notice <0.553.0> tseq_logger:launcher/1:35| waiting for <0.561.0>
[proc3]>2023-10-15T22:37:45.812213+02:00 notice <0.555.0> tseq_logger:launcher/1:38| removing handler proc3
[proc1]>2023-10-15T22:37:45.812192+02:00 notice <0.553.0> tseq_logger:launcher/1:38| removing handler proc1
[proc2]>2023-10-15T22:37:45.812484+02:00 notice <0.554.0> tseq_logger:launcher/1:38| removing handler proc2
2> logger:get_handler_ids().
[proc3,proc1,default,ssl_handler]
3>
3> logger:i().
** exception error: no match of right hand side value {error,{not_found,proc3}}
in function logger:'-get_handler_config/0-lc$^0/1-0-'/1 (logger.erl, line 520)
in call from logger:get_config/0 (logger.erl, line 660)
in call from logger:i/0 (logger.erl, line 669)