/src/support/z_tracer.erl

https://code.google.com/p/zotonic/ · Erlang · 85 lines · 59 code · 13 blank · 13 comment · 1 complexity · 3e6b8670280b4797c4c42597dea639b2 MD5 · raw file

  1. %% @doc Simple tool for ad-hoc tracing of Zotonic. Since the module
  2. %% z_notifier, serves as an internal message router, tracing on
  3. %% specific calls of the module is enough to monitor the internals
  4. %% of zotonic. Trace messages are logged to stdout by default, but
  5. %% a custom callback function can be specified.
  6. %% @author Atilla Erdodi <atilla@maximonster.com>
  7. %% @copyright 2010 Maximonster Interactive Things
  8. -module(z_tracer).
  9. -author('Atilla Erdodi <atilla@maximonster.com>').
  10. -export([start/0, start/1, stop/0, get_tracer/0]). % API
  11. -export([do_log/1]). % logger callback function
  12. -export([tracefun/2]). % dbg callback function
  13. -include_lib("zotonic.hrl").
  14. -include_lib("webmachine_logger.hrl").
  15. -define(TRACED_MOD, z_notifier).
  16. -define(TRACE_OPTS, []).
  17. %% TODO: give information about receiving processes
  18. %% TODO: do_log callback module for mod_development
  19. %% TODO: use ttbe insead of dbg
  20. %% TODO: multi node tracing
  21. start() ->
  22. start(fun do_log/1).
  23. start(DoLogCallback) when is_function(DoLogCallback) ->
  24. dbg:start(),
  25. dbg:tracer(process, {fun tracefun/2, {DoLogCallback, 0}}),
  26. lists:foreach(fun({F, A}) ->
  27. dbg:tp(?TRACED_MOD, F, A, ?TRACE_OPTS)
  28. end, traced_funs()),
  29. dbg:p(all, c).
  30. stop() ->
  31. dbg:stop_clear().
  32. get_tracer() ->
  33. dbg:get_tracer().
  34. traced_funs() ->
  35. [{notify, 2}, {notify1, 2},
  36. {first, 2}, {map, 2},
  37. {foldl, 3}, {foldr, 3}].
  38. ignored_events() ->
  39. [debug, tick_1s].
  40. %% @doc Default callback function for tracefun/2
  41. do_log({I, Pid, Fun, SessionPid, PagePid, ReqId, Msg}) ->
  42. io:format("(~p): ~p ~p :: ~p ~p ~p - ~p\n",
  43. [I, Pid, Fun, SessionPid, PagePid, ReqId, Msg]).
  44. %% %doc Callback function for dbg
  45. tracefun({trace, Pid, call, {?TRACED_MOD, Fun, Args}}, {DoLog, I}) ->
  46. {Msg, Context} =
  47. case Args of
  48. [Msg_, Context_] -> {Msg_, Context_};
  49. [Msg_, _Acc_, Context_] -> {Msg_, Context_}
  50. end,
  51. ReqData = z_context:get_reqdata(Context),
  52. ReqId = case ReqData of
  53. undefined -> undefined;
  54. _ -> (ReqData#wm_reqdata.log_data)#wm_log_data.req_id
  55. end,
  56. EventType = if is_tuple(Msg) -> element(1, Msg);
  57. is_atom(Msg) -> Msg
  58. end,
  59. case lists:member(EventType, ignored_events()) of
  60. true ->
  61. {DoLog, I};
  62. false ->
  63. {SessionPid, PagePid, ReqId} =
  64. {Context#context.session_pid,
  65. Context#context.page_pid,
  66. ReqId},
  67. DoLog({I, Pid, Fun, SessionPid, PagePid, ReqId, Msg}),
  68. {DoLog, I + 1}
  69. end;
  70. tracefun(_, {DoLog, I}) ->
  71. io:format("Ups!\n"),
  72. {DoLog, I}.