%%% Copyright (c) 2007- Facebook
%%% Distributed under the Thrift Software License
-%%%
+%%%
%%% See accompanying file LICENSE or visit the Thrift site at:
%%% http://developers.facebook.com/thrift/
--define(CONFIG_FILE, filename:join("conf", "thrift.conf")).
-
-define(ERROR(F, D),
error_logger:format(F, D)).
-
-define(INFO(Type, Report),
error_logger:info_report({thrift_info, Type}, Report)).
--include("thrift_macros.hrl").
--include("thrift_constants.hrl").
+% local (same process)
+-define(L0(Method), oop:call(This, Method, [])).
+-define(L1(Method, Arg1), oop:call(This, Method, [Arg1])).
+-define(L2(Method, Arg1, Arg2), oop:call(This, Method, [Arg1, Arg2])).
+-define(L3(Method, Arg1, Arg2, Arg3), oop:call(This, Method, [Arg1, Arg2, Arg3])).
+-define(L4(Method, Arg1, Arg2, Arg3, Arg4), oop:call(This, Method, [Arg1, Arg2, Arg3, Arg4])).
+-define(L5(Method, Arg1, Arg2, Arg3, Arg4, Arg5), oop:call(This, Method, [Arg1, Arg2, Arg3, Arg4, Arg5])).
+-define(L6(Method, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6), oop:call(This, Method, [Arg1, Arg2, Arg3, Arg4, Arg5, Arg6])).
+
+% local (same process), but not This (e.g. t*Factory)
+-define(F0(Obj, Method), oop:call(Obj, Method, [])).
+-define(F1(Obj, Method, Arg1), oop:call(Obj, Method, [Arg1])).
+-define(F2(Obj, Method, Arg1, Arg2), oop:call(Obj, Method, [Arg1, Arg2])).
+-define(F3(Obj, Method, Arg1, Arg2, Arg3), oop:call(Obj, Method, [Arg1, Arg2, Arg3])).
+-define(F4(Obj, Method, Arg1, Arg2, Arg3, Arg4), oop:call(Obj, Method, [Arg1, Arg2, Arg3, Arg4])).
+-define(F5(Obj, Method, Arg1, Arg2, Arg3, Arg4, Arg5), oop:call(Obj, Method, [Arg1, Arg2, Arg3, Arg4, Arg5])).
+-define(F6(Obj, Method, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6), oop:call(Obj, Method, [Arg1, Arg2, Arg3, Arg4, Arg5, Arg6])).
+
+% remote (different process)
+-define(RT0(ServerRef, Method, Timeout), gen_server:call(ServerRef, {Method, []}, Timeout)).
+-define(RT1(ServerRef, Method, Timeout, Arg1), gen_server:call(ServerRef, {Method, [Arg1]}, Timeout)).
+-define(RT2(ServerRef, Method, Timeout, Arg1, Arg2), gen_server:call(ServerRef, {Method, [Arg1, Arg2]}, Timeout)).
+-define(RT3(ServerRef, Method, Timeout, Arg1, Arg2, Arg3), gen_server:call(ServerRef, {Method, [Arg1, Arg2, Arg3]}, Timeout)).
+-define(RT4(ServerRef, Method, Timeout, Arg1, Arg2, Arg3, Arg4), gen_server:call(ServerRef, {Method, [Arg1, Arg2, Arg3, Arg4]}, Timeout)).
+-define(RT5(ServerRef, Method, Timeout, Arg1, Arg2, Arg3, Arg4, Arg5), gen_server:call(ServerRef, {Method, [Arg1, Arg2, Arg3, Arg4, Arg5]}, Timeout)).
+-define(RT6(ServerRef, Method, Timeout, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6), gen_server:call(ServerRef, {Method, [Arg1, Arg2, Arg3, Arg4, Arg5, Arg6]}, Timeout)).
+
+% remote (different process), default timeout
+-define(DEFAULT_TIMEOUT, 5000).
+-define(R0(ServerRef, Method), ?RT0(ServerRef, Method, ?DEFAULT_TIMEOUT)).
+-define(R1(ServerRef, Method, Arg1), ?RT1(ServerRef, Method, ?DEFAULT_TIMEOUT, Arg1)).
+-define(R2(ServerRef, Method, Arg1, Arg2), ?RT2(ServerRef, Method, ?DEFAULT_TIMEOUT, Arg1, Arg2)).
+-define(R3(ServerRef, Method, Arg1, Arg2, Arg3), ?RT3(ServerRef, Method, ?DEFAULT_TIMEOUT, Arg1, Arg2, Arg3)).
+-define(R4(ServerRef, Method, Arg1, Arg2, Arg3, Arg4), ?RT4(ServerRef, Method, ?DEFAULT_TIMEOUT, Arg1, Arg2, Arg3, Arg4)).
+-define(R5(ServerRef, Method, Arg1, Arg2, Arg3, Arg4, Arg5), ?RT5(ServerRef, Method, ?DEFAULT_TIMEOUT, Arg1, Arg2, Arg3, Arg4, Arg5)).
+-define(R6(ServerRef, Method, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6), ?RT6(ServerRef, Method, ?DEFAULT_TIMEOUT, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)).
+
+% remote (different process), cast
+-define(C0(ServerRef, Method), gen_server:cast(ServerRef, {Method, []})).
+-define(C1(ServerRef, Method, Arg1), gen_server:cast(ServerRef, {Method, [Arg1]})).
+-define(C2(ServerRef, Method, Arg1, Arg2), gen_server:cast(ServerRef, {Method, [Arg1, Arg2]})).
+-define(C3(ServerRef, Method, Arg1, Arg2, Arg3), gen_server:cast(ServerRef, {Method, [Arg1, Arg2, Arg3]})).
+-define(C4(ServerRef, Method, Arg1, Arg2, Arg3, Arg4), gen_server:cast(ServerRef, {Method, [Arg1, Arg2, Arg3, Arg4]})).
+-define(C5(ServerRef, Method, Arg1, Arg2, Arg3, Arg4, Arg5), gen_server:cast(ServerRef, {Method, [Arg1, Arg2, Arg3, Arg4, Arg5]})).
+-define(C6(ServerRef, Method, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6), gen_server:cast(ServerRef, {Method, [Arg1, Arg2, Arg3, Arg4, Arg5, Arg6]})).
+
+% spawn new server
+%% -define(NEW(Class, Args), %%
+%% gen_server:start_link(thrift_oop_server, {Class, Args}, [])). %%
+%% moved to oop:start_new/2
+
+% old
+%% -define(M0(Obj, Method), oop:call(Obj, Method, [])). %%
+%% -define(M1(Obj, Method, Arg1), oop:call(Obj, Method, [Arg1])). %%
+%% -define(M2(Obj, Method, Arg1, Arg2), oop:call(Obj, Method, [Arg1, Arg2])). %%
+%% -define(M3(Obj, Method, Arg1, Arg2, Arg3), oop:call(Obj, Method, [Arg1, Arg2, Arg3])). %%
+%% -define(M4(Obj, Method, Arg1, Arg2, Arg3, Arg4), oop:call(Obj, Method, [Arg1, Arg2, Arg3, Arg4])). %%
+%% -define(M5(Obj, Method, Arg1, Arg2, Arg3, Arg4, Arg5), oop:call(Obj, Method, [Arg1, Arg2, Arg3, Arg4, Arg5])). %%
+%% -define(M6(Obj, Method, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6), oop:call(Obj, Method, [Arg1, Arg2, Arg3, Arg4, Arg5, Arg6])). %%
+
+%%% implicit call: old
+
+%% -define(M0(Obj, Method), ((?CLASS(Obj)):Method(Obj))). %%
+%% -define(M1(Obj, Method, Arg1), ((?CLASS(Obj)):Method(Obj, Arg1))). %%
+%% -define(M2(Obj, Method, Arg1, Arg2), ((?CLASS(Obj)):Method(Obj, Arg1, Arg2))). %%
+%% -define(M3(Obj, Method, Arg1, Arg2, Arg3), ((?CLASS(Obj)):Method(Obj, Arg1, Arg2, Arg3))). %%
+%% -define(M4(Obj, Method, Arg1, Arg2, Arg3, Arg4), ((?CLASS(Obj)):Method(Obj, Arg1, Arg2, Arg3, Arg4))). %%
+%% -define(M5(Obj, Method, Arg1, Arg2, Arg3, Arg4, Arg5), ((?CLASS(Obj)):Method(Obj, Arg1, Arg2, Arg3, Arg4, Arg5))). %%
+%% -define(M6(Obj, Method, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6), ((?CLASS(Obj)):Method(Obj, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6))). %%
+
+%% TType
+-define(tType_STOP, 0).
+-define(tType_VOID, 1).
+-define(tType_BOOL, 2).
+-define(tType_BYTE, 3).
+-define(tType_DOUBLE, 4).
+-define(tType_I16, 6).
+-define(tType_I32, 8).
+-define(tType_I64, 10).
+-define(tType_STRING, 11).
+-define(tType_STRUCT, 12).
+-define(tType_MAP, 13).
+-define(tType_SET, 14).
+-define(tType_LIST, 15).
+
+% tmessagetype
+-define(tMessageType_CALL, 1).
+-define(tMessageType_REPLY, 2).
+-define(tMessageType_EXCEPTION, 3).
+
+% TProcessor
+% ?
+
+% -include("tApplicationException.hrl").
-behaviour(gen_event).
--record(state, {config}).
-
--define(CONFIG(Item), config(Item, State)).
+-include("thrift_logger.hrl").
%% TODO(cpiro): either
%% make exceptions know whether they need to be displayed
-export([init/1, handle_event/2, handle_call/2,
handle_info/2, terminate/2, code_change/3]).
--export([install/0, install/1, reconfig/0, reconfig/1]).
+-export([install/0, install/1]).
%% ensure the regular logger is out and ours is in
install() ->
install([]).
-install(Config) ->
+install(Args) ->
%% remove loggers
- io:format("starting logger~n"),
lists:foreach(fun(Logger) ->
case Logger of
_ -> gen_event:delete_handler(error_logger, Logger, normal)
%% TODO(cpiro): sasl someday?
%% gen_event:add_handler(error_logger, sasl_report_file_h, {LogFile, all}),
+ gen_event:add_handler(error_logger, ?MODULE, Args).
- gen_event:add_handler(error_logger, ?MODULE, []),
-
- reconfig(Config),
-
- ok.
-
-%% load our config file and amend the given stuff
-reconfig() ->
- reconfig([]).
+%% how to output
+format(Format, Data) ->
+ io:format(Format, Data).
-reconfig(Config) ->
- gen_event:call(error_logger, ?MODULE, {reconfig, Config}).
+%% convenience
+sformat(Format, Data) ->
+ thrift_utils:sformat(Format, Data).
%%====================================================================
%% gen_event callbacks
%% @end
%%--------------------------------------------------------------------
init([]) ->
- BootConfig = [
- {term_width, 80},
- {force_one_line, false},
- {omit, []},
- {gen_server_messages, true},
- {lookup, false}
- ], %% configuration before we try loading from file
-
- State = #state{config=BootConfig},
+ {ok, #thrift_logger_state{
+ term_width = 110,
+ force_one_line = true,
+ omit = [oop_new], % req_processed
+ gen_server_messages = false,
+ lookup = true
+ }};
+
+init([State]) ->
{ok, State}.
%%--------------------------------------------------------------------
end,
Length =
- case (length(OutputSafe) + BannerLen) < ?CONFIG(term_width) of
+ case (length(OutputSafe) + BannerLen) < State#thrift_logger_state.term_width of
true -> short;
false -> long
end,
false -> multiline
end,
- case { ?CONFIG(force_one_line), Length, OneLine } of
+ case { State#thrift_logger_state.force_one_line, Length, OneLine } of
%% one line and short ... print as is
{_, short, oneliner} ->
format("~s~s~n", [Banner, OutputSafe]);
%% too long ... squash to one
{true, long, _} ->
O = Banner ++ OutputSafe,
- Format = sformat("~~~ps >~n", [?CONFIG(term_width)-2]), % e.g. "~80s >~n"
+ Format = sformat("~~~ps >~n", [State#thrift_logger_state.term_width-2]), % e.g. "~80s >~n"
format(Format, [O]);
%% short but multiline... collapse to one
case Format of
"** Generic server ~p terminating \n** Last message in was ~p~n** When Server state == ~p~n** Reason for termination == ~n** ~p~n" ->
%% v- Pid is a pattern match, not a bind
- [Ref, LastMessage, Obj, Reason] = Data,
+ [Pid, LastMessage, Obj, Reason] = Data,
%% TODO: move as much logic as possible out of thrift_logger
Ignore =
false ->
Format1 = "** gen_server terminating in message ~p~n** State = ~s~n** Reason = ~s~n",
Message = sformat(Format1, [LastMessage, oop:inspect(Obj), oop:inspect(Reason)]), %% TODO(cpiro): hope Reason is an object?
- handle_event2(Symbol, Ref, "", Message, State)
+ handle_event2(Symbol, Pid, "", Message, State)
end;
_ ->
Message = sformat(Format, Data),
- handle_event2(Symbol, Ref, "", Message, State)
+ handle_event2(Symbol, Pid, "", Message, State)
end,
{ok, State};
case Type of
{thrift_info, TI} ->
%% should we show it?
- case not lists:member(TI, ?CONFIG(omit)) of
+ case not lists:member(TI, State#thrift_logger_state.omit) of
true ->
Message = handle_thrift_info(TI, Report, State),
handle_event2(Symbol, Pid, "", Message, State);
%%--------------------------------------------------------------------
%% @spec handle_call(Request, State) -> {ok, Reply, State} |
-%% {swap_handler, Reply, Args1, State1,
+%% {swap_handler, Reply, Args1, State1,
%% Mod2, Args2} |
%% {remove_handler, Reply}.
%%
%% handler to handle the request.
%% @end
%%--------------------------------------------------------------------
-handle_call({reconfig, Amendments}, State) ->
- {OkOrError, State1} = reconfig1(State, Amendments),
- format(".. reconfig was ~p~n", [OkOrError]),
- {ok, OkOrError, State1};
-
handle_call(_Request, State) ->
Reply = ok,
{ok, Reply, State}.
%%====================================================================
%%% Internal functions
%%====================================================================
-
-%% how to output
-format(Format, Data) ->
- io:format(Format, Data).
-
-%% convenience
-sformat(Format, Data) ->
- thrift_utils:sformat(Format, Data).
-
-reconfig1(State, Amendments) ->
- case thrift:config(thrift_logger) of
- {value, Config} ->
- Config1 = lists:keysort(1, Config),
- Amendments1 = lists:keysort(1, Amendments),
- Config2 = lists:keymerge(1, Amendments1, Config1),
-
- State1 = State#state{config=Config2},
- {ok, State1};
- _ ->
- {error, State}
- end.
-
-config(Item, State) ->
- case thrift:config(Item, State#state.config) of
- {value, V} ->
- V;
- Else ->
- ?ERROR("config for ~p is unavailable: ~p", [Item, Else])
- end.