Skip to content

Commit 96229b8

Browse files
ttt161ttt161WWWcool
authored
Epic/process tracing (#196)
* WIP: add handle functions * add tracing endpoints * fixed * bump progressor * cleanup * fix typo * fix timers * bump progressor * cleanup * bump progressor * fix issues --------- Co-authored-by: ttt161 <losto@nix> Co-authored-by: Артем <WWW_cool@inbox.ru>
1 parent cec8ef0 commit 96229b8

11 files changed

Lines changed: 555 additions & 10 deletions

apps/hellgate/src/hellgate.erl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ get_api_child_spec(MachineHandlers, Opts) ->
6464
construct_health_routes(readiness, genlib_app:env(?MODULE, health_check_readiness, #{})),
6565
EventHandlerOpts = genlib_app:env(?MODULE, scoper_event_handler_options, #{}),
6666
PrometeusRoute = get_prometheus_route(),
67+
ProcessTracingRoute = hg_progressor_handler:get_routes(),
6768
woody_server:child_spec(
6869
?MODULE,
6970
#{
@@ -78,7 +79,7 @@ get_api_child_spec(MachineHandlers, Opts) ->
7879
construct_service_handler(invoice_templating, hg_invoice_template, Opts),
7980
construct_service_handler(proxy_host_provider, hg_proxy_host_provider, Opts)
8081
],
81-
additional_routes => [PrometeusRoute | HealthRoutes],
82+
additional_routes => [PrometeusRoute | HealthRoutes] ++ ProcessTracingRoute,
8283
shutdown_timeout => genlib_app:env(?MODULE, shutdown_timeout, 0)
8384
}
8485
).

apps/hellgate/src/hg_invoice.erl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
-export([get_payment_opts/1]).
4141
-export([create/6]).
4242
-export([marshal_invoice/1]).
43+
-export([unmarshal_invoice/1]).
4344
-export([unmarshal_history/1]).
4445
-export([collapse_history/1]).
4546

apps/hellgate/src/hg_invoice_template.erl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
%% API
2727

2828
-export([get/1]).
29+
-export([unmarshal_invoice_template_params/1]).
2930

3031
-type tpl_id() :: dmsl_domain_thrift:'InvoiceTemplateID'().
3132
-type tpl() :: dmsl_domain_thrift:'InvoiceTemplate'().

apps/hellgate/test/hg_invoice_lite_tests_SUITE.erl

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
-export([payment_success_empty_cvv/1]).
2828
-export([payment_has_optional_fields/1]).
2929
-export([payment_last_trx_correct/1]).
30+
-export([payment_success_trace/1]).
3031

3132
-type config() :: hg_ct_helper:config().
3233
-type test_case_name() :: hg_ct_helper:test_case_name().
@@ -63,6 +64,7 @@ groups() ->
6364
{payments, [parallel], [
6465
payment_start_idempotency,
6566
payment_success,
67+
payment_success_trace,
6668
payment_w_first_blacklisted_success,
6769
payment_w_all_blacklisted,
6870
register_payment_success,
@@ -241,6 +243,7 @@ payment_success(C) ->
241243
},
242244
Payment
243245
),
246+
244247
?assertMatch(
245248
#domain_TransactionInfo{
246249
extra = #{
@@ -250,6 +253,158 @@ payment_success(C) ->
250253
Trx
251254
).
252255

256+
-spec payment_success_trace(config()) -> test_return().
257+
payment_success_trace(C) ->
258+
Client = cfg(client, C),
259+
InvoiceID = start_invoice(<<"rubberduck">>, make_due_date(10), 42000, C),
260+
Context = #base_Content{
261+
type = <<"application/x-erlang-binary">>,
262+
data = erlang:term_to_binary({you, 643, "not", [<<"welcome">>, here]})
263+
},
264+
PayerSessionInfo = #domain_PayerSessionInfo{
265+
redirect_url = <<"https://redirectly.io/merchant">>
266+
},
267+
PaymentParams = (make_payment_params(?pmt_sys(<<"visa-ref">>)))#payproc_InvoicePaymentParams{
268+
payer_session_info = PayerSessionInfo,
269+
context = Context
270+
},
271+
PaymentID = process_payment(InvoiceID, PaymentParams, Client),
272+
PaymentID = await_payment_capture(InvoiceID, PaymentID, Client),
273+
274+
RootUrl = unicode:characters_to_binary(cfg(root_url, C)),
275+
UrlInternal = <<RootUrl/binary, "/traces/internal/invoice/", InvoiceID/binary>>,
276+
UrlJaeger = <<RootUrl/binary, "/traces/jaeger/invoice/", InvoiceID/binary>>,
277+
{ok, _Status, _Headers, RefInternal} = hackney:get(UrlInternal),
278+
{ok, BodyInternal} = hackney:body(RefInternal),
279+
[
280+
#{
281+
<<"args">> := #{
282+
<<"content_type">> := <<"thrift_call">>,
283+
<<"content">> := #{
284+
<<"call">> := #{
285+
<<"function">> := <<"Create">>,
286+
<<"service">> := <<"Invoicing">>
287+
},
288+
<<"params">> := _
289+
}
290+
},
291+
<<"error">> := null,
292+
<<"events">> := [
293+
#{
294+
<<"event_id">> := 1,
295+
<<"event_payload">> := _,
296+
<<"event_timestamp">> := _
297+
}
298+
],
299+
<<"finished">> := _,
300+
<<"otel_trace_id">> := _,
301+
<<"retry_attempts">> := 0,
302+
<<"retry_interval">> := 0,
303+
<<"running">> := _,
304+
<<"scheduled">> := _,
305+
<<"task_id">> := _,
306+
<<"task_metadata">> := #{<<"range">> := #{}},
307+
<<"task_status">> := <<"finished">>,
308+
<<"task_type">> := <<"init">>
309+
},
310+
#{<<"task_type">> := <<"call">>, <<"task_status">> := <<"finished">>},
311+
#{<<"task_type">> := <<"timeout">>, <<"task_status">> := <<"finished">>},
312+
#{<<"task_type">> := <<"timeout">>, <<"task_status">> := <<"finished">>},
313+
#{<<"task_type">> := <<"timeout">>, <<"task_status">> := <<"finished">>},
314+
#{<<"task_type">> := <<"timeout">>, <<"task_status">> := <<"finished">>},
315+
#{<<"task_type">> := <<"timeout">>, <<"task_status">> := <<"finished">>},
316+
#{<<"task_type">> := <<"timeout">>, <<"task_status">> := <<"finished">>},
317+
#{<<"task_type">> := <<"timeout">>, <<"task_status">> := <<"finished">>},
318+
#{<<"task_type">> := <<"timeout">>, <<"task_status">> := <<"finished">>},
319+
#{<<"task_type">> := <<"timeout">>, <<"task_status">> := <<"finished">>},
320+
#{<<"task_type">> := <<"timeout">>, <<"task_status">> := <<"finished">>},
321+
#{<<"task_type">> := <<"timeout">>, <<"task_status">> := <<"finished">>},
322+
#{<<"task_type">> := <<"timeout">>, <<"task_status">> := <<"finished">>},
323+
#{<<"task_type">> := <<"timeout">>, <<"task_status">> := <<"cancelled">>}
324+
] = json:decode(BodyInternal),
325+
{ok, _Status2, _Headers2, RefJaeger} = hackney:get(UrlJaeger),
326+
{ok, BodyJaeger} = hackney:body(RefJaeger),
327+
#{
328+
<<"data">> := [
329+
#{
330+
<<"traceId">> := _,
331+
<<"processes">> := #{
332+
InvoiceID := #{
333+
<<"service_name">> := <<"hellgate_invoice">>,
334+
<<"tags">> := []
335+
}
336+
},
337+
<<"spans">> := [
338+
#{
339+
<<"operationName">> := <<"init">>,
340+
<<"process">> := #{
341+
<<"service_name">> := <<"hellgate_invoice">>,
342+
<<"tags">> := []
343+
},
344+
<<"processID">> := InvoiceID,
345+
<<"spanId">> := _,
346+
<<"traceId">> := _,
347+
<<"startTime">> := _,
348+
<<"duration">> := _,
349+
<<"tags">> := [
350+
#{
351+
<<"key">> := <<"task.status">>,
352+
<<"type">> := <<"string">>,
353+
<<"value">> := <<"finished">>
354+
},
355+
#{
356+
<<"key">> := <<"task.retries">>,
357+
<<"type">> := <<"int64">>,
358+
<<"value">> := 0
359+
},
360+
#{
361+
<<"key">> := <<"task.input">>,
362+
<<"type">> := <<"string">>,
363+
<<"value">> := _NestedJsonArgs
364+
}
365+
],
366+
<<"logs">> := [
367+
#{
368+
<<"timestamp">> := _,
369+
<<"fields">> := [
370+
#{
371+
<<"key">> := <<"event.id">>,
372+
<<"type">> := <<"int64">>,
373+
<<"value">> := 1
374+
},
375+
#{
376+
<<"key">> := <<"event.payload">>,
377+
<<"type">> := <<"string">>,
378+
<<"value">> := _NestedJsonEvent
379+
}
380+
]
381+
}
382+
]
383+
},
384+
#{<<"operationName">> := <<"call">>},
385+
#{<<"operationName">> := <<"timeout">>},
386+
#{<<"operationName">> := <<"timeout">>},
387+
#{<<"operationName">> := <<"timeout">>},
388+
#{<<"operationName">> := <<"timeout">>},
389+
#{<<"operationName">> := <<"timeout">>},
390+
#{<<"operationName">> := <<"timeout">>},
391+
#{<<"operationName">> := <<"timeout">>},
392+
#{<<"operationName">> := <<"timeout">>},
393+
#{<<"operationName">> := <<"timeout">>},
394+
#{<<"operationName">> := <<"timeout">>},
395+
#{<<"operationName">> := <<"timeout">>},
396+
#{<<"operationName">> := <<"timeout">>},
397+
#{<<"operationName">> := <<"timeout">>}
398+
]
399+
}
400+
]
401+
} = json:decode(BodyJaeger),
402+
BadInvoiceUrl = <<RootUrl/binary, "/traces/internal/invoice/UnknownInvoice">>,
403+
{ok, 404, _, _} = hackney:get(BadInvoiceUrl),
404+
BadFormatUrl = <<RootUrl/binary, "/traces/external/invoice/", InvoiceID/binary>>,
405+
{ok, 400, _, _} = hackney:get(BadFormatUrl),
406+
ok.
407+
253408
-spec payment_w_first_blacklisted_success(config()) -> test_return().
254409
payment_w_first_blacklisted_success(C) ->
255410
Client = cfg(client, C),

