From e6f6db926556c9572750ce112e646890b2fa6a19 Mon Sep 17 00:00:00 2001 From: Fernando Benavides Date: Wed, 24 Nov 2010 16:21:35 -0300 Subject: [PATCH] Dialyzed --- rebar.config | 15 +++++++++++++++ src/riak_err_app.erl | 3 +++ src/riak_err_handler.erl | 26 ++++++++++++++++---------- src/riak_err_monitor.erl | 25 +++++++++++++++++++------ src/riak_err_stdlib.erl | 19 ++++++++++++++++--- src/riak_err_sup.erl | 6 ++++++ src/trunc_io.erl | 10 +++++++++- 7 files changed, 84 insertions(+), 20 deletions(-) create mode 100644 rebar.config diff --git a/rebar.config b/rebar.config new file mode 100644 index 0000000..62ae162 --- /dev/null +++ b/rebar.config @@ -0,0 +1,15 @@ + +{erl_opts, [warn_unused_vars, + warn_export_all, + warn_shadow_vars, + warn_unused_import, + warn_unused_function, + warn_bif_clash, + warn_unused_record, + warn_deprecated_function, + warn_obsolete_guard, + strict_validation, + warn_export_vars, + warn_exported_vars, + warn_missing_spec, + warn_untyped_record, debug_info]}. diff --git a/src/riak_err_app.erl b/src/riak_err_app.erl index 53ede77..747e34c 100644 --- a/src/riak_err_app.erl +++ b/src/riak_err_app.erl @@ -90,11 +90,14 @@ start/2, stop/1]). +-spec start() -> 'ok' | {'error', term()}. start() -> application:start(riak_err). +-spec start(normal | {takeover, node()} | {failover, node()}, term()) -> {ok, pid()}. start(_StartType, _StartArgs) -> riak_err_sup:start_link(). +-spec stop([]) -> ok. stop(_State) -> ok. diff --git a/src/riak_err_handler.erl b/src/riak_err_handler.erl index 74549b3..289e27b 100644 --- a/src/riak_err_handler.erl +++ b/src/riak_err_handler.erl @@ -52,11 +52,11 @@ code_change/3]). -record(state, { - term_max_size, - fmt_max_bytes, - log_path, - log_fh, - errlog_type + term_max_size :: pos_integer(), + fmt_max_bytes :: pos_integer(), + log_path :: undefined | string(), + log_fh :: undefined | file:io_device(), + errlog_type :: error | progress | all }). %%%---------------------------------------------------------------------- @@ -65,28 +65,28 @@ %% @doc Add a supervised handler to the OTP kernel's %% error_logger event server. - +-spec add_sup_handler() -> term(). add_sup_handler() -> gen_event:add_sup_handler(error_logger, ?MODULE, []). %% @doc Change the internal value of set_term_max_size. - +-spec set_term_max_size(pos_integer()) -> ok. set_term_max_size(Num) -> gen_event:call(error_logger, ?MODULE, {set_term_max_size, Num}, infinity). %% @doc Change the internal value of set_fmt_max_bytes. - +-spec set_fmt_max_bytes(pos_integer()) -> ok. set_fmt_max_bytes(Num) -> gen_event:call(error_logger, ?MODULE, {set_fmt_max_bytes, Num}, infinity). %% @doc Tell our error handler to reopen the sasl_error_logger file's %% file handle (e.g., to assist log file rotation schemes). - +-spec reopen_log_file() -> ok. reopen_log_file() -> gen_event:call(error_logger, riak_err_handler, reopen_log_file, infinity). %% @doc Debugging: get internal state record. - +-spec get_state() -> #state{}. get_state() -> gen_event:call(error_logger, ?MODULE, {get_state}, infinity). @@ -99,6 +99,7 @@ get_state() -> %% Returns: {ok, State} | %% Other %%---------------------------------------------------------------------- +-spec init([]) -> {ok, #state{}}. init([]) -> TermMaxSize = get_int_env(term_max_size, 10*1024), FmtMaxBytes = get_int_env(fmt_max_bytes, 12*1024), @@ -125,6 +126,7 @@ init([]) -> %% {swap_handler, Args1, State1, Mod2, Args2} | %% remove_handler %%---------------------------------------------------------------------- +-spec handle_event({atom(), pid(), {pid(), string() | atom(), any()}}, #state{}) -> {ok, #state{}}. handle_event(Event, State) -> Formatted = format_event(Event, State), io:put_chars(Formatted), @@ -136,6 +138,7 @@ handle_event(Event, State) -> %% {swap_handler, Reply, Args1, State1, Mod2, Args2} | %% {remove_handler, Reply} %%---------------------------------------------------------------------- +-spec handle_call(term(), #state{}) -> {ok, ok, #state{}}. handle_call(reopen_log_file, State) -> case State#state.log_fh of undefined -> @@ -161,6 +164,7 @@ handle_call(_Request, State) -> %% {swap_handler, Args1, State1, Mod2, Args2} | %% remove_handler %%---------------------------------------------------------------------- +-spec handle_info(term(), #state{}) -> {ok, #state{}}. handle_info(_Info, State) -> {ok, State}. @@ -169,9 +173,11 @@ handle_info(_Info, State) -> %% Purpose: Shutdown the server %% Returns: any %%---------------------------------------------------------------------- +-spec terminate(term(), #state{}) -> ok. terminate(_Reason, _State) -> ok. +-spec code_change(term(), #state{}, term()) -> {ok, #state{}}. code_change(_OldVsn, State, _Extra) -> {ok, State}. diff --git a/src/riak_err_monitor.erl b/src/riak_err_monitor.erl index 7d93cae..5073687 100644 --- a/src/riak_err_monitor.erl +++ b/src/riak_err_monitor.erl @@ -31,16 +31,18 @@ code_change/3]). -record(state, { - max_len = 20*1024, - tref + max_len = 20*1024 :: pos_integer(), + tref :: timer:tref() }). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- +-spec start_link() -> {ok, pid()} | ignore | {error, term()}. start_link() -> gen_server:start_link({local, ?NAME}, ?MODULE, [], []). +-spec stop() -> ok. stop() -> gen_event:call(?NAME, stop, infinity). @@ -55,14 +57,18 @@ stop() -> %% ignore | %% {stop, Reason} %%---------------------------------------------------------------------- +-spec init([]) -> {ok, #state{}}. init([]) -> %% Add our custom handler. ok = riak_err_handler:add_sup_handler(), %% Disable the default error logger handlers and SASL handlers. - [gen_event:delete_handler(error_logger, Handler, {stop_please, ?MODULE}) || - Handler <- [error_logger, error_logger_tty_h, sasl_report_tty_h, - sasl_report_file_h]], + ok = lists:foreach( + fun(Handler) -> + gen_event:delete_handler(error_logger, Handler, {stop_please, ?MODULE}) + end, + [error_logger, error_logger_tty_h, sasl_report_tty_h, sasl_report_file_h]), + {ok, TRef} = timer:send_interval(1000, reopen_log_file), {ok, #state{tref = TRef}}. @@ -75,8 +81,11 @@ init([]) -> %% {stop, Reason, Reply, State} | (terminate/2 is called) %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- +-spec handle_call(stop | term(), reference(), #state{}) -> {stop, normal, ok, #state{}} | {reply, not_implemented, #state{}}. +handle_call(stop, _From, State) -> + {stop, normal, ok, State}; handle_call(_Request, _From, State) -> - {reply, not_implemented, State}. + {reply, not_implemented, State}. %%---------------------------------------------------------------------- %% Func: handle_cast/2 @@ -84,6 +93,7 @@ handle_call(_Request, _From, State) -> %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- +-spec handle_cast(tuple(), #state{}) -> {noreply, #state{}}. handle_cast(Msg, State) -> {Str, _} = trunc_io:print(Msg, State#state.max_len), error_logger:error_msg("~w: ~s:handle_cast got ~s\n", @@ -96,6 +106,7 @@ handle_cast(Msg, State) -> %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- +-spec handle_info(reopen_log_file | {gen_event_EXIT, ?MODULE, term()} | tuple(), #state{}) -> {noreply, #state{}} | {stop, gen_event_EXIT, #state{}}. handle_info(reopen_log_file, State) -> ok = riak_err_handler:reopen_log_file(), {noreply, State}; @@ -122,9 +133,11 @@ handle_info(Info, State) -> %% Purpose: Shutdown the server %% Returns: any (ignored by gen_server) %%---------------------------------------------------------------------- +-spec terminate(term(), #state{}) -> ok. terminate(_Reason, _State) -> ok. +-spec code_change(term(), #state{}, term()) -> {ok, #state{}}. code_change(_OldVsn, State, _Extra) -> {ok, State}. diff --git a/src/riak_err_stdlib.erl b/src/riak_err_stdlib.erl index 2e7b113..0fbb035 100644 --- a/src/riak_err_stdlib.erl +++ b/src/riak_err_stdlib.erl @@ -30,9 +30,19 @@ -export([sup_get/2]). -export([proc_lib_format/2]). +%% From calendar +-type year1970() :: 1970..10000. % should probably be 1970.. +-type month() :: 1..12. +-type day() :: 1..31. +-type hour() :: 0..23. +-type minute() :: 0..59. +-type second() :: 0..59. +-type t_time() :: {hour(),minute(),second()}. +-type t_datetime1970() :: {{year1970(),month(),day()},t_time()}. + %% From OTP stdlib's error_logger_tty_h.erl ... These functions aren't %% exported. - +-spec write_time({utc, t_datetime1970()} | t_datetime1970(), string()) -> string(). write_time({utc,{{Y,Mo,D},{H,Mi,S}}},Type) -> io_lib:format("~n=~s==== ~p-~s-~p::~s:~s:~s UTC ===~n", [Type,D,month(Mo),Y,t(H),t(Mi),t(S)]); @@ -40,6 +50,7 @@ write_time({{Y,Mo,D},{H,Mi,S}},Type) -> io_lib:format("~n=~s==== ~p-~s-~p::~s:~s:~s ===~n", [Type,D,month(Mo),Y,t(H),t(Mi),t(S)]). +-spec maybe_utc(t_datetime1970()) -> {utc, t_datetime1970()} | t_datetime1970(). maybe_utc(Time) -> UTC = case application:get_env(sasl, utc_log) of {ok, Val} -> @@ -86,14 +97,16 @@ month(12) -> "Dec". %% From OTP sasl's sasl_report.erl ... These functions aren't %% exported. - +-spec is_my_error_report(atom()) -> boolean(). is_my_error_report(supervisor_report) -> true; is_my_error_report(crash_report) -> true; is_my_error_report(_) -> false. +-spec is_my_info_report(atom()) -> boolean(). is_my_info_report(progress) -> true; is_my_info_report(_) -> false. +-spec sup_get(term(), [proplists:property()]) -> term(). sup_get(Tag, Report) -> case lists:keysearch(Tag, 1, Report) of {value, {_, Value}} -> @@ -103,7 +116,7 @@ sup_get(Tag, Report) -> end. %% From OTP stdlib's proc_lib.erl ... These functions aren't exported. - +-spec proc_lib_format([term()], pos_integer()) -> string(). proc_lib_format([OwnReport,LinkReport], FmtMaxBytes) -> OwnFormat = format_report(OwnReport, FmtMaxBytes), LinkFormat = format_report(LinkReport, FmtMaxBytes), diff --git a/src/riak_err_sup.erl b/src/riak_err_sup.erl index 1eca0f9..ea1582d 100644 --- a/src/riak_err_sup.erl +++ b/src/riak_err_sup.erl @@ -26,9 +26,15 @@ -define(SERVER, ?MODULE). +%% From supervisor +-type startlink_err() :: {'already_started', pid()} | 'shutdown' | term(). +-type startlink_ret() :: {'ok', pid()} | 'ignore' | {'error', startlink_err()}. + +-spec start_link() -> startlink_ret(). start_link() -> supervisor:start_link({local, ?SERVER}, ?MODULE, []). +-spec init([]) -> {ok, {{one_for_one, 1000, 3600}, [supervisor:child_spec()]}}. init([]) -> RestartStrategy = one_for_one, MaxRestarts = 1000, diff --git a/src/trunc_io.erl b/src/trunc_io.erl index 8d9c67a..a354385 100644 --- a/src/trunc_io.erl +++ b/src/trunc_io.erl @@ -36,6 +36,7 @@ %% @doc Returns an flattened list containing the ASCII representation of the given %% term. +-spec fprint(term(), pos_integer()) -> string(). fprint(T, Max) -> {L, _} = print(T, Max), lists:flatten(L). @@ -49,6 +50,7 @@ fprint(T, Max) -> %% depth-limited instead of length limited, so you might run out %% memory printing it. Out of the frying pan and into the fire. %% +-spec safe(term(), pos_integer()) -> {string(), pos_integer()} | {string()}. safe(What, Len) -> case catch print(What, Len) of {L, Used} when is_list(L) -> {L, Used}; @@ -56,6 +58,7 @@ safe(What, Len) -> end. %% @doc Returns {List, Length} +-spec print(term(), pos_integer()) -> {iolist(), pos_integer()}. print(_, Max) when Max < 0 -> {"...", 3}; print(Tuple, Max) when is_tuple(Tuple) -> {TC, Len} = tuple_contents(Tuple, Max-2), @@ -166,9 +169,11 @@ alist(L, Max) -> %%-------------------- %% The start of a test suite. So far, it only checks for not crashing. +-spec test() -> ok. test() -> test(trunc_io, print). +-spec test(atom(), atom()) -> ok. test(Mod, Func) -> Simple_items = [atom, 1234, 1234.0, {tuple}, [], [list], "string", self(), <<1,2,3>>, make_ref(), fun() -> ok end], @@ -196,12 +201,14 @@ test(Mod, Func) -> lists:foreach(G, Tuples), lists:foreach(G, Lists). - + +-spec perf() -> ok. perf() -> {New, _} = timer:tc(trunc_io, perf, [trunc_io, print, 1000]), {Old, _} = timer:tc(trunc_io, perf, [io_lib, write, 1000]), io:fwrite("New code took ~p us, old code ~p\n", [New, Old]). +-spec perf(atom(), atom(), integer()) -> done. perf(M, F, Reps) when Reps > 0 -> test(M,F), perf(M,F,Reps-1); @@ -209,6 +216,7 @@ perf(_,_,_) -> done. %% Performance test. Needs a particularly large term I saved as a binary... +-spec perf1() -> {non_neg_integer(), non_neg_integer()}. perf1() -> {ok, Bin} = file:read_file("bin"), A = binary_to_term(Bin),