Class: Eventboss::Sentry::ServerMiddleware

Inherits:
Middleware::Base show all
Defined in:
lib/eventboss/sentry/server_middleware.rb

Constant Summary collapse

OP_NAME =
'queue.process'
SPAN_ORIGIN =
'auto.queue.eventboss'

Instance Attribute Summary

Attributes inherited from Middleware::Base

#options

Instance Method Summary collapse

Methods inherited from Middleware::Base

#initialize

Constructor Details

This class inherits a constructor from Eventboss::Middleware::Base

Instance Method Details

#call(work) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/eventboss/sentry/server_middleware.rb', line 7

def call(work)
  return yield unless ::Sentry.initialized?

  ::Sentry.clone_hub_to_current_thread
  scope = ::Sentry.get_current_scope
  scope.clear
  if (user = extract_sentry_user(work))
    scope.set_user(user)
  end
  scope.set_tags(queue: extract_queue_name(work), message_id: work.message.message_id)
  scope.set_transaction_name(extract_transaction_name(work), source: :task)
  transaction = start_transaction(scope, work)

  if transaction
    scope.set_span(transaction)
    transaction.set_data(::Sentry::Span::DataConventions::MESSAGING_MESSAGE_ID, work.message.message_id)
    transaction.set_data(::Sentry::Span::DataConventions::MESSAGING_DESTINATION_NAME, extract_queue_name(work))

    if (latency = extract_latency(work.message))
      transaction.set_data(::Sentry::Span::DataConventions::MESSAGING_MESSAGE_RECEIVE_LATENCY, latency)
    end

    if (retry_count = extract_receive_count(work.message))
      transaction.set_data(::Sentry::Span::DataConventions::MESSAGING_MESSAGE_RETRY_COUNT, retry_count)
    end
  end

  begin
    yield
  rescue StandardError
    finish_transaction(transaction, 500)
    raise
  end

  finish_transaction(transaction, 200)
end

#extract_latency(message) ⇒ Object



82
83
84
85
86
# File 'lib/eventboss/sentry/server_middleware.rb', line 82

def extract_latency(message)
  if sent_timestamp = message.attributes.fetch('SentTimestamp', nil)
    Time.now - Time.at(sent_timestamp.to_i / 1000.0)
  end
end

#extract_queue_name(work) ⇒ Object



78
79
80
# File 'lib/eventboss/sentry/server_middleware.rb', line 78

def extract_queue_name(work)
  ::Eventboss::Sentry::Context.queue_name_for_sentry(work.queue.name)
end

#extract_receive_count(message) ⇒ Object



88
89
90
91
92
# File 'lib/eventboss/sentry/server_middleware.rb', line 88

def extract_receive_count(message)
  if receive_count = message.attributes.fetch('ApproximateReceiveCount', nil)
    receive_count.to_i - 1
  end
end

#extract_sentry_user(work) ⇒ Object



68
69
70
71
72
# File 'lib/eventboss/sentry/server_middleware.rb', line 68

def extract_sentry_user(work)
  if (value = work.message.message_attributes["sentry_user"]&.string_value)
    JSON.parse(value)
  end
end

#extract_transaction_name(work) ⇒ Object



74
75
76
# File 'lib/eventboss/sentry/server_middleware.rb', line 74

def extract_transaction_name(work)
  "Eventboss/#{work.listener.to_s}"
end

#finish_transaction(transaction, status) ⇒ Object



61
62
63
64
65
66
# File 'lib/eventboss/sentry/server_middleware.rb', line 61

def finish_transaction(transaction, status)
  return unless transaction

  transaction.set_http_status(status)
  transaction.finish
end

#start_transaction(scope, work) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/eventboss/sentry/server_middleware.rb', line 44

def start_transaction(scope, work)
  options = {
    name: scope.transaction_name,
    source: scope.transaction_source,
    op: OP_NAME,
    origin: SPAN_ORIGIN
  }

  env = {
    'sentry-trace' => work.message.message_attributes['sentry-trace']&.string_value,
    'baggage' => work.message.message_attributes['baggage']&.string_value
  }

  transaction = ::Sentry.continue_trace(env, **options)
  ::Sentry.start_transaction(transaction: transaction, **options)
end