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
- ALLOWED_TAG_KEY_TYPES =
[Symbol, String].freeze
- ALLOWED_TAG_VALUE_TYPES =
[Symbol, String, Integer].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.
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/appsignal/transaction.rb', line 75 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.
61 62 63 |
# File 'lib/appsignal/transaction.rb', line 61 def action @action end |
#discarded ⇒ Object (readonly)
Returns the value of attribute discarded.
61 62 63 |
# File 'lib/appsignal/transaction.rb', line 61 def discarded @discarded end |
#ext ⇒ Object (readonly)
Returns the value of attribute ext.
61 62 63 |
# File 'lib/appsignal/transaction.rb', line 61 def ext @ext end |
#namespace ⇒ Object (readonly)
Returns the value of attribute namespace.
61 62 63 |
# File 'lib/appsignal/transaction.rb', line 61 def namespace @namespace end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
61 62 63 |
# File 'lib/appsignal/transaction.rb', line 61 def @options end |
#params ⇒ Hash
73 |
# File 'lib/appsignal/transaction.rb', line 73 attr_writer :params |
#paused ⇒ Object (readonly)
Returns the value of attribute paused.
61 62 63 |
# File 'lib/appsignal/transaction.rb', line 61 def paused @paused end |
#request ⇒ Object (readonly)
Returns the value of attribute request.
61 62 63 |
# File 'lib/appsignal/transaction.rb', line 61 def request @request end |
#tags ⇒ Object (readonly)
Returns the value of attribute tags.
61 62 63 |
# File 'lib/appsignal/transaction.rb', line 61 def @tags end |
#transaction_id ⇒ Object (readonly)
Returns the value of attribute transaction_id.
61 62 63 |
# File 'lib/appsignal/transaction.rb', line 61 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.
51 52 53 |
# File 'lib/appsignal/transaction.rb', line 51 def clear_current_transaction! Thread.current[:appsignal_transaction] = nil end |
.complete_current! ⇒ Object
41 42 43 44 45 46 47 |
# File 'lib/appsignal/transaction.rb', line 41 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
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/appsignal/transaction.rb', line 16 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? # If not, start a new transaction Thread.current[:appsignal_transaction] = Appsignal::Transaction.new(id, namespace, request, ) else # Otherwise, log the issue about trying to start another 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}'." # And return the current transaction instead current end end |
.current ⇒ Object
37 38 39 |
# File 'lib/appsignal/transaction.rb', line 37 def current Thread.current[:appsignal_transaction] || NilTransaction.new end |
.garbage_collection_profiler ⇒ Object
55 56 57 58 |
# File 'lib/appsignal/transaction.rb', line 55 def garbage_collection_profiler @garbage_collection_profiler ||= Appsignal.config[:enable_gc_instrumentation] ? Appsignal::GarbageCollectionProfiler.new : NilGarbageCollectionProfiler.new end |
Instance Method Details
#complete ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/appsignal/transaction.rb', line 98 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
122 123 124 |
# File 'lib/appsignal/transaction.rb', line 122 def discard! @discarded = true end |
#discarded? ⇒ Boolean
130 131 132 |
# File 'lib/appsignal/transaction.rb', line 130 def discarded? @discarded == true end |
#finish_event(name, title, body, body_format = Appsignal::EventFormatter::DEFAULT) ⇒ Object
289 290 291 292 293 294 295 296 297 298 |
# File 'lib/appsignal/transaction.rb', line 289 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, self.class.garbage_collection_profiler.total_time ) end |
#instrument(name, title = nil, body = nil, body_format = Appsignal::EventFormatter::DEFAULT) ⇒ Object
312 313 314 315 316 317 |
# File 'lib/appsignal/transaction.rb', line 312 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
94 95 96 |
# File 'lib/appsignal/transaction.rb', line 94 def nil_transaction? false end |
#pause! ⇒ Object
110 111 112 |
# File 'lib/appsignal/transaction.rb', line 110 def pause! @paused = true end |
#paused? ⇒ Boolean
118 119 120 |
# File 'lib/appsignal/transaction.rb', line 118 def paused? @paused == true end |
#record_event(name, title, body, duration, body_format = Appsignal::EventFormatter::DEFAULT) ⇒ Object
300 301 302 303 304 305 306 307 308 309 310 |
# File 'lib/appsignal/transaction.rb', line 300 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, self.class.garbage_collection_profiler.total_time ) end |
#restore! ⇒ Object
126 127 128 |
# File 'lib/appsignal/transaction.rb', line 126 def restore! @discarded = false end |
#resume! ⇒ Object
114 115 116 |
# File 'lib/appsignal/transaction.rb', line 114 def resume! @paused = false end |
#sample_data ⇒ Object
254 255 256 257 258 259 260 261 262 263 264 |
# File 'lib/appsignal/transaction.rb', line 254 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.
169 170 171 172 173 |
# File 'lib/appsignal/transaction.rb', line 169 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.
189 190 191 192 |
# File 'lib/appsignal/transaction.rb', line 189 def set_action_if_nil(action) return if @action set_action(action) end |
#set_error(error) ⇒ Object Also known as: add_exception
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 |
# File 'lib/appsignal/transaction.rb', line 266 def set_error(error) unless error.is_a?(Exception) Appsignal.logger.error "Appsignal::Transaction#set_error: Cannot set error. " \ "The given value is not an exception: #{error.inspect}" return end 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
215 216 217 218 219 220 221 222 |
# File 'lib/appsignal/transaction.rb', line 215 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
231 232 233 234 235 236 237 |
# File 'lib/appsignal/transaction.rb', line 231 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
239 240 241 242 |
# File 'lib/appsignal/transaction.rb', line 239 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".
209 210 211 212 213 |
# File 'lib/appsignal/transaction.rb', line 209 def set_namespace(namespace) return unless namespace @namespace = namespace @ext.set_namespace(namespace) end |
#set_queue_start(start) ⇒ Object
224 225 226 227 228 229 |
# File 'lib/appsignal/transaction.rb', line 224 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
244 245 246 247 248 249 250 251 252 |
# File 'lib/appsignal/transaction.rb', line 244 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.
155 156 157 |
# File 'lib/appsignal/transaction.rb', line 155 def ( = {}) @tags.merge!() end |
#start_event ⇒ Object
284 285 286 287 |
# File 'lib/appsignal/transaction.rb', line 284 def start_event return if paused? @ext.start_event(self.class.garbage_collection_profiler.total_time) end |
#store(key) ⇒ Object
134 135 136 |
# File 'lib/appsignal/transaction.rb', line 134 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.
320 321 322 |
# File 'lib/appsignal/transaction.rb', line 320 def to_h JSON.parse(@ext.to_json) end |