Current section
Files
Jump to
Current section
Files
src/system_monitor_events.erl
%%--------------------------------------------------------------------------------
%% Copyright 2020 Klarna Bank AB
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%--------------------------------------------------------------------------------
%%% @doc
%%% Print BEAM VM events to the logs
%%%
%%% @end
-module(system_monitor_events).
-behaviour(gen_server).
-include("system_monitor.hrl").
-include_lib("hut/include/hut.hrl").
-export([start_link/0]).
%% gen_server callbacks
-export([ init/1
, handle_call/3
, handle_cast/2
, handle_info/2
, terminate/2
]).
%%--------------------------------------------------------------------
%% @doc
%% Starts the server
%% @end
%%--------------------------------------------------------------------
-spec start_link() -> {ok, pid()}.
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
%%====================================================================
%% gen_server callbacks
%%====================================================================
init([]) ->
setup_system_monitor(),
{ok, {}}.
handle_call(_Request, _From, State) ->
{reply, {error, unknown_call}, State}.
handle_cast(_Msg, State) ->
{noreply, State}.
handle_info({monitor, PidOrPort, EventKind, Info}, State) ->
InfoTxt = format_system_event_info(Info),
?log( info
, "sysmon ~p: pid=~p~n~s"
, [EventKind, PidOrPort, InfoTxt]
, #{domain => [system_monitor]}
),
{noreply, State};
handle_info(_Info, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
ok.
%%==============================================================================
%% Internal functions
%%==============================================================================
%%--------------------------------------------------------------------
%% @doc: Set the current process as the receiver of the BEAM system
%% events
%%--------------------------------------------------------------------
-spec setup_system_monitor() -> ok.
setup_system_monitor() ->
{ok, Opts} = application:get_env(?APP, beam_events),
erlang:system_monitor(self(), Opts),
ok.
-spec format_system_event_info(term()) -> io_lib:chars().
format_system_event_info(Info) when is_list(Info) ->
lists:foldl(
fun({Key, Value}, Acc) ->
[io_lib:format("~p=~p ", [Key, Value])|Acc];
(Value, Acc) ->
[io_lib:format("~p ", [Value])|Acc]
end,
[],
Info);
format_system_event_info(Port) when is_port(Port) ->
format_system_event_info([{port, Port}]);
format_system_event_info(Pid) when is_pid(Pid) ->
format_system_event_info([{pid_2, Pid}]);
format_system_event_info(Term) ->
format_system_event_info([{info, Term}]).
%%%_* Emacs ============================================================
%%% Local Variables:
%%% allout-layout: t
%%% erlang-indent-level: 2
%%% End: