I'm learning Erlang, and am managing to find answers and work out solutions to most issues relatively efficiently, but have spent an unacceptable amount of time working out this one:
What is the correct way to add handlers to a gen_event module that is being being started by a supervisor process? In my exploration so far, I have been able to set up processes, gen_servers, supervisors (that start gen_servers), and gen_event modules, but everything I've attempted to actually add a handler to gen_event is crashing my supervisor process — and sometimes even my shell!!
The supervisor module:
-module(sup).
-behaviour(supervisor).
%% API
-export([start_link/0, init/1]).
-export([stop/0]).
start_link() ->
  supervisor:start_link({local, ?MODULE}, ?MODULE, []).
init(_) ->
  EventServerSpec = #{
    id => osc_event_server,
    start => {gen_event, start_link, [{local, osc_server}]},
    modules => dynamic
  },
  ChildSpecList = [EventServerSpec, child(frequency), child(bkpt_server)],
  SupFlags = #{strategy => rest_for_one,
    intensity => 2, period => 3600},
  {ok, {SupFlags, ChildSpecList}}.
child(Module) ->
  #{id => Module,
    start => {Module, start_link, []},
    restart => permanent,
    shutdown => 2000,
    type => worker,
    modules => [Module]}.
… and some bits and pieces from the gen_event module, osc_event_server (hopefully the relevant ones!)
...
init([]) ->
  {ok, Socket} = gen_udp:open(8980, [binary, {active, false}]),
  {ok, #{socket => Socket, target_port => get_target_port()}}.
...
handle_event({send_osc, Path, Data}, State) ->
  TargetPort = maps:get(target_port, State),
  Socket = maps:get(socket, State),
  sendMessage(Socket, TargetPort, Path, Data),
  {ok, State};
...
As poorly as I understand the gen_event behaviour, I'm not much surprised by the result of running the code that includes these snippets:
- it launches without crashing
 - it launches gen_event and produces a referenceable Pid for it, but never hits the 
initblock of 'osc_event_server' - there are no actual event handlers attached to gen_event. Both "which_handlers" and attempts to send messages confirm that.
 
The two things that I'd like to incorporate:
- attach the specific event handlers (e.g., "send_osc") to my gen_event process… hopefully from within the supervisor code
 - pass initialization arguments to the osc_event_server module; I want to be able at least to specify the port for the UDP server (rather than hard-wiring "8980") and provide the IP+port of a remote UDP server with which I want my process to communicate.
 
Thanks very much. Feel free to be critical of anything you see… e.g., my whole approach :) As much Erlang as I've come to understand at this point, it's nothing, I'm sure, compared to the amount of Erlang I misunderstand.