File: transaction_event.rb

package info (click to toggle)
ruby-sentry-ruby 5.18.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 564 kB
  • sloc: ruby: 4,701; makefile: 8; sh: 4
file content (85 lines) | stat: -rw-r--r-- 2,558 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# frozen_string_literal: true

module Sentry
  # TransactionEvent represents events that carry transaction data (type: "transaction").
  class TransactionEvent < Event
    TYPE = "transaction"

    # @return [<Array[Span]>]
    attr_accessor :spans

    # @return [Hash]
    attr_accessor :measurements

    # @return [Float, nil]
    attr_reader :start_timestamp

    # @return [Hash, nil]
    attr_accessor :profile

    # @return [Hash, nil]
    attr_accessor :metrics_summary

    def initialize(transaction:, **options)
      super(**options)

      self.transaction = transaction.name
      self.transaction_info = { source: transaction.source }
      self.contexts.merge!(transaction.contexts)
      self.contexts.merge!(trace: transaction.get_trace_context)
      self.timestamp = transaction.timestamp
      self.start_timestamp = transaction.start_timestamp
      self.tags = transaction.tags
      self.dynamic_sampling_context = transaction.get_baggage.dynamic_sampling_context
      self.measurements = transaction.measurements
      self.metrics_summary = transaction.metrics_summary

      finished_spans = transaction.span_recorder.spans.select { |span| span.timestamp && span != transaction }
      self.spans = finished_spans.map(&:to_hash)

      populate_profile(transaction)
    end

    # Sets the event's start_timestamp.
    # @param time [Time, Float]
    # @return [void]
    def start_timestamp=(time)
      @start_timestamp = time.is_a?(Time) ? time.to_f : time
    end

    # @return [Hash]
    def to_hash
      data = super
      data[:spans] = @spans.map(&:to_hash) if @spans
      data[:start_timestamp] = @start_timestamp
      data[:measurements] = @measurements
      data[:_metrics_summary] = @metrics_summary if @metrics_summary
      data
    end

    private

    def populate_profile(transaction)
      profile_hash = transaction.profiler.to_hash
      return if profile_hash.empty?

      profile_hash.merge!(
        environment: environment,
        release: release,
        timestamp: Time.at(start_timestamp).iso8601,
        device: { architecture: Scope.os_context[:machine] },
        os: { name: Scope.os_context[:name], version: Scope.os_context[:version] },
        runtime: Scope.runtime_context,
        transaction: {
          id: event_id,
          name: transaction.name,
          trace_id: transaction.trace_id,
          # TODO-neel-profiler stubbed for now, see thread_id note in profiler.rb
          active_thead_id: '0'
        }
      )

      self.profile = profile_hash
    end
  end
end