Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 18 additions & 25 deletions apps/capi/src/capi_otel_middleware.erl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
-module(capi_otel_middleware).

%% TODO Adopt https://github.com/cogini/opentelemetry_xray
-include_lib("opentelemetry_api/include/opentelemetry.hrl").

-behaviour(cowboy_middleware).

Expand Down Expand Up @@ -55,35 +56,27 @@ extract(Ctx, Carrier, _CarrierKeysFun, CarrierGet, _Options) ->
undefined ->
Ctx;
XRayTrace ->
case decode(string:trim(XRayTrace)) of
SpanCtx0 = otel_tracer:from_remote_span(0, 0, 0),
SpanCtx1 = lists:foldl(fun decode/2, SpanCtx0, string:split(string:trim(XRayTrace), ";", all)),
case SpanCtx1 of
undefined ->
Ctx;
SpanCtx ->
otel_tracer:set_current_span(Ctx, SpanCtx)
_ ->
otel_tracer:set_current_span(Ctx, SpanCtx1)
end
end.

%%

decode(
%% NOTE Version is expected to be always single char "1"
<<"Root=", _Version:1/binary, "-", Timestamp:8/binary, "-", RootId:24/binary, ";Parent=", ParentId:16/binary,
";Sampled=", Sampled:1/binary, _/binary>>
) ->
try
TraceId = binary_to_integer(<<Timestamp/binary, RootId/binary>>, 16),
SpanId = binary_to_integer(ParentId, 16),
TraceFlags =
case Sampled of
<<"1">> -> 1;
<<"0">> -> 0;
_ -> error(badarg)
end,
otel_tracer:from_remote_span(TraceId, SpanId, TraceFlags)
catch
%% to integer from base 16 string failed
error:badarg ->
undefined
end;
decode(_) ->
undefined.
decode(<<"Root=1-", Timestamp:8/binary, "-", RootId:24/binary>>, SpanCtx) ->
TraceId = binary_to_integer(<<Timestamp/binary, RootId/binary>>, 16),
SpanCtx#span_ctx{trace_id = TraceId, hex_trace_id = otel_utils:encode_hex(<<TraceId:128>>)};
decode(<<"Parent=", ParentId:16/binary>>, SpanCtx) ->
SpanId = binary_to_integer(ParentId, 16),
SpanCtx#span_ctx{span_id = SpanId, hex_span_id = otel_utils:encode_hex(<<SpanId:64>>)};
decode(<<"Sampled=0">>, SpanCtx) ->
SpanCtx#span_ctx{trace_flags = 0};
decode(<<"Sampled=1">>, SpanCtx) ->
SpanCtx#span_ctx{trace_flags = 1};
decode(_Value, SpanCtx) ->
SpanCtx.
87 changes: 52 additions & 35 deletions apps/capi/test/capi_self_tests_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ init([]) ->
all() ->
[
{group, stream_handler_tests},
{group, validation_tests}
{group, validation_tests},
{group, middleware_tests}
].

-spec groups() -> [{group_name(), list(), [test_case_name()]}].
Expand Down Expand Up @@ -96,41 +97,10 @@ end_per_group(_Group, C) ->
ok.

-spec init_per_testcase(test_case_name(), config()) -> config().
init_per_testcase(amzn_xray_header_for_otel_ctx, C) ->
AmznXrayTraceId = <<"1-67891233-abcdef012345678912345678">>,
ExpectedTraceId = "67891233abcdef012345678912345678",
meck:expect(capi_client_lib, make_request, fun(Context, Params) ->
{Url, PreparedParams, Opts} = meck:passthrough([Context, Params]),
UpdFun = fun(Headers) ->
Headers#{
<<"X-Amzn-Trace-Id">> =>
<<"Root=", AmznXrayTraceId/binary, ";Parent=53995c3f42cd8ad8;Sampled=1">>
}
end,
{Url, maps:update_with(header, UpdFun, PreparedParams), Opts}
end),
TestProcess = self(),
meck:expect(otel_ctx, get_current, fun() ->
OtelCtx = meck:passthrough([]),
SpanCtx = otel_tracer:current_span_ctx(OtelCtx),
TestProcess ! {otel_span_info, otel_span:hex_span_ctx(SpanCtx)},
OtelCtx
end),
[
{amzn_xray_trace_id, AmznXrayTraceId},
{expected_trace_id, ExpectedTraceId},
{test_sup, capi_ct_helper:start_mocked_service_sup(?MODULE)}
| C
];
init_per_testcase(_Name, C) ->
[{test_sup, capi_ct_helper:start_mocked_service_sup(?MODULE)} | C].

-spec end_per_testcase(test_case_name(), config()) -> _.
end_per_testcase(amzn_xray_header_for_otel_ctx, C) ->
_ = capi_ct_helper:stop_mocked_service_sup(?config(test_sup, C)),
meck:unload(otel_ctx),
meck:unload(capi_client_lib),
ok;
end_per_testcase(_Name, C) ->
_ = capi_ct_helper:stop_mocked_service_sup(?config(test_sup, C)),
ok.
Expand Down Expand Up @@ -184,9 +154,56 @@ query_param_validation(Config) ->

-spec amzn_xray_header_for_otel_ctx(config()) -> _.
amzn_xray_header_for_otel_ctx(Config) ->
_ = oops_body_test(Config),
ExpectedTraceId = ?config(expected_trace_id, Config),
?assertMatch(#{otel_trace_id := ExpectedTraceId}, await_latest_otel_span_info(1_000, #{})).
_ = capi_ct_helper:mock_services([{invoicing, fun('Get', _) -> {ok, "spanish inquisition"} end}], Config),
Fixtures = [
{
"Root=1-67891233-abcdef012345678912345678;Parent=53995c3f42cd8ad8;Sampled=1",
"67891233abcdef012345678912345678"
},

{
"Sampled=1;Root=1-67891233-abcdef012345678912345678;Parent=53995c3f42cd8ad8",
"67891233abcdef012345678912345678"
},
{
"Root=1-67891233-abcdef012345678912345678;Sampled=1",
"67891233abcdef012345678912345678"
},
{
"Root=1-67891233-abcdef012345678912345678;whatever",
"67891233abcdef012345678912345678"
},
{
"Root=1-67891233-abcdef012345678912345678",
"67891233abcdef012345678912345678"
}
],
Fun = fun() ->
capi_client_invoices:get_invoice_events(?config(context, Config), ?STRING, 1)
end,
[assert_trace_based_on_header(Header, TraceId, Fun) || {Header, TraceId} <- Fixtures].

assert_trace_based_on_header(AmznTraceIdHeader0, ExpectedTraceId0, Fun) ->
AmznTraceIdHeader = list_to_binary(AmznTraceIdHeader0),
ExpectedTraceId = list_to_binary(ExpectedTraceId0),
meck:expect(capi_client_lib, make_request, fun(Context, Params) ->
{Url, PreparedParams, Opts} = meck:passthrough([Context, Params]),
UpdFun = fun(Headers) ->
Headers#{<<"X-Amzn-Trace-Id">> => AmznTraceIdHeader}
end,
{Url, maps:update_with(header, UpdFun, PreparedParams), Opts}
end),
TestProcess = self(),
meck:expect(otel_ctx, get_current, fun() ->
OtelCtx = meck:passthrough([]),
SpanCtx = otel_tracer:current_span_ctx(OtelCtx),
TestProcess ! {otel_span_info, otel_span:hex_span_ctx(SpanCtx)},
OtelCtx
end),
_ = Fun(),
meck:unload(otel_ctx),
meck:unload(capi_client_lib),
?assertMatch(#{otel_trace_id := ExpectedTraceId}, await_latest_otel_span_info(100, #{})).

await_latest_otel_span_info(Timeout, LastValue) ->
receive
Expand Down
6 changes: 3 additions & 3 deletions rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@
{swag_client, {git, "https://github.com/valitydev/swag-payments", {branch, "release/erlang/client/v3"}}},
{fraudbusters_proto, {git, "https://github.com/valitydev/fraudbusters-proto.git", {branch, "master"}}},
%% OpenTelemetry deps
{opentelemetry_api, "1.4.0"},
{opentelemetry, "1.5.0"},
{opentelemetry_exporter, "1.8.0"}
{opentelemetry_api, "1.5.0"},
{opentelemetry, "1.7.0"},
{opentelemetry_exporter, "1.10.0"}
]}.

%% XRef checks
Expand Down
30 changes: 15 additions & 15 deletions rebar.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{"1.2.0",
[{<<"accept">>,{pkg,<<"accept">>,<<"0.3.7">>},2},
{<<"acceptor_pool">>,{pkg,<<"acceptor_pool">>,<<"1.0.0">>},2},
{<<"acceptor_pool">>,{pkg,<<"acceptor_pool">>,<<"1.0.1">>},2},
{<<"bender_client">>,
{git,"https://github.com/valitydev/bender-client-erlang.git",
{ref,"2fceffde5deac85d3bd3f071187041d84c8c3af4"}},
Expand Down Expand Up @@ -92,10 +92,10 @@
{git,"https://github.com/valitydev/msgpack-proto.git",
{ref,"7e447496aa5df4a5f1ace7ef2e3c31248b2a3ed0"}},
1},
{<<"opentelemetry">>,{pkg,<<"opentelemetry">>,<<"1.5.0">>},0},
{<<"opentelemetry_api">>,{pkg,<<"opentelemetry_api">>,<<"1.4.0">>},0},
{<<"opentelemetry">>,{pkg,<<"opentelemetry">>,<<"1.7.0">>},0},
{<<"opentelemetry_api">>,{pkg,<<"opentelemetry_api">>,<<"1.5.0">>},0},
{<<"opentelemetry_exporter">>,
{pkg,<<"opentelemetry_exporter">>,<<"1.8.0">>},
{pkg,<<"opentelemetry_exporter">>,<<"1.10.0">>},
0},
{<<"org_management_proto">>,
{git,"https://github.com/valitydev/org-management-proto",
Expand Down Expand Up @@ -137,7 +137,7 @@
{ref,"3a60e5dc5bbd709495024f26e100b041c3547fd9"}},
1},
{<<"tls_certificate_check">>,
{pkg,<<"tls_certificate_check">>,<<"1.29.0">>},
{pkg,<<"tls_certificate_check">>,<<"1.31.0">>},
1},
{<<"token_keeper_client">>,
{git,"https://github.com/valitydev/token-keeper-client.git",
Expand All @@ -159,7 +159,7 @@
[
{pkg_hash,[
{<<"accept">>, <<"CD6E34A2D7E28CA38B2D3CB233734CA0C221EFBC1F171F91FEC5F162CC2D18DA">>},
{<<"acceptor_pool">>, <<"43C20D2ACAE35F0C2BCD64F9D2BDE267E459F0F3FD23DAB26485BF518C281B21">>},
{<<"acceptor_pool">>, <<"D88C2E8A0BE9216CF513FBCD3E5A4BEB36BEE3FF4168E85D6152C6F899359CDB">>},
{<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>},
{<<"certifi">>, <<"DBAB8E5E155A0763EEA978C913CA280A6B544BFA115633FA20249C3D396D9493">>},
{<<"chatterbox">>, <<"5CAC4D15DD7AD61FC3C4415CE4826FC563D4643DEE897A558EC4EA0B1C835C9C">>},
Expand All @@ -175,21 +175,21 @@
{<<"jsx">>, <<"D12516BAA0BB23A59BB35DCCAF02A1BD08243FCBB9EFE24F2D9D056CCFF71268">>},
{<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>},
{<<"mimerl">>, <<"3882A5CA67FBBE7117BA8947F27643557ADEC38FA2307490C4C4207624CB213B">>},
{<<"opentelemetry">>, <<"7DDA6551EDFC3050EA4B0B40C0D2570423D6372B97E9C60793263EF62C53C3C2">>},
{<<"opentelemetry_api">>, <<"63CA1742F92F00059298F478048DFB826F4B20D49534493D6919A0DB39B6DB04">>},
{<<"opentelemetry_exporter">>, <<"5D546123230771EF4174E37BEDFD77E3374913304CD6EA3CA82A2ADD49CD5D56">>},
{<<"opentelemetry">>, <<"20D0F12D3D1C398D3670FD44FD1A7C495DD748AB3E5B692A7906662E2FB1A38A">>},
{<<"opentelemetry_api">>, <<"1A676F3E3340CAB81C763E939A42E11A70C22863F645AA06AAFEFC689B5550CF">>},
{<<"opentelemetry_exporter">>, <<"972E142392DBFA679EC959914664ADEFEA38399E4F56CEBA5C473E1CABDBAD79">>},
{<<"parse_trans">>, <<"6E6AA8167CB44CC8F39441D05193BE6E6F4E7C2946CB2759F015F8C56B76E5FF">>},
{<<"prometheus">>, <<"B95F8DE8530F541BD95951E18E355A840003672E5EDA4788C5FA6183406BA29A">>},
{<<"prometheus_cowboy">>, <<"D9D5B300516A61ED5AE31391F8EEEEB202230081D32A1813F2D78772B6F274E1">>},
{<<"prometheus_httpd">>, <<"8F767D819A5D36275EAB9264AFF40D87279151646776069BF69FBDBBD562BD75">>},
{<<"quantile_estimator">>, <<"EF50A361F11B5F26B5F16D0696E46A9E4661756492C981F7B2229EF42FF1CD15">>},
{<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>},
{<<"ssl_verify_fun">>, <<"354C321CF377240C7B8716899E182CE4890C5938111A1296ADD3EC74CF1715DF">>},
{<<"tls_certificate_check">>, <<"4473005EB0BBDAD215D7083A230E2E076F538D9EA472C8009FD22006A4CFC5F6">>},
{<<"tls_certificate_check">>, <<"9A910B54D8CB96CC810CABF4C0129F21360F82022B20180849F1442A25CCBB04">>},
{<<"unicode_util_compat">>, <<"A48703A25C170EEDADCA83B11E88985AF08D35F37C6F664D6DCFB106A97782FC">>}]},
{pkg_hash_ext,[
{<<"accept">>, <<"CA69388943F5DAD2E7232A5478F16086E3C872F48E32B88B378E1885A59F5649">>},
{<<"acceptor_pool">>, <<"0CBCD83FDC8B9AD2EEE2067EF8B91A14858A5883CB7CD800E6FCD5803E158788">>},
{<<"acceptor_pool">>, <<"F172F3D74513E8EDD445C257D596FC84DBDD56D2C6FA287434269648AE5A421E">>},
{<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>},
{<<"certifi">>, <<"524C97B4991B3849DD5C17A631223896272C6B0AF446778BA4675A1DFF53BB7E">>},
{<<"chatterbox">>, <<"4F75B91451338BC0DA5F52F3480FA6EF6E3A2AEECFC33686D6B3D0A0948F31AA">>},
Expand All @@ -205,16 +205,16 @@
{<<"jsx">>, <<"0C5CC8FDC11B53CC25CF65AC6705AD39E54ECC56D1C22E4ADB8F5A53FB9427F3">>},
{<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>},
{<<"mimerl">>, <<"13AF15F9F68C65884ECCA3A3891D50A7B57D82152792F3E19D88650AA126B144">>},
{<<"opentelemetry">>, <<"CDF4F51D17B592FC592B9A75F86A6F808C23044BA7CF7B9534DEBBCC5C23B0EE">>},
{<<"opentelemetry_api">>, <<"3DFBBFAA2C2ED3121C5C483162836C4F9027DEF469C41578AF5EF32589FCFC58">>},
{<<"opentelemetry_exporter">>, <<"A1F9F271F8D3B02B81462A6BFEF7075FD8457FDB06ADFF5D2537DF5E2264D9AF">>},
{<<"opentelemetry">>, <<"A9173B058C4549BF824CBC2F1D2FA2ADC5CDEDC22AA3F0F826951187BBD53131">>},
{<<"opentelemetry_api">>, <<"F53EC8A1337AE4A487D43AC89DA4BD3A3C99DDF576655D071DEED8B56A2D5DDA">>},
{<<"opentelemetry_exporter">>, <<"33A116ED7304CB91783F779DEC02478F887C87988077BFD72840F760B8D4B952">>},
{<<"parse_trans">>, <<"620A406CE75DADA827B82E453C19CF06776BE266F5A67CFF34E1EF2CBB60E49A">>},
{<<"prometheus">>, <<"719862351AABF4DF7079B05DC085D2BBCBE3AC0AC3009E956671B1D5AB88247D">>},
{<<"prometheus_cowboy">>, <<"5F71C039DEB9E9FF9DD6366BC74C907A463872B85286E619EFF0BDA15111695A">>},
{<<"prometheus_httpd">>, <<"67736D000745184D5013C58A63E947821AB90CB9320BC2E6AE5D3061C6FFE039">>},
{<<"quantile_estimator">>, <<"282A8A323CA2A845C9E6F787D166348F776C1D4A41EDE63046D72D422E3DA946">>},
{<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>},
{<<"ssl_verify_fun">>, <<"FE4C190E8F37401D30167C8C405EDA19469F34577987C76DDE613E838BBC67F8">>},
{<<"tls_certificate_check">>, <<"5B0D0E5CB0F928BC4F210DF667304ED91C5BFF2A391CE6BDEDFBFE70A8F096C5">>},
{<<"tls_certificate_check">>, <<"9D2B41B128D5507BD8AD93E1A998E06D0AB2F9A772AF343F4C00BF76C6BE1532">>},
{<<"unicode_util_compat">>, <<"B3A917854CE3AE233619744AD1E0102E05673136776FB2FA76234F3E03B23642">>}]}
].
Loading