Просмотр исходного кода

Initialize trace patterns only once

They are global for the node for all future call trace flags,
so it's not necessary to set them repeatedly with every request.

Doing it once at startup also ensures we can't have race
conditions when the user wants to change which trace patterns
should be used (because requests are concurrent and patterns
end up overwriting themselves repeatedly), and makes this
changing of trace patterns much more straightforward: the
user can just define the ones they want. The default function
traces everything.

In addition I have also added the tracer_flags option to make
the trace flags configurable, excluding the tracer pid.
Loïc Hoguin 7 лет назад
Родитель
Сommit
ce5ab4b49a
2 измененных файлов с 22 добавлено и 5 удалено
  1. 19 5
      src/cowboy_tracer_h.erl
  2. 3 0
      test/tracer_SUITE.erl

+ 19 - 5
src/cowboy_tracer_h.erl

@@ -21,6 +21,8 @@
 -export([terminate/3]).
 -export([early_error/5]).
 
+-export([set_trace_patterns/0]).
+
 -export([tracer_process/3]).
 -export([system_continue/3]).
 -export([system_terminate/4]).
@@ -66,6 +68,15 @@ terminate(StreamID, Reason, Next) ->
 early_error(StreamID, Reason, PartialReq, Resp, Opts) ->
 	cowboy_stream:early_error(StreamID, Reason, PartialReq, Resp, Opts).
 
+%% API.
+
+%% These trace patterns are most likely not suitable for production.
+-spec set_trace_patterns() -> ok.
+set_trace_patterns() ->
+	erlang:trace_pattern({'_', '_', '_'}, [{'_', [], [{return_trace}]}], [local]),
+	erlang:trace_pattern(on_load, [{'_', [], [{return_trace}]}], [local]),
+	ok.
+
 %% Internal.
 
 init_tracer(StreamID, Req, Opts=#{tracer_match_specs := List, tracer_callback := _}) ->
@@ -119,12 +130,15 @@ start_tracer(StreamID, Req, Opts) ->
 	case erlang:trace_info(self(), tracer) of
 		{tracer, []} ->
 			TracerPid = proc_lib:spawn_link(?MODULE, tracer_process, [StreamID, Req, Opts]),
-			erlang:trace_pattern({'_', '_', '_'}, [{'_', [], [{return_trace}]}], [local]),
-			erlang:trace_pattern(on_load, [{'_', [], [{return_trace}]}], [local]),
-			erlang:trace(self(), true, [
-				send, 'receive', call, return_to, procs, ports,
-				monotonic_timestamp, set_on_spawn, {tracer, TracerPid}
+			%% The default flags are probably not suitable for production.
+			Flags = maps:get(tracer_flags, Opts, [
+				send, 'receive', call, return_to,
+				procs, ports, monotonic_timestamp,
+				%% The set_on_spawn flag is necessary to catch events
+				%% from request processes.
+				set_on_spawn
 			]),
+			erlang:trace(self(), true, [{tracer, TracerPid}|Flags]),
 			ok;
 		_ ->
 			ok

+ 3 - 0
test/tracer_SUITE.erl

@@ -22,7 +22,10 @@
 
 %% ct.
 
+%% We initialize trace patterns here. Appropriate would be in
+%% init_per_suite/1, but this works just as well.
 all() ->
+	cowboy_tracer_h:set_trace_patterns(),
 	cowboy_test:common_all().
 
 %% We want tests for each group to execute sequentially