opentelemetry-erlang-contrib/utilities/opentelemetry_telemetry/test/otel_telemetry_SUITE.erl

148 lines
4.9 KiB
Erlang

-module(otel_telemetry_SUITE).
-compile(export_all).
-include_lib("common_test/include/ct.hrl").
-include_lib("stdlib/include/assert.hrl").
-include_lib("opentelemetry_api/include/opentelemetry.hrl").
-include_lib("opentelemetry/include/otel_span.hrl").
-include_lib("opentelemetry_api/include/otel_tracer.hrl").
all() -> [
telemetry_span_handling
].
init_per_suite(Config) ->
ok = application:load(opentelemetry_telemetry),
ok = application:load(opentelemetry),
application:set_env(opentelemetry, processors, [{otel_batch_processor, #{scheduled_delay_ms => 1}}]),
Config.
end_per_suite(_Config) ->
ok = application:unload(opentelemetry),
ok.
init_per_testcase(_, Config) ->
{ok, _} = application:ensure_all_started(telemetry),
{ok, _} = application:ensure_all_started(opentelemetry_telemetry),
otel_batch_processor:set_exporter(otel_exporter_pid, self()),
attach_event_handlers(),
Config.
end_per_testcase(_, Config) ->
application:stop(telemetry),
application:stop(opentelemetry_telemetry),
application:stop(opentelemetry),
Config.
telemetry_span_handling(_Config) ->
SpanCtx1 = ?start_span(<<"span-1">>),
?set_current_span(SpanCtx1),
_Result = handler(ok),
?assertMatch(SpanCtx1, ?current_span_ctx),
try handler(raise_exception) of
_ -> ok
catch
error:badarg -> ok
end,
?assertMatch(SpanCtx1, ?current_span_ctx),
?set_attribute(<<"attribute">>, 1),
?end_span(),
{_, Span3Parent} = successful_span_listener(<<"test_app_nested_span">>),
{Span2, Span2Parent} = successful_span_listener(<<"test_app_handler">>),
{_, ExceptionSpanParent} = exception_span_listener(<<"test_app_handler">>),
{Span1, undefined} = successful_span_listener(<<"span-1">>),
?assertEqual(Span2Parent, Span1),
?assertEqual(ExceptionSpanParent, Span1),
?assertEqual(Span3Parent, Span2),
ok.
successful_span_listener(Name) ->
receive
{span, #span{name=Name,parent_span_id=ParentId,span_id=Id}} ->
{Id, ParentId}
after
5000 ->
error(timeout)
end.
exception_span_listener(Name) ->
receive
{span, #span{name=Name,events=Events,status={status,error,Reason},parent_span_id=ParentId,span_id=Id} = Span} ->
?assertEqual(<<"badarg">>, Reason),
?assertEqual(1, erlang:length(otel_events:list(Events))),
{Id, ParentId}
after
5000 ->
error(timeout)
end.
handler(Args) ->
_ = telemetry:span(
[test_app, handler],
#{},
fun() ->
case Args of
raise_exception ->
binary_to_list("heh, already a list");
_ -> {nested_span(), #{}}
end
end).
nested_span() ->
_ = telemetry:span(
[test_app, nested_span],
#{},
fun() ->
{ok, #{}}
end).
-define(TRACER_ID, ?MODULE).
attach_event_handlers() ->
Events = [
[test_app, handler, start],
[test_app, handler, stop],
[test_app, handler, exception],
[test_app, nested_span, start],
[test_app, nested_span, stop],
[test_app, nested_span, exception]
],
telemetry:attach_many(otel_telemetry_test_handlers, Events, fun ?TRACER_ID:handle_event/4, #{}).
handle_event([test_app, handler, start], _, Meta, _) ->
otel_telemetry:start_telemetry_span(?TRACER_ID, <<"test_app_handler">>, Meta, #{});
handle_event([test_app, handler, stop], _, Meta, _) ->
otel_telemetry:set_current_telemetry_span(?TRACER_ID, Meta),
otel_telemetry:end_telemetry_span(?TRACER_ID, Meta);
handle_event([test_app, handler, exception], _, Meta, _) ->
Ctx = otel_telemetry:set_current_telemetry_span(?TRACER_ID, Meta),
#{
kind := Kind,
reason := Reason,
stacktrace := Stacktrace
} = Meta,
otel_span:record_exception(Ctx, Kind, Reason, Stacktrace, []),
otel_span:set_status(Ctx, opentelemetry:status(?OTEL_STATUS_ERROR, atom_to_binary(Reason))),
otel_telemetry:end_telemetry_span(?TRACER_ID, Meta);
handle_event([test_app, nested_span, start], _, Meta, _) ->
otel_telemetry:start_telemetry_span(?TRACER_ID, <<"test_app_nested_span">>, Meta, #{});
handle_event([test_app, nested_span, stop], _, Meta, _) ->
otel_telemetry:set_current_telemetry_span(?TRACER_ID, Meta),
otel_telemetry:end_telemetry_span(?TRACER_ID, Meta);
handle_event([test_app, nested_span, exception], _, Meta, _) ->
Ctx = otel_telemetry:set_current_telemetry_span(?TRACER_ID, Meta),
#{
kind := Kind,
reason := Reason,
stacktrace := Stacktrace
} = Meta,
otel_span:set_status(Ctx, opentelemetry:status(?OTEL_STATUS_ERROR, <<"">>)),
otel_span:record_exception(Ctx, Kind, Reason, Stacktrace, []),
otel_telemetry:end_telemetry_span(?TRACER_ID, Meta).