Class: Sentry::Vernier::Profiler

Inherits:
Object
  • Object
show all
Defined in:
lib/sentry/vernier/profiler.rb

Constant Summary collapse

EMPTY_RESULT =
{}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(configuration) ⇒ Profiler

Returns a new instance of Profiler.



15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/sentry/vernier/profiler.rb', line 15

def initialize(configuration)
  @event_id = Utils.uuid

  @started = false
  @sampled = nil

  @profiling_enabled = defined?(Vernier) && configuration.profiling_enabled?
  @profiles_sample_rate = configuration.profiles_sample_rate
  @profiles_sample_interval = configuration.profiles_sample_interval
  @project_root = configuration.project_root
  @app_dirs_pattern = configuration.app_dirs_pattern
  @in_app_pattern = Regexp.new("^(#{@project_root}/)?#{@app_dirs_pattern}")
end

Instance Attribute Details

#event_idObject (readonly)

Returns the value of attribute event_id.



13
14
15
# File 'lib/sentry/vernier/profiler.rb', line 13

def event_id
  @event_id
end

#resultObject (readonly)

Returns the value of attribute result.



13
14
15
# File 'lib/sentry/vernier/profiler.rb', line 13

def result
  @result
end

#startedObject (readonly)

Returns the value of attribute started.



13
14
15
# File 'lib/sentry/vernier/profiler.rb', line 13

def started
  @started
end

Instance Method Details

#active_thread_idObject



90
91
92
# File 'lib/sentry/vernier/profiler.rb', line 90

def active_thread_id
  Thread.current.object_id
end

#set_initial_sample_decision(transaction_sampled) ⇒ Object



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
# File 'lib/sentry/vernier/profiler.rb', line 29

def set_initial_sample_decision(transaction_sampled)
  unless @profiling_enabled
    @sampled = false
    return
  end

  unless transaction_sampled
    @sampled = false
    log("Discarding profile because transaction not sampled")
    return
  end

  case @profiles_sample_rate
  when 0.0
    @sampled = false
    log("Discarding profile because sample_rate is 0")
    return
  when 1.0
    @sampled = true
    return
  else
    @sampled = Random.rand < @profiles_sample_rate
  end

  log("Discarding profile due to sampling decision") unless @sampled
end

#startObject



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/sentry/vernier/profiler.rb', line 56

def start
  return unless @sampled
  return if @started

  @started = ::Vernier.start_profile(interval: @profiles_sample_interval)

  log("Started")

  @started
rescue RuntimeError => e
  # TODO: once Vernier raises something more dedicated, we should catch that instead
  if e.message.include?("Profile already started")
    log("Not started since running elsewhere")
  else
    log("Failed to start: #{e.message}")
  end
end

#stopObject



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/sentry/vernier/profiler.rb', line 74

def stop
  return unless @sampled
  return unless @started

  @result = ::Vernier.stop_profile
  @started = false

  log("Stopped")
rescue RuntimeError => e
  if e.message.include?("Profile not started")
    log("Not stopped since not started")
  else
    log("Failed to stop Vernier: #{e.message}")
  end
end

#to_hObject



94
95
96
97
98
99
100
101
102
103
# File 'lib/sentry/vernier/profiler.rb', line 94

def to_h
  unless @sampled
    record_lost_event(:sample_rate) if @profiling_enabled
    return EMPTY_RESULT
  end

  return EMPTY_RESULT unless result

  { **profile_meta, profile: output.to_h }
end