apps/hg_progressor/src/hg_progressor.erl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ marshal(status, {<<"running">>, _Detail}) ->
273273
marshal(status, {<<"error">>, Detail}) ->
274274
{'failed', #mg_stateproc_MachineStatusFailed{reason = Detail}};
275275
marshal(timestamp, Timestamp) ->
276-
unicode:characters_to_binary(calendar:system_time_to_rfc3339(Timestamp, [{offset, "Z"}]));
276+
unicode:characters_to_binary(calendar:system_time_to_rfc3339(Timestamp, [{offset, "Z"}, {unit, microsecond}]));
277277
marshal(term, Term) ->
278278
binary_to_term(Term);
279279
marshal(function, init) ->
@@ -315,7 +315,7 @@ unmarshal(events, {undefined, _ID}) ->
315315
unmarshal(events, {[], _}) ->
316316
[];
317317
unmarshal(events, {Events, LastEventID}) ->
318-
Ts = erlang:system_time(second),
318+
Ts = erlang:system_time(microsecond),
319319
lists:foldl(
320320
fun(#mg_stateproc_Content{format_version = Ver, data = Payload}, Acc) ->
321321
PrevID =
@@ -349,7 +349,7 @@ unmarshal(action, #mg_stateproc_ComplexAction{
349349
remove = RemoveAction
350350
}) when Timeout =/= undefined ->
351351
genlib_map:compact(#{
352-
set_timer => erlang:system_time(second) + Timeout,
352+
set_timer => erlang:system_time(microsecond) + (Timeout * 1000000),
353353
remove => maybe_unmarshal(remove_action, RemoveAction)
354354
});
355355
unmarshal(action, #mg_stateproc_ComplexAction{timer = {unset_timer, #'mg_stateproc_UnsetTimerAction'{}}}) ->
@@ -359,9 +359,9 @@ unmarshal(action, #mg_stateproc_ComplexAction{remove = #mg_stateproc_RemoveActio
359359
unmarshal(action, #mg_stateproc_ComplexAction{remove = undefined}) ->
360360
undefined;
361361
unmarshal(timer, {deadline, DateTimeRFC3339}) ->
362-
calendar:rfc3339_to_system_time(unicode:characters_to_list(DateTimeRFC3339), [{unit, second}]);
362+
calendar:rfc3339_to_system_time(unicode:characters_to_list(DateTimeRFC3339), [{unit, microsecond}]);
363363
unmarshal(timer, {timeout, Timeout}) ->
364-
erlang:system_time(second) + Timeout;
364+
erlang:system_time(microsecond) + (Timeout * 1000000);
365365
unmarshal(term, Term) ->
366366
erlang:term_to_binary(Term);
367367
unmarshal(remove_action, #mg_stateproc_RemoveAction{}) ->

0 commit comments

Comments
 (0)