@@ -15,8 +15,9 @@ defmodule Sentry.Client do
15
15
Event ,
16
16
Interfaces ,
17
17
LoggerUtils ,
18
- Transport ,
19
- Options
18
+ Options ,
19
+ Transaction ,
20
+ Transport
20
21
}
21
22
22
23
require Logger
@@ -99,14 +100,42 @@ defmodule Sentry.Client do
99
100
client = Config . client ( )
100
101
101
102
# This is a "private" option, only really used in testing.
102
- request_retries =
103
- Application . get_env ( :sentry , :request_retries , Transport . default_retries ( ) )
103
+ request_retries = Application . get_env ( :sentry , :request_retries , Transport . default_retries ( ) )
104
104
105
105
client_report
106
106
|> Envelope . from_client_report ( )
107
107
|> Transport . encode_and_post_envelope ( client , request_retries )
108
108
end
109
109
110
+ def send_transaction ( % Transaction { } = transaction , opts \\ [ ] ) do
111
+ opts = NimbleOptions . validate! ( opts , Options . send_transaction_schema ( ) )
112
+
113
+ result_type = Keyword . get_lazy ( opts , :result , & Config . send_result / 0 )
114
+ client = Keyword . get_lazy ( opts , :client , & Config . client / 0 )
115
+ sample_rate = Keyword . get_lazy ( opts , :sample_rate , & Config . sample_rate / 0 )
116
+ before_send = Keyword . get_lazy ( opts , :before_send , & Config . before_send / 0 )
117
+ after_send_event = Keyword . get_lazy ( opts , :after_send_event , & Config . after_send_event / 0 )
118
+
119
+ request_retries =
120
+ Keyword . get_lazy ( opts , :request_retries , fn ->
121
+ Application . get_env ( :sentry , :request_retries , Transport . default_retries ( ) )
122
+ end )
123
+
124
+ with :ok <- sample_event ( sample_rate ) ,
125
+ { :ok , % Transaction { } = transaction } <- maybe_call_before_send ( transaction , before_send ) do
126
+ send_result = encode_and_send ( transaction , result_type , client , request_retries )
127
+ _ignored = maybe_call_after_send ( transaction , send_result , after_send_event )
128
+ send_result
129
+ else
130
+ :unsampled ->
131
+ ClientReport.Sender . record_discarded_events ( :sample_rate , [ transaction ] )
132
+ :unsampled
133
+
134
+ :excluded ->
135
+ :excluded
136
+ end
137
+ end
138
+
110
139
defp sample_event ( sample_rate ) do
111
140
cond do
112
141
sample_rate == 1 -> :ok
@@ -161,7 +190,7 @@ defmodule Sentry.Client do
161
190
"""
162
191
end
163
192
164
- defp maybe_call_after_send ( % Event { } = event , result , callback ) do
193
+ defp maybe_call_after_send ( event , result , callback ) do
165
194
message = ":after_send_event must be an anonymous function or a {module, function} tuple"
166
195
167
196
case callback do
@@ -205,6 +234,42 @@ defmodule Sentry.Client do
205
234
end
206
235
end
207
236
237
+ defp encode_and_send (
238
+ % Transaction { } = transaction ,
239
+ _result_type = :sync ,
240
+ client ,
241
+ request_retries
242
+ ) do
243
+ case Sentry.Test . maybe_collect ( transaction ) do
244
+ :collected ->
245
+ { :ok , "" }
246
+
247
+ :not_collecting ->
248
+ send_result =
249
+ transaction
250
+ |> Envelope . from_transaction ( )
251
+ |> Transport . encode_and_post_envelope ( client , request_retries )
252
+
253
+ send_result
254
+ end
255
+ end
256
+
257
+ defp encode_and_send (
258
+ % Transaction { } = transaction ,
259
+ _result_type = :none ,
260
+ client ,
261
+ _request_retries
262
+ ) do
263
+ case Sentry.Test . maybe_collect ( transaction ) do
264
+ :collected ->
265
+ { :ok , "" }
266
+
267
+ :not_collecting ->
268
+ :ok = Transport.Sender . send_async ( client , transaction )
269
+ { :ok , "" }
270
+ end
271
+ end
272
+
208
273
@ spec render_event ( Event . t ( ) ) :: map ( )
209
274
def render_event ( % Event { } = event ) do
210
275
json_library = Config . json_library ( )
@@ -225,6 +290,19 @@ defmodule Sentry.Client do
225
290
|> update_if_present ( :threads , fn list -> Enum . map ( list , & render_thread / 1 ) end )
226
291
end
227
292
293
+ @ spec render_transaction ( % Transaction { } ) :: map ( )
294
+ def render_transaction ( % Transaction { } = transaction ) do
295
+ transaction
296
+ |> Transaction . to_payload ( )
297
+ |> Map . merge ( % {
298
+ platform: "elixir" ,
299
+ sdk: % {
300
+ name: "sentry.elixir" ,
301
+ version: Application . spec ( :sentry , :vsn )
302
+ }
303
+ } )
304
+ end
305
+
228
306
defp render_exception ( % Interfaces.Exception { } = exception ) do
229
307
exception
230
308
|> Map . from_struct ( )
0 commit comments