Class: Appsignal::Transaction

Inherits:
Object
  • Object
show all
Defined in:
lib/appsignal/transaction.rb,
lib/appsignal/transaction/formatter.rb,
lib/appsignal/transaction/params_sanitizer.rb

Defined Under Namespace

Classes: Formatter, ParamsSanitizer, ParamsSanitizerCopy, ParamsSanitizerCopyScrub, ParamsSanitizerDestructive, ParamsSanitizerDestructiveScrub

Constant Summary collapse

ENV_METHODS =

Based on what Rails uses + some variables we’d like to show

%w(CONTENT_LENGTH AUTH_TYPE GATEWAY_INTERFACE
PATH_TRANSLATED REMOTE_HOST REMOTE_IDENT REMOTE_USER REMOTE_ADDR
REQUEST_METHOD SERVER_NAME SERVER_PORT SERVER_PROTOCOL

HTTP_X_REQUEST_START HTTP_X_MIDDLEWARE_START HTTP_X_QUEUE_START
HTTP_X_QUEUE_TIME HTTP_X_HEROKU_QUEUE_WAIT_TIME HTTP_X_APPLICATION_START
HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING HTTP_ACCEPT_LANGUAGE
HTTP_CACHE_CONTROL HTTP_CONNECTION HTTP_USER_AGENT HTTP_FROM HTTP_NEGOTIATE
HTTP_PRAGMA HTTP_REFERER HTTP_X_FORWARDED_FOR).freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(request_id, env) ⇒ Transaction

Returns a new instance of Transaction.



27
28
29
30
31
32
33
34
# File 'lib/appsignal/transaction.rb', line 27

def initialize(request_id, env)
  @request_id = request_id
  @events = []
  @process_action_event = nil
  @exception = nil
  @env = env
  @tags = {}
end

Instance Attribute Details

#actionObject (readonly)

Returns the value of attribute action.



24
25
26
# File 'lib/appsignal/transaction.rb', line 24

def action
  @action
end

#envObject (readonly)

Returns the value of attribute env.



24
25
26
# File 'lib/appsignal/transaction.rb', line 24

def env
  @env
end

#eventsObject (readonly)

Returns the value of attribute events.



24
25
26
# File 'lib/appsignal/transaction.rb', line 24

def events
  @events
end

#exceptionObject (readonly)

Returns the value of attribute exception.



24
25
26
# File 'lib/appsignal/transaction.rb', line 24

def exception
  @exception
end

#fullpathObject (readonly)

Returns the value of attribute fullpath.



24
25
26
# File 'lib/appsignal/transaction.rb', line 24

def fullpath
  @fullpath
end

#kindObject (readonly)

Returns the value of attribute kind.



24
25
26
# File 'lib/appsignal/transaction.rb', line 24

def kind
  @kind
end

#process_action_eventObject (readonly)

Returns the value of attribute process_action_event.



24
25
26
# File 'lib/appsignal/transaction.rb', line 24

def process_action_event
  @process_action_event
end

#queue_startObject (readonly)

Returns the value of attribute queue_start.



24
25
26
# File 'lib/appsignal/transaction.rb', line 24

def queue_start
  @queue_start
end

#request_idObject (readonly)

Returns the value of attribute request_id.



24
25
26
# File 'lib/appsignal/transaction.rb', line 24

def request_id
  @request_id
end

#tagsObject (readonly)

Returns the value of attribute tags.



24
25
26
# File 'lib/appsignal/transaction.rb', line 24

def tags
  @tags
end

#timeObject (readonly)

Returns the value of attribute time.



24
25
26
# File 'lib/appsignal/transaction.rb', line 24

def time
  @time
end

Class Method Details

.create(key, env) ⇒ Object



14
15
16
17
18
# File 'lib/appsignal/transaction.rb', line 14

def self.create(key, env)
  Appsignal.logger.debug("Creating transaction: #{key}")
  Thread.current[:appsignal_transaction_id] = key
  Appsignal.transactions[key] = Appsignal::Transaction.new(key, env)
end

.currentObject



20
21
22
# File 'lib/appsignal/transaction.rb', line 20

def self.current
  Appsignal.transactions[Thread.current[:appsignal_transaction_id]]
end

Instance Method Details

#add_event(event) ⇒ Object



68
69
70
# File 'lib/appsignal/transaction.rb', line 68

def add_event(event)
  @events << event
end

#add_exception(ex) ⇒ Object



72
73
74
75
# File 'lib/appsignal/transaction.rb', line 72

def add_exception(ex)
  @time = Time.now.utc.to_f
  @exception = ex
end

#complete!Object



