Class: Appsignal::Transaction
Defined Under Namespace
Classes: GenericRequest, NilTransaction
Constant Summary collapse
- HTTP_REQUEST =
"http_request".freeze
- BACKGROUND_JOB =
"background_job".freeze
- ACTION_CABLE =
"action_cable".freeze
- FRONTEND =
"frontend".freeze
- BLANK =
"".freeze
- 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 REQUEST_URI PATH_INFO 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 HTTP_CLIENT_IP HTTP_RANGE ].freeze
Instance Attribute Summary collapse
-
#action ⇒ Object
readonly
Returns the value of attribute action.
-
#discarded ⇒ Object
readonly
Returns the value of attribute discarded.
-
#ext ⇒ Object
readonly
Returns the value of attribute ext.
-
#namespace ⇒ Object
readonly
Returns the value of attribute namespace.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#params ⇒ Hash
Attribute for parameters of the transaction.
-
#paused ⇒ Object
readonly
Returns the value of attribute paused.
-
#request ⇒ Object
readonly
Returns the value of attribute request.
-
#tags ⇒ Object
readonly
Returns the value of attribute tags.
-
#transaction_id ⇒ Object
readonly
Returns the value of attribute transaction_id.
Class Method Summary collapse
-
.clear_current_transaction! ⇒ Object
private
Remove current transaction from current Thread.
- .complete_current! ⇒ Object
- .create(id, namespace, request, options = {}) ⇒ Object
- .current ⇒ Object
- .garbage_collection_profiler ⇒ Object
Instance Method Summary collapse
- #complete ⇒ Object
- #discard! ⇒ Object
- #discarded? ⇒ Boolean
- #finish_event(name, title, body, body_format = Appsignal::EventFormatter::DEFAULT) ⇒ Object
-
#initialize(transaction_id, namespace, request, options = {}) ⇒ Transaction
constructor
A new instance of Transaction.
- #instrument(name, title = nil, body = nil, body_format = Appsignal::EventFormatter::DEFAULT) ⇒ Object
- #nil_transaction? ⇒ Boolean
- #pause! ⇒ Object
- #paused? ⇒ Boolean
- #record_event(name, title, body, duration, body_format = Appsignal::EventFormatter::DEFAULT) ⇒ Object
- #restore! ⇒ Object
- #resume! ⇒ Object
- #sample_data ⇒ Object
-
#set_action(action) ⇒ void
Set an action name for the transaction.
-
#set_action_if_nil(action) ⇒ void
Set an action name only if there is no current action set.
- #set_error(error) ⇒ Object (also: #add_exception)
- #set_http_or_background_action(from = request.params) ⇒ Object
- #set_http_or_background_queue_start ⇒ Object
- #set_metadata(key, value) ⇒ Object
-
#set_namespace(namespace) ⇒ void
Set the namespace for this transaction.
- #set_queue_start(start) ⇒ Object
- #set_sample_data(key, data) ⇒ Object
-
#set_tags(given_tags = {}) ⇒ void
Set tags on the transaction.
- #start_event ⇒ Object
- #store(key) ⇒ Object
- #to_h ⇒ Object (also: #to_hash) private
Constructor Details
#initialize(transaction_id, namespace, request, options = {}) ⇒ Transaction
Returns a new instance of Transaction.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/appsignal/transaction.rb', line 85 def initialize(transaction_id, namespace, request, = {}) @transaction_id = transaction_id @action = nil @namespace = namespace @request = request @paused = false @discarded = false @tags = {} @store = Hash.new({}) @options = @options[:params_method] ||= :params @ext = Appsignal::Extension.start_transaction( @transaction_id, @namespace, self.class.garbage_collection_profiler.total_time ) end |
Instance Attribute Details
#action ⇒ Object (readonly)
Returns the value of attribute action.
71 72 73 |
# File 'lib/appsignal/transaction.rb', line 71 def action @action end |
#discarded ⇒ Object (readonly)
Returns the value of attribute discarded.
71 72 73 |
# File 'lib/appsignal/transaction.rb', line 71 def discarded @discarded end |
#ext ⇒ Object (readonly)
Returns the value of attribute ext.
71 72 73 |
# File 'lib/appsignal/transaction.rb', line 71 def ext @ext end |
#namespace ⇒ Object (readonly)
Returns the value of attribute namespace.
71 72 73 |
# File 'lib/appsignal/transaction.rb', line 71 def namespace @namespace end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
71 72 73 |
# File 'lib/appsignal/transaction.rb', line 71 def @options end |
#params ⇒ Hash
83 |
# File 'lib/appsignal/transaction.rb', line 83 attr_writer :params |
#paused ⇒ Object (readonly)
Returns the value of attribute paused.
71 72 73 |
# File 'lib/appsignal/transaction.rb', line 71 def paused @paused end |
#request ⇒ Object (readonly)
Returns the value of attribute request.
71 72 73 |
# File 'lib/appsignal/transaction.rb', line 71 def request @request end |
#tags ⇒ Object (readonly)
Returns the value of attribute tags.
71 72 73 |
# File 'lib/appsignal/transaction.rb', line 71 def @tags end |
#transaction_id ⇒ Object (readonly)
Returns the value of attribute transaction_id.
71 72 73 |
# File 'lib/appsignal/transaction.rb', line 71 def transaction_id @transaction_id end |
Class Method Details
.clear_current_transaction! ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Remove current transaction from current Thread.
62 63 64 |
# File 'lib/appsignal/transaction.rb', line 62 def clear_current_transaction! Thread.current[:appsignal_transaction] = nil end |
.complete_current! ⇒ Object
52 53 54 55 56 57 58 |
# File 'lib/appsignal/transaction.rb', line 52 def complete_current! current.complete rescue => e Appsignal.logger.error("Failed to complete transaction ##{current.transaction_id}. #{e.}") ensure clear_current_transaction! end |
.create(id, namespace, request, options = {}) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/appsignal/transaction.rb', line 27 def create(id, namespace, request, = {}) # Allow middleware to force a new transaction if .include?(:force) && [:force] Thread.current[:appsignal_transaction] = nil end # Check if we already have a running transaction if Thread.current[:appsignal_transaction] != nil # Log the issue and return the current transaction Appsignal.logger.debug "Trying to start new transaction with id " \ "'#{id}', but a transaction with id '#{current.transaction_id}' " \ "is already running. Using transaction '#{current.transaction_id}'." # Return the current (running) transaction current else # Otherwise, start a new transaction Thread.current[:appsignal_transaction] = Appsignal::Transaction.new(id, namespace, request, ) end end |
.current ⇒ Object
48 49 50 |
# File 'lib/appsignal/transaction.rb', line 48 def current Thread.current[:appsignal_transaction] || NilTransaction.new end |
.garbage_collection_profiler ⇒ Object
66 67 68 |
# File 'lib/appsignal/transaction.rb', line 66 def garbage_collection_profiler @garbage_collection_profiler ||= Appsignal::GarbageCollectionProfiler.new end |
Instance Method Details
#complete ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/appsignal/transaction.rb', line 108 def complete if discarded? Appsignal.logger.debug "Skipping transaction '#{transaction_id}' " \ "because it was manually discarded." return end if @ext.finish(self.class.garbage_collection_profiler.total_time) sample_data end @ext.complete end |
#discard! ⇒ Object
132 133 134 |
# File 'lib/appsignal/transaction.rb', line 132 def discard! @discarded = true end |
#discarded? ⇒ Boolean
140 141 142 |
# File 'lib/appsignal/transaction.rb', line 140 def discarded? @discarded == true end |
#finish_event(name, title, body, body_format = Appsignal::EventFormatter::DEFAULT) ⇒ Object
293 294 295 296 297 298 299 300 301 |
# File 'lib/appsignal/transaction.rb', line 293 def finish_event(name, title, body, body_format = Appsignal::EventFormatter::DEFAULT) @ext.finish_event( name, title || BLANK, body || BLANK, body_format || Appsignal::EventFormatter::DEFAULT, self.class.garbage_collection_profiler.total_time ) end |
#instrument(name, title = nil, body = nil, body_format = Appsignal::EventFormatter::DEFAULT) ⇒ Object
314 315 316 317 318 319 |
# File 'lib/appsignal/transaction.rb', line 314 def instrument(name, title = nil, body = nil, body_format = Appsignal::EventFormatter::DEFAULT) start_event yield if block_given? ensure finish_event(name, title, body, body_format) end |
#nil_transaction? ⇒ Boolean
104 105 106 |
# File 'lib/appsignal/transaction.rb', line 104 def nil_transaction? false end |
#pause! ⇒ Object
120 121 122 |
# File 'lib/appsignal/transaction.rb', line 120 def pause! @paused = true end |
#paused? ⇒ Boolean
128 129 130 |
# File 'lib/appsignal/transaction.rb', line 128 def paused? @paused == true end |
#record_event(name, title, body, duration, body_format = Appsignal::EventFormatter::DEFAULT) ⇒ Object
303 304 305 306 307 308 309 310 311 312 |
# File 'lib/appsignal/transaction.rb', line 303 def record_event(name, title, body, duration, body_format = Appsignal::EventFormatter::DEFAULT) @ext.record_event( name, title || BLANK, body || BLANK, body_format || Appsignal::EventFormatter::DEFAULT, duration, self.class.garbage_collection_profiler.total_time ) end |
#restore! ⇒ Object
136 137 138 |
# File 'lib/appsignal/transaction.rb', line 136 def restore! @discarded = false end |
#resume! ⇒ Object
124 125 126 |
# File 'lib/appsignal/transaction.rb', line 124 def resume! @paused = false end |
#sample_data ⇒ Object
264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/appsignal/transaction.rb', line 264 def sample_data { :params => sanitized_params, :environment => sanitized_environment, :session_data => sanitized_session_data, :metadata => , :tags => }.each do |key, data| set_sample_data(key, data) end end |
#set_action(action) ⇒ void
This method returns an undefined value.
Set an action name for the transaction.
An action name is used to identify the location of a certain sample; error and performance issues.
179 180 181 182 183 |
# File 'lib/appsignal/transaction.rb', line 179 def set_action(action) return unless action @action = action @ext.set_action(action) end |
#set_action_if_nil(action) ⇒ void
This method returns an undefined value.
Set an action name only if there is no current action set.
Commonly used by AppSignal integrations so that they don't override custom action names.
199 200 201 202 |
# File 'lib/appsignal/transaction.rb', line 199 def set_action_if_nil(action) return if @action set_action(action) end |
#set_error(error) ⇒ Object Also known as: add_exception
276 277 278 279 280 281 282 283 284 285 286 |
# File 'lib/appsignal/transaction.rb', line 276 def set_error(error) return unless error return unless Appsignal.active? backtrace = cleaned_backtrace(error.backtrace) @ext.set_error( error.class.name, error..to_s, backtrace ? Appsignal::Utils.data_generate(backtrace) : Appsignal::Extension.data_array_new ) end |
#set_http_or_background_action(from = request.params) ⇒ Object
225 226 227 228 229 230 231 232 |
# File 'lib/appsignal/transaction.rb', line 225 def set_http_or_background_action(from = request.params) return unless from group_and_action = [ from[:controller] || from[:class], from[:action] || from[:method] ] set_action(group_and_action.compact.join("#")) end |
#set_http_or_background_queue_start ⇒ Object
241 242 243 244 245 246 247 |
# File 'lib/appsignal/transaction.rb', line 241 def set_http_or_background_queue_start if namespace == HTTP_REQUEST set_queue_start(http_queue_start) elsif namespace == BACKGROUND_JOB set_queue_start(background_queue_start) end end |
#set_metadata(key, value) ⇒ Object
249 250 251 252 |
# File 'lib/appsignal/transaction.rb', line 249 def (key, value) return unless key && value @ext.(key, value) end |
#set_namespace(namespace) ⇒ void
This method returns an undefined value.
Set the namespace for this transaction.
Useful to split up parts of an application into certain namespaces. For example: http requests, background jobs and administration panel controllers.
Note: The "http_request" namespace gets transformed on AppSignal.com to "Web" and "background_job" gets transformed to "Background".
219 220 221 222 223 |
# File 'lib/appsignal/transaction.rb', line 219 def set_namespace(namespace) return unless namespace @namespace = namespace @ext.set_namespace(namespace) end |
#set_queue_start(start) ⇒ Object
234 235 236 237 238 239 |
# File 'lib/appsignal/transaction.rb', line 234 def set_queue_start(start) return unless start @ext.set_queue_start(start) rescue RangeError Appsignal.logger.warn("Queue start value #{start} is too big") end |
#set_sample_data(key, data) ⇒ Object
254 255 256 257 258 259 260 261 262 |
# File 'lib/appsignal/transaction.rb', line 254 def set_sample_data(key, data) return unless key && data && (data.is_a?(Array) || data.is_a?(Hash)) @ext.set_sample_data( key.to_s, Appsignal::Utils.data_generate(data) ) rescue RuntimeError => e Appsignal.logger.error("Error generating data (#{e.class}: #{e.}) for '#{data.inspect}'") end |
#set_tags(given_tags = {}) ⇒ void
This method returns an undefined value.
Set tags on the transaction.
165 166 167 |
# File 'lib/appsignal/transaction.rb', line 165 def ( = {}) @tags.merge!() end |
#start_event ⇒ Object
289 290 291 |
# File 'lib/appsignal/transaction.rb', line 289 def start_event @ext.start_event(self.class.garbage_collection_profiler.total_time) end |
#store(key) ⇒ Object
144 145 146 |
# File 'lib/appsignal/transaction.rb', line 144 def store(key) @store[key] end |
#to_h ⇒ Object Also known as: to_hash
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
322 323 324 |
# File 'lib/appsignal/transaction.rb', line 322 def to_h JSON.parse(@ext.to_json) end |