Class: Appsignal::Transaction
Defined Under Namespace
Classes: NilTransaction
Constant Summary collapse
- HTTP_REQUEST =
"http_request"
- BACKGROUND_JOB =
"background_job"
- ACTION_CABLE =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
"action_cable"
- BLANK =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
""
- ALLOWED_TAG_KEY_TYPES =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
[Symbol, String].freeze
- ALLOWED_TAG_VALUE_TYPES =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
[Symbol, String, Integer, TrueClass, FalseClass].freeze
- BREADCRUMB_LIMIT =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
20
- ERROR_CAUSES_LIMIT =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
10
- ERRORS_LIMIT =
10
Class Attribute Summary collapse
- .last_errors ⇒ Object private
Instance Attribute Summary collapse
- #action ⇒ Object readonly private
- #namespace ⇒ Object readonly private
- #transaction_id ⇒ Object readonly private
Class Method Summary collapse
-
.after_create(&block) ⇒ Array<Proc>
private
Add a block, if given, to be executed after a transaction is created.
-
.before_complete(&block) ⇒ Array<Proc>
private
Add a block, if given, to be executed before a transaction is completed.
-
.clear_current_transaction! ⇒ Object
private
Remove current transaction from current Thread.
-
.complete_current! ⇒ Object
Complete the currently active transaction and unset it as the active transaction.
-
.create(namespace) ⇒ Transaction
Create a new transaction and set it as the currently active transaction.
-
.current ⇒ Boolean
Returns currently active transaction or a NilTransaction if none is active.
-
.current? ⇒ Boolean
Returns if any transaction is currently active or not.
- .set_current_transaction(transaction) ⇒ Object private
-
.with_transaction(transaction) ⇒ Object
private
Set the current for the duration of the given block.
Instance Method Summary collapse
-
#add_breadcrumb(category, action, message = "", metadata = {}, time = Time.now.utc) ⇒ void
Add breadcrumbs to the transaction.
-
#add_custom_data(data) ⇒ void
(also: #set_custom_data)
Add custom data to the transaction.
- #add_error(error, &block) ⇒ Object (also: #set_error, #add_exception) private
-
#add_headers(given_headers = nil) { ... } ⇒ void
(also: #set_headers)
Add headers to the transaction.
-
#add_headers_if_nil(given_headers = nil) { ... } ⇒ void
(also: #set_headers_if_nil)
private
Add headers to the transaction if not already set.
-
#add_params(given_params = nil) { ... } ⇒ void
(also: #set_params)
Add parameters to the transaction.
-
#add_params_if_nil(given_params = nil) { ... } ⇒ void
(also: #set_params_if_nil)
private
Add parameters to the transaction if not already set.
-
#add_session_data(given_session_data = nil) { ... } ⇒ void
(also: #set_session_data)
Add session data to the transaction.
-
#add_session_data_if_nil(given_session_data = nil) { ... } ⇒ void
(also: #set_session_data_if_nil)
private
Set session data on the transaction if not already set.
-
#add_tags(given_tags = {}) ⇒ void
(also: #set_tags)
Add tags to the transaction.
- #complete ⇒ Object private
- #discard! ⇒ Object private
- #discarded? ⇒ Boolean private
- #duplicate? ⇒ Boolean private
- #finish_event(name, title, body, body_format = Appsignal::EventFormatter::DEFAULT) ⇒ Object private
-
#initialize(namespace, id: SecureRandom.uuid, ext: nil) ⇒ Transaction
constructor
private
Use Transaction.create to create new transactions.
- #instrument(name, title = nil, body = nil, body_format = Appsignal::EventFormatter::DEFAULT) ⇒ Object private
- #nil_transaction? ⇒ Boolean private
- #pause! ⇒ Object private
- #paused? ⇒ Boolean private
- #record_event(name, title, body, duration, body_format = Appsignal::EventFormatter::DEFAULT) ⇒ Object private
- #restore! ⇒ Object private
- #resume! ⇒ Object private
-
#set_action(action) ⇒ void
Set an action name for the transaction.
-
#set_action_if_nil(action) ⇒ void
private
Set an action name only if there is no current action set.
- #set_empty_params! ⇒ void private
- #set_metadata(key, value) ⇒ Object private
-
#set_namespace(namespace) ⇒ void
Set the namespace for this transaction.
-
#set_queue_start(start) ⇒ void
Set queue start time for transaction.
- #start_event ⇒ Object private
- #store(key) ⇒ Object private
- #to_h ⇒ Object (also: #to_hash) private
Constructor Details
#initialize(namespace, id: SecureRandom.uuid, ext: nil) ⇒ Transaction
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.
Use create to create new transactions.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/appsignal/transaction.rb', line 151 def initialize(namespace, id: SecureRandom.uuid, ext: nil) @transaction_id = id @action = nil @namespace = namespace @paused = false @discarded = false @tags = {} @breadcrumbs = [] @store = Hash.new { |hash, key| hash[key] = {} } @error_blocks = Hash.new { |hash, key| hash[key] = [] } @is_duplicate = false @error_set = nil @params = Appsignal::SampleData.new(:params) @session_data = Appsignal::SampleData.new(:session_data, Hash) @headers = Appsignal::SampleData.new(:headers, Hash) @custom_data = Appsignal::SampleData.new(:custom_data) @ext = ext || Appsignal::Extension.start_transaction( @transaction_id, @namespace, 0 ) || Appsignal::Extension::MockTransaction.new run_after_create_hooks end |
Class Attribute Details
.last_errors ⇒ 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.
135 136 137 |
# File 'lib/appsignal/transaction.rb', line 135 def last_errors @last_errors ||= [] end |
Instance Attribute Details
#action ⇒ Object (readonly)
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.
144 145 146 |
# File 'lib/appsignal/transaction.rb', line 144 def action @action end |
#namespace ⇒ Object (readonly)
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.
144 145 146 |
# File 'lib/appsignal/transaction.rb', line 144 def namespace @namespace end |
#transaction_id ⇒ Object (readonly)
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.
144 145 146 |
# File 'lib/appsignal/transaction.rb', line 144 def transaction_id @transaction_id end |
Class Method Details
.after_create(&block) ⇒ Array<Proc>
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.
Add a block, if given, to be executed after a transaction is created. The block will be called with the transaction as an argument. Returns the array of blocks that will be executed after a transaction is created.
53 54 55 56 57 58 59 |
# File 'lib/appsignal/transaction.rb', line 53 def after_create(&block) @after_create ||= Set.new return @after_create if block.nil? @after_create << block end |
.before_complete(&block) ⇒ Array<Proc>
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.
Add a block, if given, to be executed before a transaction is completed. This happens after duplicating the transaction for each error that was reported in the transaction – that is, when a transaction with several errors is completed, the block will be called once for each error, with the transaction (either the original one or a duplicate of it) that has each of the errors set. The block will be called with the transaction as the first argument, and the error reported by the transaction, if any, as the second argument. Returns the array of blocks that will be executed before a transaction is completed.
73 74 75 76 77 78 79 |
# File 'lib/appsignal/transaction.rb', line 73 def before_complete(&block) @before_complete ||= Set.new return @before_complete if block.nil? @before_complete << block end |
.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.
130 131 132 |
# File 'lib/appsignal/transaction.rb', line 130 def clear_current_transaction! Thread.current[:appsignal_transaction] = nil end |
.complete_current! ⇒ Object
Complete the currently active transaction and unset it as the active transaction.
118 119 120 121 122 123 124 125 126 |
# File 'lib/appsignal/transaction.rb', line 118 def complete_current! current.complete rescue => e Appsignal.internal_logger.error( "Failed to complete transaction ##{current.transaction_id}. #{e.}" ) ensure clear_current_transaction! end |
.create(namespace) ⇒ Transaction
Create a new transaction and set it as the currently active transaction.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/appsignal/transaction.rb', line 29 def create(namespace) # Check if we already have a running transaction if Thread.current[:appsignal_transaction].nil? # If not, start a new transaction set_current_transaction(Appsignal::Transaction.new(namespace)) else # Otherwise, log the issue about trying to start another transaction Appsignal.internal_logger.warn( "Trying to start new transaction, but a transaction " \ "with id '#{current.transaction_id}' is already running. " \ "Using transaction '#{current.transaction_id}'." ) # And return the current transaction instead current end end |
.current ⇒ Boolean
Returns currently active transaction or a NilTransaction if none is active.
103 104 105 |
# File 'lib/appsignal/transaction.rb', line 103 def current Thread.current[:appsignal_transaction] || NilTransaction.new end |
.current? ⇒ Boolean
Returns if any transaction is currently active or not. A NilTransaction is not considered an active transaction.
112 113 114 |
# File 'lib/appsignal/transaction.rb', line 112 def current? current && !current.nil_transaction? end |
.set_current_transaction(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.
82 83 84 |
# File 'lib/appsignal/transaction.rb', line 82 def set_current_transaction(transaction) Thread.current[:appsignal_transaction] = transaction end |
.with_transaction(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.
Set the current for the duration of the given block. It restores the original transaction (if any) when the block has executed.
90 91 92 93 94 95 96 |
# File 'lib/appsignal/transaction.rb', line 90 def with_transaction(transaction) original_transaction = current if current? set_current_transaction(transaction) yield ensure set_current_transaction(original_transaction) end |
Instance Method Details
#add_breadcrumb(category, action, message = "", metadata = {}, time = Time.now.utc) ⇒ void
This method returns an undefined value.
Add breadcrumbs to the transaction.
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 |
# File 'lib/appsignal/transaction.rb', line 445 def (category, action, = "", = {}, time = Time.now.utc) unless .is_a? Hash Appsignal.internal_logger.error "add_breadcrumb: Cannot add breadcrumb. " \ "The given metadata argument is not a Hash." return end @breadcrumbs.push( :time => time.to_i, :category => category, :action => action, :message => , :metadata => ) @breadcrumbs = @breadcrumbs.last(BREADCRUMB_LIMIT) end |
#add_custom_data(data) ⇒ void Also known as: set_custom_data
This method returns an undefined value.
Add custom data to the transaction.
426 427 428 |
# File 'lib/appsignal/transaction.rb', line 426 def add_custom_data(data) @custom_data.add(data) end |
#add_error(error, &block) ⇒ Object Also known as: set_error, add_exception
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.
553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 |
# File 'lib/appsignal/transaction.rb', line 553 def add_error(error, &block) unless error.is_a?(Exception) Appsignal.internal_logger.error "Appsignal::Transaction#add_error: Cannot add error. " \ "The given value is not an exception: #{error.inspect}" return end return unless error return unless Appsignal.active? _set_error(error) if @error_blocks.empty? if !@error_blocks.include?(error) && @error_blocks.length >= ERRORS_LIMIT Appsignal.internal_logger.warn "Appsignal::Transaction#add_error: Transaction has more " \ "than #{ERRORS_LIMIT} distinct errors. Only the first " \ "#{ERRORS_LIMIT} distinct errors will be reported." return end @error_blocks[error] << block @error_blocks[error].compact! end |
#add_headers(given_headers = nil) { ... } ⇒ void Also known as: set_headers
This method returns an undefined value.
Add headers to the transaction.
392 393 394 |
# File 'lib/appsignal/transaction.rb', line 392 def add_headers(given_headers = nil, &block) @headers.add(given_headers, &block) end |
#add_headers_if_nil(given_headers = nil) { ... } ⇒ void Also known as: set_headers_if_nil
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.
This method returns an undefined value.
Add headers to the transaction if not already set.
When both the ‘given_headers` and a block is given to this method, the block is leading and the argument will not be used.
412 413 414 |
# File 'lib/appsignal/transaction.rb', line 412 def add_headers_if_nil(given_headers = nil, &block) add_headers(given_headers, &block) unless @headers.value? end |
#add_params(given_params = nil) { ... } ⇒ void Also known as: set_params
This method returns an undefined value.
Add parameters to the transaction.
When this method is called multiple times, it will merge the request parameters.
When both the ‘given_params` and a block is given to this method, the block is leading and the argument will not be used.
290 291 292 |
# File 'lib/appsignal/transaction.rb', line 290 def add_params(given_params = nil, &block) @params.add(given_params, &block) end |
#add_params_if_nil(given_params = nil) { ... } ⇒ void Also known as: set_params_if_nil
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.
This method returns an undefined value.
Add parameters to the transaction if not already set.
314 315 316 |
# File 'lib/appsignal/transaction.rb', line 314 def add_params_if_nil(given_params = nil, &block) add_params(given_params, &block) if !@params.value? && !@params.empty? end |
#add_session_data(given_session_data = nil) { ... } ⇒ void Also known as: set_session_data
This method returns an undefined value.
Add session data to the transaction.
When this method is called multiple times, it will merge the session data.
When both the ‘given_session_data` and a block is given to this method, the block is leading and the argument will not be used.
355 356 357 |
# File 'lib/appsignal/transaction.rb', line 355 def add_session_data(given_session_data = nil, &block) @session_data.add(given_session_data, &block) end |
#add_session_data_if_nil(given_session_data = nil) { ... } ⇒ void Also known as: set_session_data_if_nil
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.
This method returns an undefined value.
Set session data on the transaction if not already set.
When both the ‘given_session_data` and a block is given to this method, the `given_session_data` argument is leading and the block will not be called.
376 377 378 |
# File 'lib/appsignal/transaction.rb', line 376 def add_session_data_if_nil(given_session_data = nil, &block) add_session_data(given_session_data, &block) unless @session_data.value? end |
#add_tags(given_tags = {}) ⇒ void Also known as:
This method returns an undefined value.
Add tags to the transaction.
When this method is called multiple times, it will merge the tags.
334 335 336 |
# File 'lib/appsignal/transaction.rb', line 334 def ( = {}) @tags.merge!() end |
#complete ⇒ 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.
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/appsignal/transaction.rb', line 189 def complete if discarded? Appsignal.internal_logger.debug "Skipping transaction '#{transaction_id}' " \ "because it was manually discarded." return end # If the transaction is a duplicate, we don't want to finish it, # because we want its finish time to be the finish time of the # original transaction. # Duplicate transactions should always be sampled, as we only # create duplicates for errors, which are always sampled. should_sample = true unless duplicate? self.class.last_errors = @error_blocks.keys should_sample = @ext.finish(0) end @error_blocks.each do |error, blocks| # Ignore the error that is already set in this transaction. next if error == @error_set duplicate.tap do |transaction| # In the duplicate transaction for each error, set an error # with a block that calls all the blocks set for that error # in the original transaction. transaction.set_error(error) do blocks.each { |block| block.call(transaction) } end transaction.complete end end if @error_set && @error_blocks[@error_set].any? self.class.with_transaction(self) do @error_blocks[@error_set].each do |block| block.call(self) end end end run_before_complete_hooks sample_data if should_sample @ext.complete end |
#discard! ⇒ 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.
255 256 257 |
# File 'lib/appsignal/transaction.rb', line 255 def discard! @discarded = true end |
#discarded? ⇒ Boolean
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.
265 266 267 |
# File 'lib/appsignal/transaction.rb', line 265 def discarded? @discarded == true end |
#duplicate? ⇒ Boolean
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.
179 180 181 |
# File 'lib/appsignal/transaction.rb', line 179 def duplicate? @is_duplicate end |
#finish_event(name, title, body, body_format = Appsignal::EventFormatter::DEFAULT) ⇒ 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.
588 589 590 591 592 593 594 595 596 597 598 |
# File 'lib/appsignal/transaction.rb', line 588 def finish_event(name, title, body, body_format = Appsignal::EventFormatter::DEFAULT) return if paused? @ext.finish_event( name, title || BLANK, body || BLANK, body_format || Appsignal::EventFormatter::DEFAULT, 0 ) end |
#instrument(name, title = nil, body = nil, body_format = Appsignal::EventFormatter::DEFAULT) ⇒ 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.
617 618 619 620 621 622 |
# File 'lib/appsignal/transaction.rb', line 617 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
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.
184 185 186 |
# File 'lib/appsignal/transaction.rb', line 184 def nil_transaction? false end |
#pause! ⇒ 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.
240 241 242 |
# File 'lib/appsignal/transaction.rb', line 240 def pause! @paused = true end |
#paused? ⇒ Boolean
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.
250 251 252 |
# File 'lib/appsignal/transaction.rb', line 250 def paused? @paused == true end |
#record_event(name, title, body, duration, body_format = Appsignal::EventFormatter::DEFAULT) ⇒ 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.
602 603 604 605 606 607 608 609 610 611 612 613 |
# File 'lib/appsignal/transaction.rb', line 602 def record_event(name, title, body, duration, body_format = Appsignal::EventFormatter::DEFAULT) return if paused? @ext.record_event( name, title || BLANK, body || BLANK, body_format || Appsignal::EventFormatter::DEFAULT, duration, 0 ) end |
#restore! ⇒ 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.
260 261 262 |
# File 'lib/appsignal/transaction.rb', line 260 def restore! @discarded = false end |
#resume! ⇒ 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.
245 246 247 |
# File 'lib/appsignal/transaction.rb', line 245 def resume! @paused = false 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.
472 473 474 475 476 477 |
# File 'lib/appsignal/transaction.rb', line 472 def set_action(action) return unless action @action = action @ext.set_action(action) end |
#set_action_if_nil(action) ⇒ void
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.
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.
495 496 497 498 499 |
# File 'lib/appsignal/transaction.rb', line 495 def set_action_if_nil(action) return if @action set_action(action) end |
#set_empty_params! ⇒ void
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.
This method returns an undefined value.
300 301 302 |
# File 'lib/appsignal/transaction.rb', line 300 def set_empty_params! @params.set_empty_value! end |
#set_metadata(key, value) ⇒ 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.
544 545 546 547 548 549 |
# File 'lib/appsignal/transaction.rb', line 544 def (key, value) return unless key && value return if Appsignal.config[:filter_metadata].include?(key.to_s) @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”.
520 521 522 523 524 525 |
# File 'lib/appsignal/transaction.rb', line 520 def set_namespace(namespace) return unless namespace @namespace = namespace @ext.set_namespace(namespace) end |
#set_queue_start(start) ⇒ void
This method returns an undefined value.
Set queue start time for transaction.
535 536 537 538 539 540 541 |
# File 'lib/appsignal/transaction.rb', line 535 def set_queue_start(start) return unless start @ext.set_queue_start(start) rescue RangeError Appsignal.internal_logger.warn("Queue start value #{start} is too big") end |
#start_event ⇒ 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.
580 581 582 583 584 |
# File 'lib/appsignal/transaction.rb', line 580 def start_event return if paused? @ext.start_event(0) end |
#store(key) ⇒ 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.
270 271 272 |
# File 'lib/appsignal/transaction.rb', line 270 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.
625 626 627 |
# File 'lib/appsignal/transaction.rb', line 625 def to_h JSON.parse(@ext.to_json) end |