Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encapsulate extension helpers #1725

Merged
merged 2 commits into from
Feb 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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