117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/appsignal/transaction.rb', line 117

def complete!
  Appsignal.logger.debug("Completing transaction: #{@request_id}")
  Thread.current[:appsignal_transaction_id] = nil
  current_transaction = Appsignal.transactions.delete(@request_id)
  if process_action_event || exception?
    if Appsignal::Pipe.current
      Appsignal::Pipe.current.write(self)
    else
      Appsignal.enqueue(current_transaction)
    end
  else
    Appsignal.logger.debug("No process_action_event or exception: #{@request_id}")
  end
end

#convert_values_to_primitives!Object



99
100
101
102
103
104
105
# File 'lib/appsignal/transaction.rb', line 99

def convert_values_to_primitives!
  Appsignal::Transaction::ParamsSanitizer.sanitize!(@process_action_event.payload) if @process_action_event
  @events.map do |o|
    Appsignal::Transaction::ParamsSanitizer.sanitize(o.payload)
  end
  add_sanitized_context!
end

#exception?Boolean

Returns:

  • (Boolean)


77
78
79
# File 'lib/appsignal/transaction.rb', line 77

def exception?
  !!exception
end

#requestObject



44
45
46
# File 'lib/appsignal/transaction.rb', line 44

def request
  ::Rack::Request.new(@env)
end

#sanitized_environmentObject



36
37
38
# File 'lib/appsignal/transaction.rb', line 36

def sanitized_environment
  @sanitized_environment ||= {}
end

#sanitized_session_dataObject



40
41
42
# File 'lib/appsignal/transaction.rb', line 40

def sanitized_session_data
  @sanitized_session_data ||= {}
end

#set_background_queue_startObject



132
133
134
135
136
137
# File 'lib/appsignal/transaction.rb', line 132

def set_background_queue_start
  queue_start = process_action_event.payload[:queue_start]
  return unless queue_start
  Appsignal.logger.debug("Setting background queue start: #{queue_start}")
  @queue_start = queue_start.to_f
end

#set_http_queue_startObject



139
140
141
142
143
144
145
146
147
148
149
# File 'lib/appsignal/transaction.rb', line 139

def set_http_queue_start
  return unless env
  env_var = env['HTTP_X_QUEUE_START'] || env['HTTP_X_REQUEST_START']
  if env_var
    Appsignal.logger.debug("Setting http queue start: #{env_var}")
    value = env_var.tr('^0-9', '')
    unless value.empty?
      @queue_start = value.to_f / 1000.0
    end
  end
end

#set_perform_job_event(event) ⇒ Object



60
61
62
63
64
65
66
# File 'lib/appsignal/transaction.rb', line 60

def set_perform_job_event(event)
  return unless event && event.payload
  @process_action_event = event.dup
  @action = "#{@process_action_event.payload[:class]}##{@process_action_event.payload[:method]}"
  @kind = 'background_job'
  set_background_queue_start
end

#set_process_action_event(event) ⇒ Object



52
53
54
55
56
57
58
# File 'lib/appsignal/transaction.rb', line 52

def set_process_action_event(event)
  return unless event && event.payload
  @process_action_event = event.dup
  @action = "#{@process_action_event.payload[:controller]}##{@process_action_event.payload[:action]}"
  @kind = 'http_request'
  set_http_queue_start
end

#set_tags(given_tags = {}) ⇒ Object



48
49
50
# File 'lib/appsignal/transaction.rb', line 48

def set_tags(given_tags={})
  @tags.merge!(given_tags)
end

#slow_request?Boolean

Returns:

  • (Boolean)


81
82
83
84
# File 'lib/appsignal/transaction.rb', line 81

def slow_request?
  return false unless process_action_event && process_action_event.payload
  Appsignal.config[:slow_request_threshold] <= process_action_event.duration
end

#slower?(transaction) ⇒ Boolean

Returns:

  • (Boolean)


86
87
88
# File 'lib/appsignal/transaction.rb', line 86

def slower?(transaction)
  process_action_event.duration > transaction.process_action_event.duration
end

#to_hashObject



113
114
115
# File 'lib/appsignal/transaction.rb', line 113

def to_hash
  Formatter.new(self).to_hash
end

#truncate!Object



90
91
92
93
94
95
96
97
# File 'lib/appsignal/transaction.rb', line 90

def truncate!
  process_action_event.payload.clear
  events.clear
  tags.clear
  sanitized_environment.clear
  sanitized_session_data.clear
  @env = nil
end

#typeObject



107
108
109
110
111
# File 'lib/appsignal/transaction.rb', line 107

def type
  return :exception if exception?
  return :slow_request if slow_request?
  :regular_request
end