Add dedicated monitor processes option
diff --git a/src/couch_stats/src/couch_stats_resource_tracker.erl b/src/couch_stats/src/couch_stats_resource_tracker.erl
index bdedd81..2774f7f 100644
--- a/src/couch_stats/src/couch_stats_resource_tracker.erl
+++ b/src/couch_stats/src/couch_stats_resource_tracker.erl
@@ -48,7 +48,8 @@
     set_context_dbname/1,
     set_context_handler_fun/1,
     set_context_username/1,
-    track/1,
+    track/1, tracker/1,
+    stop_tracker/0, stop_tracker/1, stop_tracker/2,
     should_track/1
 ]).
 
@@ -140,6 +141,7 @@
 -define(DELTA_TA, csrt_delta_ta).
 -define(DELTA_TZ, csrt_delta_tz). %% T Zed instead of T0
 -define(PID_REF, csrt_pid_ref). %% track local ID
+-define(TRACKER_PID, csrt_tracker). %% tracker pid
 
 
 -record(st, {
@@ -675,6 +677,7 @@
 destroy_context(undefined) ->
     ok;
 destroy_context({_, _} = PidRef) ->
+    stop_tracker(PidRef),
     close_pid_ref(PidRef),
     gen_server:cast(?MODULE, {destroy, PidRef}),
     ok.
@@ -800,11 +803,80 @@
             end
     end.
 
-track(#rctx{pid_ref=PidRef}) ->
+track(#rctx{}=Rctx) ->
+    case conf_get("spawn_monitor", "true") of
+        "true" ->
+            track(Rctx, spawn_monitor);
+        _ ->
+            track(Rctx, gen_server)
+    end.
+
+track(#rctx{pid_ref=PidRef}, spawn_monitor) ->
+    case get_tracker() of
+        undefined ->
+            Pid = spawn(?MODULE, tracker, [PidRef]),
+            put_tracker(Pid);
+        Pid when is_pid(Pid) ->
+            Pid
+    end;
+track(#rctx{pid_ref=PidRef}, gen_server) ->
     %% TODO: should this block or not? If no, what cleans up zombies?
     %% gen_server:call(?MODULE, {track, PR}).
     gen_server:cast(?MODULE, {track, PidRef}).
 
+get_tracker() ->
+    get(?TRACKER_PID).
+
+put_tracker(Pid) when is_pid(Pid) ->
+    put(?TRACKER_PID, Pid).
+
+tracker({Pid, _Ref}=PidRef) ->
+    MonRef = erlang:monitor(process, Pid),
+    should_scan() andalso catch ets:update_element(?MODULE, PidRef, [{#rctx.mon_ref, MonRef}]),
+    receive
+        stop ->
+            %% TODO: do we need cleanup here?
+            %%cleanup_tracker(PidRef, <<"shutdown:stopped">>),
+            demonitor(MonRef),
+            ok;
+        {'DOWN', MonRef, _Type, _0DPid, Reason0} ->
+            Reason = case Reason0 of
+                {shutdown, Shutdown0} ->
+                    Shutdown = atom_to_binary(Shutdown0),
+                    <<"shutdown: ", Shutdown/binary>>;
+                Reason0 ->
+                    Reason0
+            end,
+            cleanup_tracker(PidRef, Reason)
+    end.
+
+cleanup_tracker(PidRef, Reason) ->
+    case is_logging_enabled() andalso get_resource(PidRef) of
+        #rctx{} = Rctx ->
+            should_log(Rctx) andalso log_process_lifetime_report(PidRef, Rctx);
+        _ ->
+            ok
+    end,
+    %% update stats
+    should_scan() andalso catch ets:update_element(?MODULE, PidRef,
+            [{#rctx.state, {down, Reason}}, {#rctx.updated_at, tnow()}]),
+    catch evict(PidRef).
+
+
+stop_tracker() ->
+    stop_tracker(get_tracker(), get_pid_ref()).
+
+stop_tracker({_Pid, _Ref}=PidRef) ->
+    stop_tracker(get_tracker(), PidRef);
+stop_tracker(Pid) when is_pid(Pid) ->
+    stop_tracker(Pid, get_pid_ref()).
+
+stop_tracker(undefined, _) ->
+    ok;
+stop_tracker(Pid, PidRef) ->
+    should_scan() andalso catch ets:update_element(?MODULE, PidRef, [{#rctx.mon_ref, undefined}]),
+    Pid ! stop.
+
 
 make_delta() ->
     TA = case get(?DELTA_TA) of
@@ -916,9 +988,6 @@
     catch get_resource_int(PidRef).
 
 
-get_resource_int() ->
-    get_resource_int(get_pid_ref()).
-
 get_resource_int(undefined) ->
     undefined;
 get_resource_int(PidRef) ->
@@ -1100,12 +1169,13 @@
     case is_enabled() andalso is_logging_enabled() of
         true ->
             Rctx = get_resource_int(PidRef),
-            should_log(Rctx) andalso
-                couch_log:report("csrt-pid-usage-lifetime", to_flat_json(Rctx));
+            should_log(Rctx) andalso log_process_lifetime_report(PidRef, Rctx);
         false ->
             ok
     end.
 
+log_process_lifetime_report(_PidRef, Rctx) ->
+    couch_log:report("csrt-pid-usage-lifetime", to_flat_json(Rctx)).
 
 is_logging_enabled() ->
     logging_enabled() =/= false.
@@ -1121,10 +1191,14 @@
     end.
 
 
+should_log(undefined) ->
+    false;
 should_log(#rctx{}=Rctx) ->
     should_log(Rctx, logging_enabled()).
 
 
+should_log(undefined, _) ->
+    false;
 should_log(#rctx{}, true) ->
     true;
 should_log(#rctx{}, false) ->