-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 := Meta}, Config}, #{logFolder := LogFolder, fileD := FileDescriptors} = State) -> {MODULE, _FUNCTION_NAME, _FUNCTION_ARITY} = get_mfa_data(Meta), 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). check_file_size(FileName) -> FileSize = filelib:file_size(FileName), if FileSize > 25000000 -> move_file(FileName); true -> ok end. move_file(FileName) -> FileNameAbs = filename:absname(FileName), FileNameWithoutExt = filename:basename(FileName), FileDir = filename:absname(filename:dirname(FileName)), {{Year, Month, _}, _} = calendar:local_time(), DateDir = lists:flatten(io_lib:format("~B~2.10.0B", [Year, Month])), ArchDir = FileDir ++ "/arch", file:make_dir(ArchDir), NewFileDir = ArchDir ++ "/" ++ DateDir, file:make_dir(NewFileDir), NewFileName = NewFileDir ++ "/" ++ FileNameWithoutExt ++ ".arch", Res = file:rename(FileNameAbs, NewFileName), spawn(?MODULE, zip, [NewFileName]). zip(FileName) -> {{Year, Month, Day}, {Hour, Min, Second}} = calendar:local_time(), Date = lists:flatten(io_lib:format("~B~2.10.0B~2.10.0B~2.10.0B~2.10.0B~2.10.0B", [Year, Month, Day, Hour, Min, Second])), FileDir = filename:absname(filename:dirname(FileName)), FileNameWithoutExt = filename:basename(FileName), ZipCommand = "zip -mj " ++ FileDir ++ "/" ++ Date ++ "_" ++ FileNameWithoutExt ++ ".zip " ++ FileName, os:cmd(ZipCommand). get_mfa_data(Meta) -> case Meta of #{mfa := MFA} -> case MFA of {MODULE, _FUNCTION_NAME, _FUNCTION_ARITY} -> {MODULE, _FUNCTION_NAME, _FUNCTION_ARITY}; _else -> {unknown, unknown, unknown} end; _else -> {unknown, unknown, unknown} end.