PageRenderTime 18ms CodeModel.GetById 1ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/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
 9-module(z_tracer).
10-author('Atilla Erdodi <atilla@maximonster.com>').
11-export([start/0, start/1, stop/0, get_tracer/0]). % API
12-export([do_log/1]). % logger callback function 
13-export([tracefun/2]). % dbg callback function
14
15-include_lib("zotonic.hrl").
16-include_lib("webmachine_logger.hrl").
17
18-define(TRACED_MOD, z_notifier).
19-define(TRACE_OPTS, []).
20
21%% TODO: give information about receiving processes
22%% TODO: do_log callback module for mod_development
23%% TODO: use ttbe insead of dbg
24%% TODO: multi node tracing
25
26
27start() ->
28    start(fun do_log/1).
29
30start(DoLogCallback) when is_function(DoLogCallback) ->
31    dbg:start(),
32    dbg:tracer(process, {fun tracefun/2, {DoLogCallback, 0}}),
33    lists:foreach(fun({F, A}) -> 
34                          dbg:tp(?TRACED_MOD, F, A, ?TRACE_OPTS) 
35                  end, traced_funs()),
36    dbg:p(all, c).
37
38stop() ->
39    dbg:stop_clear().
40
41get_tracer() ->
42    dbg:get_tracer().
43   
44traced_funs() ->
45    [{notify, 2}, {notify1, 2}, 
46     {first, 2}, {map, 2},
47     {foldl, 3}, {foldr, 3}].
48   
49ignored_events() ->
50    [debug, tick_1s].
51
52%% @doc Default callback function for tracefun/2
53do_log({I, Pid, Fun, SessionPid, PagePid, ReqId, Msg}) ->
54    io:format("(~p): ~p ~p :: ~p ~p ~p - ~p\n",
55              [I, Pid, Fun, SessionPid, PagePid, ReqId, Msg]).
56
57%% %doc Callback function for dbg
58tracefun({trace, Pid, call, {?TRACED_MOD, Fun, Args}}, {DoLog, I}) ->
59    {Msg, Context} = 
60        case Args of 
61            [Msg_, Context_] -> {Msg_, Context_};
62            [Msg_, _Acc_, Context_] -> {Msg_, Context_}
63        end,
64    ReqData = z_context:get_reqdata(Context),
65    ReqId = case ReqData of
66                undefined -> undefined;
67                        _ -> (ReqData#wm_reqdata.log_data)#wm_log_data.req_id
68            end,
69    EventType = if  is_tuple(Msg) -> element(1, Msg);
70                    is_atom(Msg) -> Msg
71                end,
72    case lists:member(EventType, ignored_events()) of
73        true ->
74            {DoLog, I};
75        false ->
76            {SessionPid, PagePid, ReqId} = 
77                {Context#context.session_pid,
78                 Context#context.page_pid,
79                 ReqId}, 
80            DoLog({I, Pid, Fun, SessionPid, PagePid, ReqId, Msg}),
81            {DoLog, I + 1}
82    end;    
83tracefun(_, {DoLog, I}) ->
84    io:format("Ups!\n"),
85    {DoLog, I}.