Class: Appsignal::Transaction
Defined Under Namespace
Classes: GenericRequest, NilTransaction
Constant Summary
collapse
- HTTP_REQUEST =
'http_request'.freeze
- BACKGROUND_JOB =
'background_job'.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
HTTP_X_AUTH_TOKEN)
- JSON_EXCEPTIONS =
[
IOError,
NotImplementedError,
JSON::GeneratorError,
Encoding::UndefinedConversionError
].freeze
Instance Attribute Summary collapse
Class Method Summary
collapse
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) ⇒ Object
-
#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_queue_start(start) ⇒ Object
-
#set_sample_data(key, data) ⇒ Object
-
#set_tags(given_tags = {}) ⇒ Object
-
#start_event ⇒ Object
-
#store(key) ⇒ Object
Constructor Details
#initialize(transaction_id, namespace, request, options = {}) ⇒ Transaction
Returns a new instance of Transaction.
64
65
66
67
68
69
70
71
72
73
74
75
76
|
# File 'lib/appsignal/transaction.rb', line 64
def initialize(transaction_id, namespace, request, options={})
@transaction_id = transaction_id
@namespace = namespace
@request = request
@paused = false
@discarded = false
@tags = {}
@store = Hash.new({})
@options = options
@options[:params_method] ||= :params
@ext = Appsignal::Extension.start_transaction(@transaction_id, @namespace)
end
|
Instance Attribute Details
#discarded ⇒ Object
Returns the value of attribute discarded.
62
63
64
|
# File 'lib/appsignal/transaction.rb', line 62
def discarded
@discarded
end
|
Returns the value of attribute ext.
62
63
64
|
# File 'lib/appsignal/transaction.rb', line 62
def ext
@ext
end
|
#namespace ⇒ Object
Returns the value of attribute namespace.
62
63
64
|
# File 'lib/appsignal/transaction.rb', line 62
def namespace
@namespace
end
|
Returns the value of attribute options.
62
63
64
|
# File 'lib/appsignal/transaction.rb', line 62
def options
@options
end
|
Returns the value of attribute paused.
62
63
64
|
# File 'lib/appsignal/transaction.rb', line 62
def paused
@paused
end
|
Returns the value of attribute request.
62
63
64
|
# File 'lib/appsignal/transaction.rb', line 62
def request
@request
end
|
Returns the value of attribute tags.
62
63
64
|
# File 'lib/appsignal/transaction.rb', line 62
def tags
@tags
end
|
#transaction_id ⇒ Object
Returns the value of attribute transaction_id.
62
63
64
|
# File 'lib/appsignal/transaction.rb', line 62
def transaction_id
@transaction_id
end
|
Class Method Details
.complete_current! ⇒ Object
53
54
55
56
57
58
59
|
# File 'lib/appsignal/transaction.rb', line 53
def complete_current!
current.complete
rescue => e
Appsignal.logger.error("Failed to complete transaction ##{current.transaction_id}. #{e.message}")
ensure
Thread.current[:appsignal_transaction] = nil
end
|
.create(id, namespace, request, options = {}) ⇒ Object
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
# File 'lib/appsignal/transaction.rb', line 30
def create(id, namespace, request, options={})
if options.include?(:force) && options[:force]
Thread.current[:appsignal_transaction] = nil
end
if Thread.current[:appsignal_transaction] != nil
Appsignal.logger.debug("Trying to start new transaction #{id} but #{current.transaction_id} is already running. Using #{current.transaction_id}")
current
else
Thread.current[:appsignal_transaction] = Appsignal::Transaction.new(id, namespace, request, options)
end
end
|
49
50
51
|
# File 'lib/appsignal/transaction.rb', line 49
def current
Thread.current[:appsignal_transaction] || NilTransaction.new
end
|
Instance Method Details
82
83
84
85
86
87
88
89
90
91
|
# File 'lib/appsignal/transaction.rb', line 82
def complete
if discarded?
Appsignal.logger.debug('Skipping transaction because it was manually discarded.'.freeze)
return
end
if @ext.finish
sample_data
end
@ext.complete
end
|
105
106
107
|
# File 'lib/appsignal/transaction.rb', line 105
def discard!
@discarded = true
end
|
#discarded? ⇒ Boolean
113
114
115
|
# File 'lib/appsignal/transaction.rb', line 113
def discarded?
@discarded == true
end
|
#finish_event(name, title, body, body_format = Appsignal::EventFormatter::DEFAULT) ⇒ Object
201
202
203
204
205
206
207
208
|
# File 'lib/appsignal/transaction.rb', line 201
def finish_event(name, title, body, body_format=Appsignal::EventFormatter::DEFAULT)
@ext.finish_event(
name,
title || BLANK,
body || BLANK,
body_format || Appsignal::EventFormatter::DEFAULT
)
end
|
#instrument(name, title = nil, body = nil, body_format = Appsignal::EventFormatter::DEFAULT) ⇒ Object
220
221
222
223
224
225
|
# File 'lib/appsignal/transaction.rb', line 220
def instrument(name, title=nil, body=nil, body_format=Appsignal::EventFormatter::DEFAULT)
start_event
r = yield
finish_event(name, title, body, body_format)
r
end
|
#nil_transaction? ⇒ Boolean
78
79
80
|
# File 'lib/appsignal/transaction.rb', line 78
def nil_transaction?
false
end
|
93
94
95
|
# File 'lib/appsignal/transaction.rb', line 93
def pause!
@paused = true
end
|
#paused? ⇒ Boolean
101
102
103
|
# File 'lib/appsignal/transaction.rb', line 101
def paused?
@paused == true
end
|
#record_event(name, title, body, duration, body_format = Appsignal::EventFormatter::DEFAULT) ⇒ Object
210
211
212
213
214
215
216
217
218
|
# File 'lib/appsignal/transaction.rb', line 210
def record_event(name, title, body, duration, body_format=Appsignal::EventFormatter::DEFAULT)
@ext.record_event(
name,
title || BLANK,
body || BLANK,
duration,
body_format || Appsignal::EventFormatter::DEFAULT
)
end
|
109
110
111
|
# File 'lib/appsignal/transaction.rb', line 109
def restore!
@discarded = false
end
|
97
98
99
|
# File 'lib/appsignal/transaction.rb', line 97
def resume!
@paused = false
end
|
#sample_data ⇒ Object
169
170
171
172
173
174
175
176
177
178
179
|
# File 'lib/appsignal/transaction.rb', line 169
def sample_data
{
:params => sanitized_params,
:environment => sanitized_environment,
:session_data => sanitized_session_data,
:metadata => metadata,
:tags => sanitized_tags
}.each do |key, data|
set_sample_data(key, data)
end
end
|
#set_action(action) ⇒ Object
125
126
127
128
|
# File 'lib/appsignal/transaction.rb', line 125
def set_action(action)
return unless action
@ext.set_action(action)
end
|
#set_error(error) ⇒ Object
Also known as:
add_exception
181
182
183
184
185
186
187
188
189
190
191
192
193
194
|
# File 'lib/appsignal/transaction.rb', line 181
def set_error(error)
return unless error
return unless Appsignal.active?
return if Appsignal.is_ignored_error?(error)
backtrace = cleaned_backtrace(error.backtrace)
@ext.set_error(
error.class.name,
error.message.to_s,
backtrace ? Appsignal::Utils.json_generate(backtrace) : ''
)
rescue *JSON_EXCEPTIONS => e
Appsignal.logger.error("Error generating JSON (#{e.class}: #{e.message}) for '#{backtrace.inspect}'")
end
|
#set_http_or_background_action(from = request.params) ⇒ Object
130
131
132
133
134
135
136
137
|
# File 'lib/appsignal/transaction.rb', line 130
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
146
147
148
149
150
151
152
|
# File 'lib/appsignal/transaction.rb', line 146
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
|
154
155
156
157
|
# File 'lib/appsignal/transaction.rb', line 154
def set_metadata(key, value)
return unless key && value
@ext.set_metadata(key, value)
end
|
#set_queue_start(start) ⇒ Object
139
140
141
142
143
144
|
# File 'lib/appsignal/transaction.rb', line 139
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
159
160
161
162
163
164
165
166
167
|
# File 'lib/appsignal/transaction.rb', line 159
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.json_generate(data)
)
rescue *JSON_EXCEPTIONS => e
Appsignal.logger.error("Error generating JSON (#{e.class}: #{e.message}) for '#{data.inspect}'")
end
|
121
122
123
|
# File 'lib/appsignal/transaction.rb', line 121
def set_tags(given_tags={})
@tags.merge!(given_tags)
end
|
#start_event ⇒ Object
197
198
199
|
# File 'lib/appsignal/transaction.rb', line 197
def start_event
@ext.start_event
end
|
#store(key) ⇒ Object
117
118
119
|
# File 'lib/appsignal/transaction.rb', line 117
def store(key)
@store[key]
end
|