Class: Sqewer::Contrib::AppsignalWrapper

Inherits:
Object
  • Object
show all
Defined in:
lib/sqewer/extensions/appsignal_wrapper.rb

Overview

Can be used as a wrapper middleware in an ExecutionContext to log exceptions to Appsignal and to monitor performance. Will only activate if the Appsignal gem is loaded within the current process and active.

Defined Under Namespace

Classes: FakeRequest

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.newObject



8
9
10
11
12
13
14
# File 'lib/sqewer/extensions/appsignal_wrapper.rb', line 8

def self.new
  if defined?(Appsignal)
    super
  else
    nil
  end
end

Instance Method Details

#around_deserialization(serializer, msg_id, msg_payload) ⇒ Object



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
# File 'lib/sqewer/extensions/appsignal_wrapper.rb', line 25

def around_deserialization(serializer, msg_id, msg_payload)
  return yield unless Appsignal.active?

  # This creates a transaction, but also sets it as the Appsignal.current_transaction
  # which is a thread-local variable. We DO share this middleware between threads,
  # but since the object lives in thread locals it should be fine.
  transaction = Appsignal::Transaction.create(
    SecureRandom.uuid,
    namespace = Appsignal::Transaction::BACKGROUND_JOB,
    request = FakeRequest.new)

  transaction.set_action('%s#%s' % [serializer.class, 'unserialize'])
  transaction.request.params = {:sqs_message_body => msg_payload.to_s}
  transaction.set_http_or_background_queue_start

  job_unserialized = yield

  if !job_unserialized
    # If the job is nil or falsy, we skip the execution. In that case we finish the transaction.
    Appsignal::Transaction.complete_current!
  else
    # If not, then the job will be executed - keep the transaction open for execution block
    # that comes next. Hacky but should work.
    set_transaction_details_from_job(transaction, job_unserialized)
  end
  return job_unserialized
rescue Exception => e
  if transaction
    # If an exception is raised, raise it through and also set it as the Appsignal exception
    # and commit the transaction.
    transaction.set_error(e)
    Appsignal::Transaction.complete_current!
  end
  raise e
end

#around_execution(job, context) ⇒ Object

Run the job with Appsignal monitoring.



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/sqewer/extensions/appsignal_wrapper.rb', line 68

def around_execution(job, context)
  return yield unless Appsignal.active?
  transaction = Appsignal::Transaction.current
  set_transaction_details_from_job(transaction, job)
  yield
rescue Exception => e
  transaction.set_error(e) if transaction
  raise e
ensure
  Appsignal::Transaction.complete_current! if transaction
end

#set_transaction_details_from_job(transaction, job) ⇒ Object



61
62
63
64
65
# File 'lib/sqewer/extensions/appsignal_wrapper.rb', line 61

def set_transaction_details_from_job(transaction, job)
  transaction.set_action('%s#%s' % [job.class.to_s, 'run'])
  job_params = job.respond_to?(:to_h) ? job.to_h : {}
  transaction.request.params = job_params
end