/src/log.erl

http://github.com/antoniogarrote/egearmand-server · Erlang · 151 lines · 75 code · 44 blank · 32 comment · 3 complexity · a81f11b82b027f47c9627cac1a345f53 MD5 · raw file

  1. -module(log).
  2. %% @doc
  3. %% Logging server
  4. -author("Antonio Garrote Hernandez").
  5. -behaviour(gen_server) .
  6. -import(io).
  7. -export([t/1,p/1,error/1, info/1, warning/1, debug/1, ot/1, timestamp/0]).
  8. -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2]).
  9. -export([start_link/1, msg/2]).
  10. %% Public API
  11. %% @doc
  12. %% Creates the logger server.
  13. %% Options are: method:(stdout | file),
  14. %% level:([debug, info, warning, error])
  15. %% path: string()
  16. start_link(Args) ->
  17. gen_server:start_link({global, egearmand_logger}, log, Args, []) .
  18. ot(Msg) ->
  19. io:format("~n*** trace: ~p~n",[Msg]),
  20. Msg .
  21. %% @doc
  22. %% Traces code Msg returning Msg.
  23. -spec(t(any()) -> any()) .
  24. t(Msg) ->
  25. Msg .
  26. %% @doc
  27. %% Prints the message Msg.
  28. p(Msg) ->
  29. io:format("~n*** print: ~p~n",[Msg]) .
  30. %% @doc
  31. %% Logs message Msg with error log level.
  32. error(Msg) ->
  33. msg(error, Msg) .
  34. %% @doc
  35. %% Logs message Msg with debug log level.
  36. debug(Msg) ->
  37. msg(debug, Msg) .
  38. %% @doc
  39. %% Logs message Msg with error info level.
  40. info(Msg) ->
  41. msg(info, Msg) .
  42. %% @doc
  43. %% Logs message Msg with error warning level.
  44. warning(Msg) ->
  45. msg(warning, Msg) .
  46. %% @doc
  47. %% Sends a log message to the logger server with the given log level
  48. msg(Level, Msg) ->
  49. MsgP = io_lib:format("~n*** ~p:~s ~n~p~n***~n",[Level,timestamp(),Msg]),
  50. gen_server:cast({global, egearmand_logger},{Level, MsgP}) .
  51. %% Callbacks
  52. init(Options) ->
  53. LoggerMethod = proplists:get_value(method, Options),
  54. State = if LoggerMethod =:= file ->
  55. case file:open(proplists:get_value(path,Options), [write, raw]) of
  56. {ok, F} -> [{file, F}, {method, file}] ;
  57. {error, _Reason} -> [{method, none}]
  58. end ;
  59. LoggerMethod =:= stdout ->
  60. [{method, stdout}]
  61. end,
  62. {ok, [{level, proplists:get_value(level, Options)} | State]} .
  63. handle_cast({Level, Msg}, State) ->
  64. case should_log_p(Level,State) of
  65. true -> process(Msg, State) ;
  66. false -> dont_care
  67. end,
  68. {noreply, State} .
  69. %% dummy callbacks so no warning are shown at compile time
  70. handle_call(_Msg, _From, State) ->
  71. {reply, State} .
  72. handle_info(_Msg, State) ->
  73. {noreply, State}.
  74. terminate(shutdown, _State) ->
  75. ok.
  76. %% private functions
  77. %% @doc
  78. %% Timestamp generation
  79. timestamp() ->
  80. {{Year,Month,Day},{Hour,Min,Sec}} = erlang:localtime(),
  81. lists:flatten(
  82. io_lib:fwrite("~2B/~2B/~4..0B ~2B:~2.10.0B:~2.10.0B",
  83. [Month, Day, Year, Hour, Min, Sec])).
  84. %% @doc
  85. %% Tests if Level is greater or equal than the default logging
  86. %% level stored in Options.
  87. should_log_p(Level, Options) ->
  88. Levels = [debug, info, warning, error],
  89. DefaultLevel = proplists:get_value(level,Options),
  90. IndexLevel = lists_extensions:index(Level, Levels),
  91. IndexDefault = lists_extensions:index(DefaultLevel, Levels),
  92. if (IndexLevel =:= not_found) or (IndexDefault =:= not_found) ->
  93. false ;
  94. true ->
  95. if Level < DefaultLevel -> false ;
  96. Level >= DefaultLevel -> true
  97. end
  98. end .
  99. %% @doc
  100. %% Writes a message using the method stored in State.
  101. process(Msg, Options) ->
  102. Method = proplists:get_value(method, Options),
  103. case Method of
  104. file -> File = proplists:get_value(file, Options),
  105. file:write(File, Msg) ;
  106. stdout -> io:format(Msg)
  107. end .