Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up transactions docs and code #852

Merged
merged 1 commit into from
Jan 27, 2025
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
19 changes: 9 additions & 10 deletions lib/sentry/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ defmodule Sentry.Client do
|> Transport.encode_and_post_envelope(client, request_retries)
end

@spec send_transaction(Transaction.t(), keyword()) ::
{:ok, transaction_id :: String.t()}
| {:error, ClientError.t()}
| :unsampled
| :excluded
def send_transaction(%Transaction{} = transaction, opts \\ []) do
opts = NimbleOptions.validate!(opts, Options.send_transaction_schema())

Expand Down Expand Up @@ -190,12 +195,12 @@ defmodule Sentry.Client do
"""
end

defp maybe_call_after_send(event, result, callback) do
defp maybe_call_after_send(event_or_transaction, result, callback) do
message = ":after_send_event must be an anonymous function or a {module, function} tuple"

case callback do
function when is_function(function, 2) -> function.(event, result)
{module, function} -> apply(module, function, [event, result])
function when is_function(function, 2) -> function.(event_or_transaction, result)
{module, function} -> apply(module, function, [event_or_transaction, result])
nil -> nil
_ -> raise ArgumentError, message
end
Expand Down Expand Up @@ -294,13 +299,7 @@ defmodule Sentry.Client do
def render_transaction(%Transaction{} = transaction) do
transaction
|> Transaction.to_payload()
|> Map.merge(%{
platform: "elixir",
sdk: %{
name: "sentry.elixir",
version: Application.spec(:sentry, :vsn)
}
})
|> update_if_present(:sdk, &Map.from_struct/1)
end

defp render_exception(%Interfaces.Exception{} = exception) do
Expand Down
31 changes: 14 additions & 17 deletions lib/sentry/interfaces.ex
Original file line number Diff line number Diff line change
Expand Up @@ -272,24 +272,26 @@ defmodule Sentry.Interfaces do
@moduledoc """
The struct for the **span** interface.

See <https://develop.sentry.dev/sdk/event-payloads/spans>.
See <https://develop.sentry.dev/sdk/data-model/event-payloads/span/>.
"""

@moduledoc since: "11.0.0"

@typedoc since: "11.0.0"
@type t() :: %__MODULE__{
trace_id: String.t(),
span_id: String.t(),
start_timestamp: String.t(),
timestamp: String.t(),
parent_span_id: String.t(),
description: String.t(),
op: String.t(),
status: String.t(),
tags: map(),
data: map(),
origin: String.t()
trace_id: <<_::256>>,
span_id: <<_::128>>,
start_timestamp: String.t() | number(),
timestamp: String.t() | number(),

# Optional
parent_span_id: <<_::128>> | nil,
description: String.t() | nil,
op: String.t() | nil,
status: String.t() | nil,
tags: %{optional(String.t()) => term()} | nil,
data: %{optional(String.t()) => term()} | nil,
origin: String.t() | nil
}

@enforce_keys [:trace_id, :span_id, :start_timestamp, :timestamp]
Expand All @@ -304,10 +306,5 @@ defmodule Sentry.Interfaces do
:data,
:origin
]

@doc false
def to_payload(%__MODULE__{} = span) do
Map.from_struct(span)
end
end
end
50 changes: 41 additions & 9 deletions lib/sentry/transaction.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,42 @@ defmodule Sentry.Transaction do
@moduledoc """
The struct for the **transaction** interface.

See <https://develop.sentry.dev/sdk/event-payloads/transactions>.
See <https://develop.sentry.dev/sdk/data-model/event-payloads/transaction/>.
"""

@moduledoc since: "11.0.0"

alias Sentry.{Config, UUID, Interfaces.Span, Interfaces.SDK}
alias Sentry.{Config, UUID, Interfaces, Interfaces.Span, Interfaces.SDK}

@sdk %Interfaces.SDK{
name: "sentry-elixir",
version: Mix.Project.config()[:version]
}

@typedoc """
A map of measurements.

See
[here](https://github.com/getsentry/sentry/blob/a8c960a933d2ded5225841573d8fc426a482ca9c/static/app/utils/discover/fields.tsx#L654-L676)
for the list of supported keys (which could change in the future).
"""
@typedoc since: "11.0.0"
@type measurements() :: %{
optional(key :: atom()) => %{
required(:value) => number(),
optional(:unit) => String.t()
}
}

@typedoc """
Transaction information.

Should only be set by integrations and not developers directly.
"""
@typedoc since: "11.0.0"
@type transaction_info() :: %{
required(:source) => String.t()
}

@typedoc since: "11.0.0"
@type t() ::
Expand All @@ -16,7 +46,8 @@ defmodule Sentry.Transaction do
event_id: UUID.t(),
start_timestamp: String.t() | number(),
timestamp: String.t() | number(),
platform: :elixir,
platform: String.t(),
# See https://develop.sentry.dev/sdk/data-model/event-payloads/contexts/#trace-context
contexts: %{
required(:trace) => %{
required(:trace_id) => String.t(),
Expand All @@ -31,9 +62,8 @@ defmodule Sentry.Transaction do
# Optional
environment: String.t(),
transaction: String.t(),
transaction_info: map(),
measurements: map(),
type: String.t(),
transaction_info: transaction_info(),
measurements: measurements(),
tags: map(),
data: map(),

Expand All @@ -55,8 +85,7 @@ defmodule Sentry.Transaction do
:platform,
:environment,
:tags,
:data,
type: "transaction"
:data
]

@doc false
Expand All @@ -66,13 +95,16 @@ defmodule Sentry.Transaction do
attrs
|> Map.put(:event_id, UUID.uuid4_hex())
|> Map.put(:environment, Config.environment_name())
|> Map.put(:sdk, @sdk)
|> Map.put(:platform, "elixir")
)
end

@doc false
def to_payload(%__MODULE__{} = transaction) do
transaction
|> Map.from_struct()
|> Map.update(:spans, [], fn spans -> Enum.map(spans, &Span.to_payload/1) end)
|> Map.put(:type, "transaction")
|> update_in([Access.key(:spans, []), Access.all()], &Map.from_struct/1)
end
end
9 changes: 4 additions & 5 deletions test/sentry/transaction_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@ defmodule Sentry.TransactionTest do
import Sentry.TestHelpers

describe "to_payload/1" do
setup do
{:ok, %{transaction: create_transaction()}}
end

test "returns a map representation of the transaction", %{transaction: transaction} do
test "returns a map representation of the transaction" do
transaction = create_transaction()
transaction_payload = Transaction.to_payload(transaction)

assert transaction_payload.type == "transaction"

[child_span] = transaction_payload[:spans]

assert transaction_payload[:contexts][:trace][:trace_id] == "trace-312"
Expand Down
Loading