-module(file_logger_handler). -include("include/types_rabbit.hrl"). -include_lib("kernel/include/logger.hrl"). -export([adding_handler/1, removing_handler/1, log/2]). -export([init/1, handle_call/3, handle_cast/2, terminate/2]). adding_handler(Config) -> MyConfig = maps:get(config,Config), {ok, Pid} = gen_server:start(?MODULE, MyConfig, []), {ok, Config#{config => MyConfig#{pid => Pid}}}. init(#{logFolder := LogFolder}) -> {ok,#{fileD => [], logFolder => LogFolder}}. removing_handler(#{config := #{pid := Pid}}) -> gen_server:stop(Pid). terminate(_Reason, #{fileD := FileDescriptors}) -> _ = closeFD(FileDescriptors), ok. log(LogEvent,#{config := #{pid := Pid}} = Config) -> gen_server:cast(Pid, {log, LogEvent, Config}). handle_cast({log, LogEvent = #{meta := #{mfa := {MODULE, _FUNCTION_NAME, _FUNCTION_ARITY}}}, Config}, #{logFolder := LogFolder, fileD := FileDescriptors} = State) -> FilePath = string:join([LogFolder,MODULE],"/"), case find_fd(FileDescriptors,FilePath) of none -> NewFD = open_new_fd(FilePath), NewFDL = lists:append(FileDescriptors,[{FilePath,NewFD}]), do_log(NewFD,LogEvent,Config), {noreply, State#{fileD => NewFDL}}; Fd -> do_log(Fd,LogEvent,Config), {noreply, State} end. handle_call(_, _, State) -> {reply, {error, bad_request}, State}. find_fd([], _Name) -> none; find_fd([{Name,Fd}|_FileDescriptors], Name) -> Fd; find_fd([_|FileDescriptors], Name) -> find_fd(FileDescriptors,Name). open_new_fd(File) -> {ok, Fd} = file:open(File, [append, {encoding, utf8}]), Fd. do_log(Fd, LogEvent, #{formatter := {FModule, FConfig}}) -> String = FModule:format(LogEvent, FConfig), io:put_chars(Fd, String). closeFD([]) -> ok; closeFD([{_Name,Fd}|FileDescriptors]) -> file:close(Fd), closeFD(FileDescriptors).