Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

166 wiersze
5.6 KiB

9 lat temu
9 lat temu
9 lat temu
  1. %% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
  2. %% ex: ts=4 sw=4 et
  3. %% -------------------------------------------------------------------
  4. %%
  5. %% rebar: Erlang Build Tools
  6. %%
  7. %% Copyright (c) 2009 Dave Smith (dizzyd@dizzyd.com)
  8. %%
  9. %% Permission is hereby granted, free of charge, to any person obtaining a copy
  10. %% of this software and associated documentation files (the "Software"), to deal
  11. %% in the Software without restriction, including without limitation the rights
  12. %% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. %% copies of the Software, and to permit persons to whom the Software is
  14. %% furnished to do so, subject to the following conditions:
  15. %%
  16. %% The above copyright notice and this permission notice shall be included in
  17. %% all copies or substantial portions of the Software.
  18. %%
  19. %% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. %% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. %% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. %% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. %% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. %% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. %% THE SOFTWARE.
  26. %% -------------------------------------------------------------------
  27. -module(rebar_log).
  28. -export([init/2,
  29. crashdump/2,
  30. set_level/1,
  31. get_level/0,
  32. error_level/0,
  33. default_level/0,
  34. debug_level/0,
  35. diagnostic_level/0,
  36. intensity/0,
  37. log/3,
  38. is_verbose/1,
  39. valid_level/1,
  40. truncate/1]).
  41. -define(ERROR_LEVEL, 0).
  42. -define(WARN_LEVEL, 1).
  43. -define(INFO_LEVEL, 2).
  44. -define(DEBUG_LEVEL, 3).
  45. -define(DIAGNOSTIC_LEVEL, 4).
  46. -define(DFLT_INTENSITY, high).
  47. %% ===================================================================
  48. %% Public API
  49. %% ===================================================================
  50. %% @doc Returns the color intensity, we first check the application envorinment
  51. %% if that is not set we check the environment variable REBAR_COLOR.
  52. intensity() ->
  53. case application:get_env(rebar, color_intensity) of
  54. undefined ->
  55. R = case os:getenv("REBAR_COLOR") of
  56. "high" ->
  57. high;
  58. "low" ->
  59. low;
  60. "none" ->
  61. none;
  62. _ ->
  63. ?DFLT_INTENSITY
  64. end,
  65. application:set_env(rebar, color_intensity, R),
  66. R;
  67. {ok, Mode} ->
  68. Mode
  69. end.
  70. init(Caller, Verbosity) ->
  71. Level = case valid_level(Verbosity) of
  72. ?ERROR_LEVEL -> error;
  73. ?WARN_LEVEL -> warn;
  74. ?INFO_LEVEL -> info;
  75. ?DEBUG_LEVEL -> debug;
  76. ?DIAGNOSTIC_LEVEL -> debug
  77. end,
  78. Intensity = intensity(),
  79. application:set_env(rebar, log_caller, Caller),
  80. Log = ec_cmd_log:new(Level, Caller, Intensity),
  81. set_level(valid_level(Verbosity)),
  82. application:set_env(rebar, log, Log).
  83. set_level(Level) ->
  84. ok = application:set_env(rebar, log_level, Level).
  85. get_level() ->
  86. case application:get_env(rebar, log_level) of
  87. undefined ->
  88. default_level();
  89. {ok, Level} ->
  90. Level
  91. end.
  92. log(diagnostic, Str, Args) ->
  93. %% The diagnostic level is intended for debug info
  94. %% that is useful for rebar3 developers and implementers who
  95. %% understand the internal structure; the debug level
  96. %% itself should aim to be useful for users themselves.
  97. %% The underlying library only supports debug at its lowest
  98. %% level, so we filter on our end of the lib.
  99. case get_level() of
  100. ?DIAGNOSTIC_LEVEL -> log(debug, Str, Args);
  101. _ -> ok
  102. end;
  103. log(Level = error, Str, Args) ->
  104. case application:get_env(rebar, log) of
  105. {ok, LogState} ->
  106. NewStr = lists:flatten(cf:format("~!^~ts~n", [Str])),
  107. ec_cmd_log:Level( LogState, NewStr, Args);
  108. undefined -> % fallback
  109. io:format(standard_error, Str++"~n", Args)
  110. end;
  111. log(Level, Str, Args) ->
  112. case application:get_env(rebar, log) of
  113. {ok, LogState} -> ec_cmd_log:Level(LogState, Str++"~n", Args);
  114. undefined -> io:format(Str++"~n", Args)
  115. end.
  116. crashdump(Str, Args) ->
  117. crashdump("rebar3.crashdump", Str, Args).
  118. crashdump(File, Str, Args) ->
  119. case application:get_env(rebar, log_caller) of
  120. {ok, api} ->
  121. ok;
  122. _ ->
  123. file:write_file(File, io_lib:fwrite(Str, Args))
  124. end.
  125. error_level() -> ?ERROR_LEVEL.
  126. default_level() -> ?INFO_LEVEL.
  127. debug_level() -> ?DEBUG_LEVEL.
  128. diagnostic_level() -> ?DIAGNOSTIC_LEVEL.
  129. is_verbose(State) ->
  130. rebar_state:get(State, is_verbose, false).
  131. valid_level(Level) ->
  132. erlang:max(?ERROR_LEVEL, erlang:min(Level, ?DIAGNOSTIC_LEVEL)).
  133. %% ===================================================================
  134. %% Internal functions
  135. %% ===================================================================
  136. truncate(IoData) ->
  137. Size = iolist_size(IoData),
  138. if Size > 4096 -> [take_bytes(4096, IoData), "[...]"];
  139. Size =< 4096 -> IoData
  140. end.
  141. take_bytes(0, _) -> [];
  142. take_bytes(N, Bin) when is_binary(Bin), byte_size(Bin) > N ->
  143. <<B:N/binary, _>> = Bin,
  144. binary:copy(B); % avoid holding on to large refs
  145. take_bytes(_, Bin) when is_binary(Bin) ->
  146. Bin;
  147. take_bytes(_, []) -> [];
  148. take_bytes(N, [H|T]) when is_integer(H) ->
  149. [H | take_bytes(N-1, T)];
  150. take_bytes(N, [H|T]) when is_binary(H); is_list(H) ->
  151. Res = take_bytes(N, H),
  152. [Res | take_bytes(N-byte_size(Res), T)].