You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ii...@apache.org on 2019/10/01 18:08:25 UTC

[couchdb] 02/08: Identify tracing span life cycle

This is an automated email from the ASF dual-hosted git repository.

iilyak pushed a commit to branch opentracing
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 2e00ea8abbc670e29b810bdec8d9498c512ab119
Author: ILYA Khlopotov <ii...@apache.org>
AuthorDate: Wed Sep 25 12:17:28 2019 +0000

    Identify tracing span life cycle
    
    A note for curious observer:
      We wouldn't be finishing a span on exit because we don't
      want to spam our trace collector with client disconnects.
      The open tracing library handles this case just fine.
---
 src/chttpd/src/chttpd.erl | 46 ++++++++++++++++++++++++++++++++++++----------
 1 file changed, 36 insertions(+), 10 deletions(-)

diff --git a/src/chttpd/src/chttpd.erl b/src/chttpd/src/chttpd.erl
index e4ddb6a..704e203 100644
--- a/src/chttpd/src/chttpd.erl
+++ b/src/chttpd/src/chttpd.erl
@@ -157,6 +157,7 @@ handle_request(MochiReq0) ->
     handle_request_int(MochiReq).
 
 handle_request_int(MochiReq) ->
+    Span = start_span(),
     Begin = os:timestamp(),
     case config:get("chttpd", "socket_options") of
     undefined ->
@@ -231,6 +232,8 @@ handle_request_int(MochiReq) ->
                 || Part <- string:tokens(RequestedPath, "/")]
     },
 
+    HttpReq1 = attach_span(HttpReq0, Span),
+
     % put small token on heap to keep requests synced to backend calls
     erlang:put(nonce, Nonce),
 
@@ -238,11 +241,11 @@ handle_request_int(MochiReq) ->
     erlang:put(dont_log_request, true),
     erlang:put(dont_log_response, true),
 
-    {HttpReq2, Response} = case before_request(HttpReq0) of
-        {ok, HttpReq1} ->
-            process_request(HttpReq1);
+    {HttpReq3, Response} = case before_request(HttpReq1) of
+        {ok, HttpReq2} ->
+            process_request(HttpReq2);
         {error, Response0} ->
-            {HttpReq0, Response0}
+            {HttpReq1, Response0}
     end,
 
     {Status, Code, Reason, Resp} = split_response(Response),
@@ -251,12 +254,13 @@ handle_request_int(MochiReq) ->
         code = Code,
         status = Status,
         response = Resp,
-        nonce = HttpReq2#httpd.nonce,
+        nonce = HttpReq3#httpd.nonce,
         reason = Reason
     },
 
-    case after_request(HttpReq2, HttpResp) of
+    case after_request(HttpReq3, HttpResp) of
         #httpd_resp{status = ok, response = Resp} ->
+            finish_span(HttpReq3, span_ok(HttpResp)),
             {ok, Resp};
         #httpd_resp{status = aborted, reason = Reason} ->
             couch_log:error("Response abnormally terminated: ~p", [Reason]),
@@ -1048,16 +1052,20 @@ send_error(#httpd{} = Req, Code, ErrorStr, ReasonStr) ->
     send_error(Req, Code, [], ErrorStr, ReasonStr, []).
 
 send_error(Req, Code, Headers, ErrorStr, ReasonStr, []) ->
-    send_json(Req, Code, Headers,
+    Return = send_json(Req, Code, Headers,
         {[{<<"error">>,  ErrorStr},
-        {<<"reason">>, ReasonStr}]});
+        {<<"reason">>, ReasonStr}]}),
+    finish_span(Req, span_error(ErrorStr, ReasonStr, [])),
+    Return;
 send_error(Req, Code, Headers, ErrorStr, ReasonStr, Stack) ->
     log_error_with_stack_trace({ErrorStr, ReasonStr, Stack}),
-    send_json(Req, Code, [stack_trace_id(Stack) | Headers],
+    Return = send_json(Req, Code, [stack_trace_id(Stack) | Headers],
         {[{<<"error">>,  ErrorStr},
         {<<"reason">>, ReasonStr} |
         case Stack of [] -> []; _ -> [{<<"ref">>, stack_hash(Stack)}] end
-    ]}).
+    ]}),
+    finish_span(Req, span_error(ErrorStr, ReasonStr, [])),
+    Return.
 
 update_timeout_stats(<<"timeout">>, #httpd{requested_path_parts = PathParts}) ->
     update_timeout_stats(PathParts);
@@ -1211,6 +1219,24 @@ get_user(#httpd{user_ctx = #user_ctx{name = User}}) ->
 get_user(#httpd{user_ctx = undefined}) ->
     "undefined".
 
+start_span() ->
+    span.
+
+attach_span(Req, _Span) ->
+    Req.
+
+trace(Req, _Fun) ->
+    Req.
+
+finish_span(_Req, _Fun) ->
+    ok.
+
+span_ok(_Resp) ->
+    fun(Span) -> Span end.
+
+span_error(_ErrorStr, _ReasonStr, []) ->
+    fun(Span) -> Span end.
+
 -ifdef(TEST).
 
 -include_lib("eunit/include/eunit.hrl").