Skip to content

Commit

Permalink
Encapsulate extension helpers (#1725)
Browse files Browse the repository at this point in the history
* Encapsulate sentry-resque's helper methods

* Encapsulate sentry-rails's ActiveJob integration
  • Loading branch information
st0012 authored Feb 17, 2022
1 parent 341b66e commit 7197bd0
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 104 deletions.
120 changes: 62 additions & 58 deletions sentry-rails/lib/sentry/rails/active_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,76 +5,80 @@ def perform_now
if !Sentry.initialized? || already_supported_by_sentry_integration?
super
else
Sentry.with_scope do |scope|
capture_and_reraise_with_sentry(scope) do
super
end
SentryReporter.record(self) do
super
end
end
end

def capture_and_reraise_with_sentry(scope, &block)
scope.set_transaction_name(self.class.name)
transaction =
if is_a?(::Sentry::SendEventJob)
nil
else
Sentry.start_transaction(name: scope.transaction_name, op: "active_job")
end

scope.set_span(transaction) if transaction

return_value = block.call
def already_supported_by_sentry_integration?
Sentry.configuration.rails.skippable_job_adapters.include?(self.class.queue_adapter.class.to_s)
end

finish_sentry_transaction(transaction, 200)
class SentryReporter
class << self
def record(job, &block)
Sentry.with_scope do |scope|
begin
scope.set_transaction_name(job.class.name)
transaction =
if job.is_a?(::Sentry::SendEventJob)
nil
else
Sentry.start_transaction(name: scope.transaction_name, op: "active_job")
end

return_value
rescue Exception => e # rubocop:disable Lint/RescueException
finish_sentry_transaction(transaction, 500)
scope.set_span(transaction) if transaction

Sentry::Rails.capture_exception(
e,
extra: sentry_context,
tags: {
job_id: job_id,
provider_job_id: provider_job_id
}
)
raise e
end
yield.tap do
finish_sentry_transaction(transaction, 200)
end
rescue Exception => e # rubocop:disable Lint/RescueException
finish_sentry_transaction(transaction, 500)

def finish_sentry_transaction(transaction, status)
return unless transaction
Sentry::Rails.capture_exception(
e,
extra: sentry_context(job),
tags: {
job_id: job.job_id,
provider_job_id: job.provider_job_id
}
)
raise
end
end
end

transaction.set_http_status(status)
transaction.finish
end
def finish_sentry_transaction(transaction, status)
return unless transaction

def already_supported_by_sentry_integration?
Sentry.configuration.rails.skippable_job_adapters.include?(self.class.queue_adapter.class.to_s)
end
transaction.set_http_status(status)
transaction.finish
end

def sentry_context
{
active_job: self.class.name,
arguments: sentry_serialize_arguments(arguments),
scheduled_at: scheduled_at,
job_id: job_id,
provider_job_id: provider_job_id,
locale: locale
}
end
def sentry_context(job)
{
active_job: job.class.name,
arguments: sentry_serialize_arguments(job.arguments),
scheduled_at: job.scheduled_at,
job_id: job.job_id,
provider_job_id: job.provider_job_id,
locale: job.locale
}
end

def sentry_serialize_arguments(argument)
case argument
when Hash
argument.transform_values { |v| sentry_serialize_arguments(v) }
when Array, Enumerable
argument.map { |v| sentry_serialize_arguments(v) }
when ->(v) { v.respond_to?(:to_global_id) }
argument.to_global_id.to_s rescue argument
else
argument
def sentry_serialize_arguments(argument)
case argument
when Hash
argument.transform_values { |v| sentry_serialize_arguments(v) }
when Array, Enumerable
argument.map { |v| sentry_serialize_arguments(v) }
when ->(v) { v.respond_to?(:to_global_id) }
argument.to_global_id.to_s rescue argument
else
argument
end
end
end
end
end
Expand Down
104 changes: 58 additions & 46 deletions sentry-resque/lib/sentry/resque.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,63 +5,75 @@
module Sentry
module Resque
def perform
return super unless Sentry.initialized?
if Sentry.initialized?
SentryReporter.record(queue, worker, payload) do
super
end
else
super
end
end

Sentry.with_scope do |scope|
begin
contexts = generate_contexts
scope.set_contexts(**contexts)
scope.set_tags("resque.queue" => queue)
class SentryReporter
class << self
def record(queue, worker, payload, &block)
Sentry.with_scope do |scope|
begin
contexts = generate_contexts(queue, worker, payload)
scope.set_contexts(**contexts)
scope.set_tags("resque.queue" => queue)

scope.set_transaction_name(contexts.dig(:"Active-Job", :job_class) || contexts.dig(:"Resque", :job_class))
transaction = Sentry.start_transaction(name: scope.transaction_name, op: "resque")
scope.set_span(transaction) if transaction
scope.set_transaction_name(contexts.dig(:"Active-Job", :job_class) || contexts.dig(:"Resque", :job_class))
transaction = Sentry.start_transaction(name: scope.transaction_name, op: "resque")
scope.set_span(transaction) if transaction

super
yield

finish_transaction(transaction, 200)
rescue Exception => exception
::Sentry::Resque.capture_exception(exception, hint: { background: false })
finish_transaction(transaction, 500)
raise
finish_transaction(transaction, 200)
rescue Exception => exception
::Sentry::Resque.capture_exception(exception, hint: { background: false })
finish_transaction(transaction, 500)
raise
end
end
end
end
end

def generate_contexts
context = {}
def generate_contexts(queue, worker, payload)
context = {}

if payload["class"] == "ActiveJob::QueueAdapters::ResqueAdapter::JobWrapper"
active_job_payload = payload["args"].first
if payload["class"] == "ActiveJob::QueueAdapters::ResqueAdapter::JobWrapper"
active_job_payload = payload["args"].first

context[:"Active-Job"] = {
job_class: active_job_payload["job_class"],
job_id: active_job_payload["job_id"],
arguments: active_job_payload["arguments"],
executions: active_job_payload["executions"],
exception_executions: active_job_payload["exception_executions"],
locale: active_job_payload["locale"],
enqueued_at: active_job_payload["enqueued_at"],
queue: queue,
worker: worker.to_s
}
else
context[:"Resque"] = {
job_class: payload["class"],
arguments: payload["args"],
queue: queue,
worker: worker.to_s
}
end
context[:"Active-Job"] = {
job_class: active_job_payload["job_class"],
job_id: active_job_payload["job_id"],
arguments: active_job_payload["arguments"],
executions: active_job_payload["executions"],
exception_executions: active_job_payload["exception_executions"],
locale: active_job_payload["locale"],
enqueued_at: active_job_payload["enqueued_at"],
queue: queue,
worker: worker.to_s
}
else
context[:"Resque"] = {
job_class: payload["class"],
arguments: payload["args"],
queue: queue,
worker: worker.to_s
}
end

context
end
context
end

def finish_transaction(transaction, status)
return unless transaction
def finish_transaction(transaction, status)
return unless transaction

transaction.set_http_status(status)
transaction.finish
transaction.set_http_status(status)
transaction.finish
end
end
end
end
end
Expand Down

0 comments on commit 7197bd0

Please sign in to comment.