Module: Sqreen::EcosystemIntegration::AroundCallbacks

Extended by:
Log::Loggable::ClassMethods
Defined in:
lib/sqreen/ecosystem_integration/around_callbacks.rb

Class Method Summary collapse

Methods included from Log::Loggable::ClassMethods

logger

Class Method Details

.wrap_generic_callback(module_name, action, callable) ⇒ Object

XXX: not used yet



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
86
87
88
89
90
# File 'lib/sqreen/ecosystem_integration/around_callbacks.rb', line 40

def wrap_generic_callback(module_name, action, callable)
  timer_name = "ecosystem:#{module_name}@#{action}"
  perf_notif_name = "ecosystem_#{module_name}"

  Proc.new do |*args|
    begin
      req_storage = Thread.current[:sqreen_http_request]

      timer = Graft::Timer.new(timer_name) do |t|
        # this is an epilogue to measure()
        req_storage && req_storage[:timed_hooks] << t
      end

      req_timer = nil
      timer.measure do
        # not in a request, no budget; call cb
        next callable.call(*args) unless req_storage

        # 1) budget enforcement
        # skip callback if budget already expended
        next if req_storage[:time_budget_expended]

        budget = req_storage[:time_budget]
        if budget
          req_timer = req_storage[:timer]
          remaining = budget - req_timer.elapsed
          unless remaining > 0
            req_storage[:time_budget_expended] = true
            next # skip callback
          end
        end

        callable.call(*args)
      end
    rescue ::Exception => e # rubocop:disable Lint/RescueException
      # 2) rescue exceptions
      logger.warn { "Error in #{module_name}:#{action}: #{e.message}" }
      logger.debug { e.backtrace.map { |x| "  #{x}" }.join("\n") }
      Sqreen::RemoteException.record(e)
    ensure
      # 3) contribute to performance metrics
      if timer
        req_timer.include_measurements(timer) if req_timer

        Sqreen::PerformanceNotifications.notify(
          perf_notif_name, action, *timer.start_and_end
        )
      end
    end # end begin
  end # end proc
end

.wrap_instrumentation_hook(module_name, action, callable) ⇒ Object

for instrumentation hooks instrumentation hooks already handle budgets, so nothing to do in that respect



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/sqreen/ecosystem_integration/around_callbacks.rb', line 19

def wrap_instrumentation_hook(module_name, action, callable)
  perf_notif_name = "ecosystem_#{module_name}"

  Proc.new do |*args|
    begin
      start = Sqreen.time
      callable.call(*args)
    rescue ::Exception => e # rubocop:disable Lint/RescueException
      # 2) rescue exceptions
      logger.warn { "Error in #{module_name}:#{action}: #{e.message}" }
      logger.debug { e.backtrace.map { |x| "  #{x}" }.join("\n") }
      Sqreen::RemoteException.record(e)
    ensure
      # 3) contribute to performance metrics
      stop = Sqreen.time
      Sqreen::PerformanceNotifications.notify(perf_notif_name, action, start, stop)
    end # end proc
  end # end begin
end