You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by da...@apache.org on 2019/12/05 19:35:41 UTC
[couchdb] 08/11: WIP: Trace spans into FDB land
This is an automated email from the ASF dual-hosted git repository.
davisp pushed a commit to branch opentracing-davisp
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 5464e38d645d1a1707c94b0ed2ea117eaae32ef5
Author: Paul J. Davis <pa...@gmail.com>
AuthorDate: Tue Nov 5 17:19:51 2019 -0600
WIP: Trace spans into FDB land
---
src/chttpd/src/chttpd.erl | 12 ++++
src/fabric/src/fabric2_fdb.erl | 11 +++
support/load-fdb-traces.escript | 155 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 178 insertions(+)
diff --git a/src/chttpd/src/chttpd.erl b/src/chttpd/src/chttpd.erl
index a28a33c..956a635 100644
--- a/src/chttpd/src/chttpd.erl
+++ b/src/chttpd/src/chttpd.erl
@@ -151,9 +151,21 @@ stop() ->
catch mochiweb_http:stop(https),
mochiweb_http:stop(?MODULE).
+
+ctrace_id() ->
+ TraceId = hexify(ctrace:get_trace_id()),
+ SpanId = hexify(ctrace:get_span_id()),
+ <<TraceId/binary, ":", SpanId/binary>>.
+
+hexify(Value) ->
+ Bin = binary:encode_unsigned(Value, little),
+ fabric2_util:to_hex(Bin).
+
+
handle_request(MochiReq0) ->
fabric2_fdb:clear_state(),
ctrace:start_span('http.request'),
+ erlang:put(erlfdb_trace, ctrace_id()),
erlang:put(?REWRITE_COUNT, 0),
MochiReq = couch_httpd_vhost:dispatch_host(MochiReq0),
handle_request_int(MochiReq).
diff --git a/src/fabric/src/fabric2_fdb.erl b/src/fabric/src/fabric2_fdb.erl
index 2922a14..2945ee9 100644
--- a/src/fabric/src/fabric2_fdb.erl
+++ b/src/fabric/src/fabric2_fdb.erl
@@ -169,6 +169,17 @@ do_transaction(Fun, LayerPrefix) when is_function(Fun, 1) ->
end.
+ctrace_id() ->
+ TraceId = hexify(ctrace:get_trace_id()),
+ SpanId = hexify(ctrace:get_span_id()),
+ <<TraceId/binary, ":", SpanId/binary, 0:8/integer>>.
+
+
+hexify(Value) ->
+ Bin = ?uint2bin(Value),
+ fabric2_util:to_hex(Bin).
+
+
maybe_reuse_transaction(Db, UserFun) ->
Tx = case get(?PDICT_PREV_TRANSACTION) of
undefined ->
diff --git a/support/load-fdb-traces.escript b/support/load-fdb-traces.escript
new file mode 100755
index 0000000..e3e1354
--- /dev/null
+++ b/support/load-fdb-traces.escript
@@ -0,0 +1,155 @@
+#!/usr/bin/env escript
+%%! -env ERL_LIBS src -noshell -s escript start
+
+-mode(compile).
+
+-export([main/1]).
+
+-define(ANCESTORS_KEY, passage_span_ancestors).
+-define(SPAN_TYPES, [
+ <<"TransactionTrace_Commit">>,
+ <<"TransactionTrace_Get">>,
+ <<"TransactionTrace_GetRange">>,
+ <<"TransactionTrace_GetVersion">>
+]).
+-define(TAG_KEYS, [
+ {<<"Key">>, key},
+ {<<"StartKey">>, 'start-key'},
+ {<<"EndKey">>, 'end-key'},
+ {<<"ValueSizeBytes">>, 'value-size-bytes'},
+ {<<"RangeSizeBytes">>, 'range-size-bytes'},
+ {<<"NumMutations">>, 'num-mutations'},
+ {<<"CommitSizeBytes">>, 'commit-size-bytes'}
+]).
+
+
+main(Args) ->
+ start_apps(),
+ start_tracer(),
+
+ lists:foreach(fun(FileName) ->
+ load_file(FileName)
+ end, Args),
+ timer:sleep(1000).
+
+
+load_file(FileName) ->
+ {ok, Data} = file:read_file(FileName),
+ Lines = binary:split(Data, <<"\r\n">>, [global]),
+ lists:foreach(fun(Line) ->
+ case string:trim(Line) of
+ <<>> ->
+ ok;
+ Else ->
+ {Props} = jiffy:decode(Else),
+ maybe_create_span(Props)
+ end
+ end, Lines).
+
+
+maybe_create_span(Props) ->
+ {_, Type} = lists:keyfind(<<"Type">>, 1, Props),
+ case lists:member(Type, ?SPAN_TYPES) of
+ true ->
+ create_span(Type, Props);
+ false ->
+ ok
+ end.
+
+
+create_span(Type, Props) ->
+ %io:format(standard_error, "~p~n", [Props]),
+ {StartTime, EndTime} = get_time(Props),
+ {TraceId, SpanId} = get_trace_ids(Props),
+ Tags = get_tags(Props),
+
+ fake_root(TraceId, SpanId),
+ passage_pd:start_span(binary_to_atom(Type, utf8), [
+ {time, StartTime},
+ {tags, Tags}
+ ]),
+ passage_pd:finish_span([{time, EndTime}]).
+
+
+get_time(Props) ->
+ {_, EndTimeBin} = lists:keyfind(<<"Time">>, 1, Props),
+ {_, LatencyBin} = lists:keyfind(<<"Latency">>, 1, Props),
+ EndTimeFloat = binary_to_float(EndTimeBin),
+ Latency = binary_to_float(LatencyBin),
+ {float_to_time(EndTimeFloat - Latency), float_to_time(EndTimeFloat)}.
+
+
+float_to_time(Val) ->
+ Mega = trunc(Val / 1000000),
+ Secs = trunc(Val) rem 1000000,
+ Micro = trunc(Val * 1000000) rem 1000000,
+ {Mega, Secs, Micro}.
+
+
+get_trace_ids(Props) ->
+ {_, TxId} = lists:keyfind(<<"TransactionID">>, 1, Props),
+ [TraceIdBin, SpanIdBin] = binary:split(TxId, <<":">>),
+ TraceId = mochihex:to_bin(binary_to_list(TraceIdBin)),
+ SpanId = mochihex:to_bin(binary_to_list(SpanIdBin)),
+ {
+ binary:decode_unsigned(TraceId, little),
+ binary:decode_unsigned(SpanId, little)
+ }.
+
+
+get_tags(Props) ->
+ lists:foldl(fun({BinKey, AtomKey}, Tags) ->
+ case lists:keyfind(BinKey, 1, Props) of
+ {_, Value} ->
+ Tags#{AtomKey => Value};
+ false ->
+ Tags
+ end
+ end, #{}, ?TAG_KEYS).
+
+
+start_apps() ->
+ Apps = [
+ jiffy,
+ passage,
+ jaeger_passage
+ ],
+ lists:foreach(fun(App) ->
+ {ok, _} = application:ensure_all_started(App)
+ end, Apps).
+
+
+start_tracer() ->
+ Sampler = passage_sampler_all:new(),
+ Options = [
+ {thrift_format, compact},
+ {agent_host, "127.0.0.1"},
+ {agent_port, 6831},
+ {default_service_name, 'fdb-client'}
+ ],
+ ok = jaeger_passage:start_tracer(main, Sampler, Options).
+
+
+fake_root(TraceId, SpanId) ->
+ Root = [{child_of, {
+ passage_span,
+ main,
+ foo,
+ {0, 0, 0},
+ undefined,
+ [],
+ #{},
+ [],
+ {
+ passage_span_context,
+ {
+ jaeger_passage_span_context,
+ TraceId,
+ SpanId,
+ true,
+ undefined
+ },
+ #{}
+ }
+ }}],
+ put(?ANCESTORS_KEY, Root).
\ No newline at end of file