Class: EventTimeline::CallTracker

Inherits:
Object
  • Object
show all
Defined in:
lib/event_timeline/call_tracker.rb

Class Method Summary collapse

Class Method Details

.install! ⇒ Object



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
# File 'lib/event_timeline/call_tracker.rb', line 6

def install!
  @last_location = {}
  @method_stack = Hash.new { |h, k| h[k] = [] }

  call_trace = TracePoint.new(:call) do |tp|
    next unless EventTimeline.configuration&.watched?(tp.path)

    current_location = "#{tp.path}:#{tp.lineno}"
    correlation_id = CurrentCorrelation.id || determine_correlation_id

    if @last_location[correlation_id] != current_location
      @last_location[correlation_id] = current_location

      # Capture method arguments
      params = capture_params(tp)

      event_id = SecureRandom.uuid
      @method_stack[correlation_id].push({
                                           event_id: event_id,
                                           method: "#{tp.defined_class}##{tp.method_id}"
                                         })

      Session.create!(
        name: "#{tp.defined_class}##{tp.method_id}",
        severity: 'info',
        category: 'method_call',
        payload: {
          event_id: event_id,
          file: tp.path,
          line: tp.lineno,
          class: tp.defined_class.to_s,
          method: tp.method_id.to_s,
          params: params
        },
        correlation_id: correlation_id,
        occurred_at: Time.current
      )

      # Enforce rotation limits
      RotationService.enforce_correlation_limit(correlation_id)
      RotationService.cleanup_if_needed
    end
  rescue StandardError => e
    Rails.logger.error "EventTimeline call tracking failed: #{e.message}" if defined?(Rails.logger)
  end

  return_trace = TracePoint.new(:return) do |tp|
    next unless EventTimeline.configuration&.watched?(tp.path)

    correlation_id = CurrentCorrelation.id || determine_correlation_id
    method_info = @method_stack[correlation_id].find { |m| m[:method] == "#{tp.defined_class}##{tp.method_id}" }

    if method_info
      @method_stack[correlation_id].delete(method_info)

      Session.create!(
        name: "#{tp.defined_class}##{tp.method_id}_return",
        severity: 'info',
        category: 'method_return',
        payload: {
          event_id: method_info[:event_id],
          return_value: filter_sensitive_data(:return_value, tp.return_value, { context: :return_value }),
          class: tp.defined_class.to_s,
          method: tp.method_id.to_s
        },
        correlation_id: correlation_id,
        occurred_at: Time.current
      )
    end
  rescue StandardError => e
    Rails.logger.error "EventTimeline return tracking failed: #{e.message}" if defined?(Rails.logger)
  end

  call_trace.enable
  return_trace.enable
end