%% Copyright (C) 2025 by sysmocom - s.f.m.c. GmbH %% Author: Vadim Yanitskiy %% %% All Rights Reserved %% %% SPDX-License-Identifier: MPL-2.0 %% %% This Source Code Form is subject to the terms of the Mozilla Public %% License, v. 2.0. If a copy of the MPL was not distributed with this %% file, You can obtain one at http://mozilla.org/MPL/2.0/. -module(logger_gsmtap_h). -moduledoc """ GSMTAP logging handler. """. %% Erlang/OTP versions below 27.0.0 have no 'logger_handler' behaviour -if(?OTP_RELEASE >= 27). -behaviour(logger_handler). -endif. %% logger_handler callbacks -export([adding_handler/1, removing_handler/1, filter_config/1, log/2]). -define(LADDR_DEFAULT, "0.0.0.0"). -define(RADDR_DEFAULT, "127.0.0.1"). -define(APP_NAME_DEFAULT, unknown). %% ------------------------------------------------------------------ %% logger_handler API %% ------------------------------------------------------------------ -spec adding_handler(logger_handler:config()) -> {ok, logger_handler:config()} | {error, term()}. adding_handler(Config) -> HConfig = maps:get(config, Config, #{}), LAddr = ipaddr(maps:get(loc_addr, HConfig, ?LADDR_DEFAULT)), RAddr = ipaddr(maps:get(rem_addr, HConfig, ?RADDR_DEFAULT)), AppName = app_name(maps:get(app_name, HConfig, ?APP_NAME_DEFAULT)), {ok, Pid} = logger_gsmtap:start(LAddr, RAddr, AppName), {ok, Config#{config => HConfig#{pid => Pid, loc_addr => LAddr, rem_addr => RAddr, app_name => AppName}}}. -spec removing_handler(logger_handler:config()) -> ok. removing_handler(#{config := #{pid := Pid}}) -> logger_gsmtap:stop(Pid), ok. -spec filter_config(logger_handler:config()) -> logger_handler:config(). filter_config(#{config := HConfig} = Config) -> Config#{config => maps:without([pid], HConfig)}. -spec log(logger:log_event(), logger_handler:config()) -> term(). log(LogEvent, #{config := #{pid := Pid}}) -> logger_gsmtap:log(Pid, LogEvent). %% ------------------------------------------------------------------ %% private API %% ------------------------------------------------------------------ -spec ipaddr(Addr0) -> Addr1 when Addr0 :: string() | inet:ip_address(), Addr1 :: inet:ip_address(). ipaddr(AddrStr) when is_list(AddrStr) -> {ok, Addr} = inet:parse_address(AddrStr), Addr; ipaddr(Addr) -> true = inet:is_ip_address(Addr), Addr. -spec app_name(string() | atom()) -> string(). app_name(AppName) when is_list(AppName) -> AppName; app_name(AppName) when is_atom(AppName) -> atom_to_list(AppName). %% vim:set ts=4 sw=4 et: