diff --git a/rebar.config b/rebar.config index 43fba5c..d727684 100644 --- a/rebar.config +++ b/rebar.config @@ -28,7 +28,7 @@ {deps, [ {genlib, {git, "https://github.com/valitydev/genlib.git", {tag, "v1.1.0"}}}, {prometheus, "4.8.1"}, - {woody, {git, "https://github.com/valitydev/woody_erlang.git", {tag, "v1.1.0"}}}, + {woody, {git, "https://github.com/valitydev/woody_erlang", {tag, "v1.1.1"}}}, {mg_proto, {git, "https://github.com/valitydev/machinegun-proto", {branch, "master"}}}, {progressor, {git, "https://github.com/valitydev/progressor.git", {tag, "v1.0.12"}}}, {opentelemetry_api, "1.4.0"} diff --git a/rebar.lock b/rebar.lock index d6fb5ef..9002210 100644 --- a/rebar.lock +++ b/rebar.lock @@ -54,8 +54,8 @@ 1}, {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.1">>},2}, {<<"woody">>, - {git,"https://github.com/valitydev/woody_erlang.git", - {ref,"cc983a9423325ba1d6a509775eb6ff7ace721539"}}, + {git,"https://github.com/valitydev/woody_erlang", + {ref,"3de9a236b66807d5397b28aed42e2b1c85f36739"}}, 0}]}. [ {pkg_hash,[ diff --git a/src/machinery_hybrid_backend.erl b/src/machinery_hybrid_backend.erl index e6d1fe5..f5ba4b4 100644 --- a/src/machinery_hybrid_backend.erl +++ b/src/machinery_hybrid_backend.erl @@ -181,7 +181,11 @@ migrate_machine(NS, ID, History, AuxState, TimestampSec, SimpleStatus, Opts) -> action => Action }, context => machinery_utils:encode( - context, machinery_utils:add_otel_context(maps:with([woody_ctx], FallbackOpts)) + context, + woody_rpc_helper:encode_rpc_context( + maps:get(woody_ctx, FallbackOpts, woody_context:new()), + otel_ctx:get_current() + ) ) }, case progressor:put(Req) of diff --git a/src/machinery_mg_backend.erl b/src/machinery_mg_backend.erl index 5cddc3d..2e96dbf 100644 --- a/src/machinery_mg_backend.erl +++ b/src/machinery_mg_backend.erl @@ -44,7 +44,8 @@ -type handler_opts() :: machinery:handler_opts(#{ - woody_ctx := woody_context:ctx() + woody_ctx := woody_context:ctx(), + otel_ctx => otel_ctx:t() }). -type backend_handler_opts() :: #{ diff --git a/src/machinery_modernizer_mg_backend.erl b/src/machinery_modernizer_mg_backend.erl index 0e58eda..c1d5327 100644 --- a/src/machinery_modernizer_mg_backend.erl +++ b/src/machinery_modernizer_mg_backend.erl @@ -30,7 +30,8 @@ -type handler_opts() :: machinery:handler_opts(#{ - woody_ctx := woody_context:ctx() + woody_ctx := woody_context:ctx(), + otel_ctx => otel_ctx:t() }). -type backend_handler_opts() :: #{ diff --git a/src/machinery_prg_backend.erl b/src/machinery_prg_backend.erl index 62069fe..4eb16e0 100644 --- a/src/machinery_prg_backend.erl +++ b/src/machinery_prg_backend.erl @@ -33,6 +33,7 @@ -export_type([backend_opts/0]). -export_type([backend_opts_static/0]). +-export_type([handler_opts/0]). -type backend_opts() :: machinery:backend_opts(#{ ?BACKEND_CORE_OPTS, @@ -40,6 +41,12 @@ otel_ctx => otel_ctx:t() }). +-type handler_opts() :: + machinery:handler_opts(#{ + woody_ctx := woody_context:ctx(), + otel_ctx => otel_ctx:t() + }). + -ifdef(WITH_OTEL). -define(WITH_OTEL_SPAN(N, O, F), ?with_span(N, O, F)). -else. @@ -220,7 +227,13 @@ make_request(NS, ID, Args, Range, CtxOpts) -> id => ID, range => Range, args => machinery_utils:encode(args, Args), - context => machinery_utils:encode(context, machinery_utils:add_otel_context(maps:with([woody_ctx], CtxOpts))) + context => machinery_utils:encode( + context, + woody_rpc_helper:encode_rpc_context( + maps:get(woody_ctx, CtxOpts, woody_context:new()), + otel_ctx:get_current() + ) + ) }). build_schema_context(NS, ID) -> @@ -236,14 +249,18 @@ build_schema_context(NS, ID) -> -spec process({task_t(), encoded_args(), process()}, backend_opts(), encoded_ctx()) -> process_result(). process({CallType, BinArgs, Process}, Opts, BinCtx) -> - ProcessCtx = machinery_utils:decode(context, BinCtx), - ok = machinery_utils:attach_otel_context(ProcessCtx), + {WoodyCtx, OtelCtx} = woody_rpc_helper:decode_rpc_context(machinery_utils:decode(context, BinCtx)), + ok = woody_rpc_helper:attach_otel_context(OtelCtx), NS = get_namespace(Opts), ID = maps:get(process_id, Process), SpanOpts = #{kind => ?SPAN_KIND_INTERNAL, attributes => process_tags(NS, ID)}, ?WITH_OTEL_SPAN(<<"processing">>, SpanOpts, fun(_SpanCtx) -> try - do_process(CallType, BinArgs, Process, Opts, ProcessCtx) + %% NOTE Process context must conform type `handler_opts/0` + do_process(CallType, BinArgs, Process, Opts, #{ + otel_ctx => OtelCtx, + woody_ctx => WoodyCtx + }) catch Class:Reason:Stacktrace -> _ = ?record_exception(Class, Reason, Stacktrace, process_tags(NS, ID)), diff --git a/src/machinery_utils.erl b/src/machinery_utils.erl index 591d750..27536cd 100644 --- a/src/machinery_utils.erl +++ b/src/machinery_utils.erl @@ -39,9 +39,6 @@ -export([encode/2]). -export([decode/2]). --export([add_otel_context/1]). --export([attach_otel_context/1]). - %% API -spec get_handler(machinery:modopts(Opts)) -> {module(), Opts}. @@ -98,58 +95,3 @@ decode(term, undefined) -> undefined; decode(term, V) -> erlang:binary_to_term(V). - -%% OTEL - --type packed_otel_ctx() :: list(). - --spec add_otel_context(map()) -> #{_ => _, otel_ctx := list()}. -add_otel_context(CtxOpts) -> - CtxOpts#{otel_ctx => pack_otel_stub(otel_ctx:get_current())}. - -pack_otel_stub(Ctx) -> - case otel_tracer:current_span_ctx(Ctx) of - undefined -> - []; - #span_ctx{trace_id = TraceID, span_id = SpanID, trace_flags = TraceFlags} -> - [trace_id_to_binary(TraceID), span_id_to_binary(SpanID), TraceFlags] - end. - -trace_id_to_binary(TraceID) -> - {ok, EncodedTraceID} = otel_utils:format_binary_string("~32.16.0b", [TraceID]), - EncodedTraceID. - -span_id_to_binary(SpanID) -> - {ok, EncodedSpanID} = otel_utils:format_binary_string("~16.16.0b", [SpanID]), - EncodedSpanID. - --spec attach_otel_context(#{otel_ctx := packed_otel_ctx()}) -> ok. -attach_otel_context(#{otel_ctx := PackedOtelCtx}) -> - case restore_otel_stub(otel_ctx:get_current(), PackedOtelCtx) of - NewCtx when map_size(NewCtx) =:= 0 -> - ok; - NewCtx -> - _ = otel_ctx:attach(choose_viable_otel_ctx(NewCtx, otel_ctx:get_current())), - ok - end; -attach_otel_context(_) -> - ok. - -%% lowest bit is if it is sampled --define(IS_NOT_SAMPLED(SpanCtx), SpanCtx#span_ctx.trace_flags band 2#1 =/= 1). - -choose_viable_otel_ctx(NewCtx, CurrentCtx) -> - case {otel_tracer:current_span_ctx(NewCtx), otel_tracer:current_span_ctx(CurrentCtx)} of - {SpanCtx = #span_ctx{}, #span_ctx{}} when ?IS_NOT_SAMPLED(SpanCtx) -> CurrentCtx; - {undefined, #span_ctx{}} -> CurrentCtx; - {_, _} -> NewCtx - end. - -restore_otel_stub(Ctx, [TraceID, SpanID, TraceFlags]) -> - SpanCtx = otel_tracer:from_remote_span(binary_to_id(TraceID), binary_to_id(SpanID), TraceFlags), - otel_tracer:set_current_span(Ctx, SpanCtx); -restore_otel_stub(Ctx, _Other) -> - Ctx. - -binary_to_id(Opaque) when is_binary(Opaque) -> - binary_to_integer(Opaque, 16).