28
28
is_valid /1 ,
29
29
is_valid_name /1 ,
30
30
validate_start_opts /1 ,
31
+ validate_with_opts /1 ,
31
32
set_attribute /3 ,
32
33
set_attributes /2 ,
33
34
add_event /3 ,
51
52
start_time := opentelemetry :timestamp (),
52
53
kind := opentelemetry :span_kind ()}.
53
54
54
- -export_type ([start_opts / 0 ]).
55
+ -type with_opts () :: #{attributes => opentelemetry :attributes_map (),
56
+ links => [opentelemetry :link ()],
57
+ is_recording => boolean (),
58
+ start_time => opentelemetry :timestamp (),
59
+ kind => opentelemetry :span_kind (),
60
+ record_exception => boolean (),
61
+ set_status_on_exception => boolean ()}.
62
+
63
+ -export_type ([start_opts / 0 , with_opts / 0 ]).
55
64
56
65
-spec validate_start_opts (start_opts ()) -> start_opts ().
57
66
validate_start_opts (Opts ) when is_map (Opts ) ->
@@ -68,6 +77,17 @@ validate_start_opts(Opts) when is_map(Opts) ->
68
77
is_recording => IsRecording
69
78
}.
70
79
80
+ -spec validate_with_opts (with_opts ()) -> with_opts ().
81
+ validate_with_opts (Opts ) when is_map (Opts ) ->
82
+ StartOpts = validate_start_opts (Opts ),
83
+ RecordException = maps :get (record_exception , Opts , false ),
84
+ SetStatusOnException = maps :get (set_status_on_exception , Opts , false ),
85
+ maps :merge (StartOpts , #{
86
+ record_exception => RecordException ,
87
+ set_status_on_exception => SetStatusOnException
88
+ }).
89
+
90
+
71
91
-spec is_recording (SpanCtx ) -> boolean () when
72
92
SpanCtx :: opentelemetry :span_ctx ().
73
93
is_recording (SpanCtx ) ->
@@ -201,11 +221,12 @@ add_events(_, _) ->
201
221
record_exception (SpanCtx , Class , Term , Stacktrace , Attributes ) when is_list (Attributes ) ->
202
222
record_exception (SpanCtx , Class , Term , Stacktrace , maps :from_list (Attributes ));
203
223
record_exception (SpanCtx , Class , Term , Stacktrace , Attributes ) when is_map (Attributes ) ->
204
- { ok , ExceptionType } = otel_utils : format_binary_string ( " ~0tP : ~0tP " , [ Class , 10 , Term , 10 ], [{ chars_limit , 50 }] ),
224
+ ExceptionType = exception_type ( Class , Term ),
205
225
{ok , StacktraceString } = otel_utils :format_binary_string (" ~0tP " , [Stacktrace , 10 ], [{chars_limit , 50 }]),
206
226
ExceptionAttributes = #{? EXCEPTION_TYPE => ExceptionType ,
207
227
? EXCEPTION_STACKTRACE => StacktraceString },
208
- add_event (SpanCtx , 'exception' , maps :merge (ExceptionAttributes , Attributes ));
228
+ ExceptionAttributes1 = add_elixir_message (ExceptionAttributes , Term ),
229
+ add_event (SpanCtx , 'exception' , maps :merge (ExceptionAttributes1 , Attributes ));
209
230
record_exception (_ , _ , _ , _ , _ ) ->
210
231
false .
211
232
@@ -219,7 +240,7 @@ record_exception(_, _, _, _, _) ->
219
240
record_exception (SpanCtx , Class , Term , Message , Stacktrace , Attributes ) when is_list (Attributes ) ->
220
241
record_exception (SpanCtx , Class , Term , Message , Stacktrace , maps :from_list (Attributes ));
221
242
record_exception (SpanCtx , Class , Term , Message , Stacktrace , Attributes ) when is_map (Attributes ) ->
222
- { ok , ExceptionType } = otel_utils : format_binary_string ( " ~0tP : ~0tP " , [ Class , 10 , Term , 10 ], [{ chars_limit , 50 }] ),
243
+ ExceptionType = exception_type ( Class , Term ),
223
244
{ok , StacktraceString } = otel_utils :format_binary_string (" ~0tP " , [Stacktrace , 10 ], [{chars_limit , 50 }]),
224
245
ExceptionAttributes = #{? EXCEPTION_TYPE => ExceptionType ,
225
246
? EXCEPTION_STACKTRACE => StacktraceString ,
@@ -228,6 +249,28 @@ record_exception(SpanCtx, Class, Term, Message, Stacktrace, Attributes) when is_
228
249
record_exception (_ , _ , _ , _ , _ , _ ) ->
229
250
false .
230
251
252
+ exception_type (error , #{'__exception__' := true , '__struct__' := ElixirErrorStruct } = Term ) ->
253
+ case atom_to_binary (ElixirErrorStruct ) of
254
+ <<" Elixir." , ExceptionType /binary >> -> ExceptionType ;
255
+ _ -> exception_type_erl (error , Term )
256
+ end ;
257
+ exception_type (Class , Term ) ->
258
+ exception_type_erl (Class , Term ).
259
+ exception_type_erl (Class , Term ) ->
260
+ {ok , ExceptionType } = otel_utils :format_binary_string (" ~0tP :~0tP " , [Class , 10 , Term , 10 ], [{chars_limit , 50 }]),
261
+ ExceptionType .
262
+
263
+ add_elixir_message (Attributes , #{'__exception__' := true } = Exception ) ->
264
+ try
265
+ Message = 'Elixir.Exception' :message (Exception ),
266
+ maps :put (? EXCEPTION_MESSAGE , Message , Attributes )
267
+ catch
268
+ _Class :_Exception ->
269
+ Attributes
270
+ end ;
271
+ add_elixir_message (Attributes , _ ) ->
272
+ Attributes .
273
+
231
274
-spec set_status (SpanCtx , StatusOrCode ) -> boolean () when
232
275
StatusOrCode :: opentelemetry :status () | undefined | opentelemetry :status_code (),
233
276
SpanCtx :: opentelemetry :span_ctx ().
0 commit comments