Class: OneApm::Agent::CrossAppMonitor
Constant Summary
collapse
'X-OneApm-ID'
'X-OneApm-Transaction'
'X-OneApm-App-Data'
'HTTP_X_ONEAPM_ID'.freeze
'HTTP_X_ONEAPM_TRANSACTION'.freeze
'HTTP_CONTENT_LENGTH'.freeze
Instance Attribute Summary
#obfuscator
Instance Method Summary
collapse
-
#build_payload(state, timings, content_length) ⇒ Object
-
#clear_client_cross_app_id(state) ⇒ Object
-
#client_referring_transaction_guid(state) ⇒ Object
-
#client_referring_transaction_path_hash(state) ⇒ Object
-
#client_referring_transaction_record_flag(state) ⇒ Object
-
#client_referring_transaction_trip_id(state) ⇒ Object
-
#content_length_from_request(request) ⇒ Object
-
#cross_app_enabled? ⇒ Boolean
-
#decoded_id(request) ⇒ Object
-
#hash_transaction_name(identifier) ⇒ Object
-
#insert_response_header(state, request_headers, response_headers) ⇒ Object
-
#on_finished_configuring(events) ⇒ Object
-
#path_hash(txn_name, seed) ⇒ Object
-
#register_event_listeners(events) ⇒ Object
Expected sequence of events: :before_call will save our cross application request id to the thread :after_call will write our response headers/metrics and clean up the thread.
-
#save_client_cross_app_id(state, request_headers) ⇒ Object
-
#save_referring_transaction_info(state, request_headers) ⇒ Object
-
#set_error_custom_parameters(state, options) ⇒ Object
-
#set_metrics(id, timings) ⇒ Object
-
#set_response_headers(state, response_headers, timings, content_length) ⇒ Object
-
#set_transaction_custom_parameters(state) ⇒ Object
-
#should_process_request(request_headers) ⇒ Object
-
#trusts?(request) ⇒ Boolean
Expects an ID of format “12#345”, and will only accept that!.
#deserialize_header, #initialize, #setup_obfuscator
Instance Method Details
#build_payload(state, timings, content_length) ⇒ Object
126
127
128
129
130
131
132
133
134
135
136
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 126
def build_payload(state, timings, content_length)
payload = [
OneApm::Manager.config[:cross_process_id],
timings.transaction_name,
timings.queue_time_in_seconds.to_f,
timings.app_time_in_seconds.to_f,
content_length,
state.request_guid
]
payload = obfuscator.obfuscate(OneApm::JSONWrapper.dump(payload))
end
|
#clear_client_cross_app_id(state) ⇒ Object
59
60
61
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 59
def clear_client_cross_app_id(state)
state.client_cross_app_id = nil
end
|
#client_referring_transaction_guid(state) ⇒ Object
69
70
71
72
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 69
def client_referring_transaction_guid(state)
info = state.referring_transaction_info or return nil
return info[0]
end
|
#client_referring_transaction_path_hash(state) ⇒ Object
84
85
86
87
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 84
def client_referring_transaction_path_hash(state)
info = state.referring_transaction_info or return nil
return info[3].is_a?(String) && info[3]
end
|
#client_referring_transaction_record_flag(state) ⇒ Object
74
75
76
77
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 74
def client_referring_transaction_record_flag(state)
info = state.referring_transaction_info or return nil
return info[1]
end
|
#client_referring_transaction_trip_id(state) ⇒ Object
79
80
81
82
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 79
def client_referring_transaction_trip_id(state)
info = state.referring_transaction_info or return nil
return info[2].is_a?(String) && info[2]
end
|
#content_length_from_request(request) ⇒ Object
165
166
167
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 165
def content_length_from_request(request)
request[OA_CONTENT_LENGTH_HEADER_KEY] || -1
end
|
#cross_app_enabled? ⇒ Boolean
#decoded_id(request) ⇒ Object
158
159
160
161
162
163
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 158
def decoded_id(request)
encoded_id = request[ONEAPM_ID_HEADER_KEY]
return "" if encoded_id.nil?
obfuscator.deobfuscate(encoded_id)
end
|
#hash_transaction_name(identifier) ⇒ Object
169
170
171
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 169
def hash_transaction_name(identifier)
Digest::MD5.digest(identifier).unpack("@12N").first & 0xffffffff
end
|
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 89
def (state, , )
unless state.client_cross_app_id.nil?
txn = state.current_transaction
unless txn.nil?
txn.freeze_name_and_execute_if_not_ignored do
timings = state.timings
content_length = content_length_from_request()
(state, , timings, content_length)
set_metrics(state.client_cross_app_id, timings)
end
end
clear_client_cross_app_id(state)
end
end
|
#on_finished_configuring(events) ⇒ Object
21
22
23
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 21
def on_finished_configuring(events)
register_event_listeners(events)
end
|
#path_hash(txn_name, seed) ⇒ Object
173
174
175
176
177
178
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 173
def path_hash(txn_name, seed)
rotated = ((seed << 1) | (seed >> 31)) & 0xffffffff
app_name = OneApm::Manager.config.app_names.first
identifier = "#{app_name};#{txn_name}"
sprintf("%08x", rotated ^ hash_transaction_name(identifier))
end
|
#register_event_listeners(events) ⇒ Object
Expected sequence of events:
:before_call will save our cross application request id to the thread
:after_call will write our response headers/metrics and clean up the thread
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 28
def register_event_listeners(events)
OneApm::Manager.logger.
debug("Wiring up Cross Application Tracing to events after finished configuring")
events.subscribe(:before_call) do |env|
if should_process_request(env)
state = OneApm::TransactionState.tl_get
save_client_cross_app_id(state, env)
save_referring_transaction_info(state, env)
set_transaction_custom_parameters(state)
end
end
events.subscribe(:after_call) do |env, (_status_code, , _body)|
state = OneApm::TransactionState.tl_get
(state, env, )
end
events.subscribe(:notice_error) do |_, options|
state = OneApm::TransactionState.tl_get
set_error_custom_parameters(state, options)
end
end
|
#save_client_cross_app_id(state, request_headers) ⇒ Object
55
56
57
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 55
def save_client_cross_app_id(state, )
state.client_cross_app_id = decoded_id()
end
|
#save_referring_transaction_info(state, request_headers) ⇒ Object
63
64
65
66
67
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 63
def save_referring_transaction_info(state, )
= [ONEAPM_TXN_HEADER_KEY] or return
txn_info = (, ONEAPM_TXN_HEADER)
state.referring_transaction_info = txn_info
end
|
#set_error_custom_parameters(state, options) ⇒ Object
149
150
151
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 149
def set_error_custom_parameters(state, options)
options[:client_cross_process_id] = state.client_cross_app_id if state.client_cross_app_id
end
|
#set_metrics(id, timings) ⇒ Object
153
154
155
156
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 153
def set_metrics(id, timings)
metric_name = "ClientApplication/#{id}/all"
OneApm::Manager.record_metric(metric_name, timings.app_time_in_seconds)
end
|
122
123
124
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 122
def (state, , timings, content_length)
[ONEAPM_APPDATA_HEADER] = build_payload(state, timings, content_length)
end
|
#set_transaction_custom_parameters(state) ⇒ Object
138
139
140
141
142
143
144
145
146
147
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 138
def set_transaction_custom_parameters(state)
OneApm::Manager.add_custom_parameters(:client_cross_process_id => state.client_cross_app_id) if state.client_cross_app_id
referring_guid = client_referring_transaction_guid(state)
if referring_guid
OneApm::Manager.add_custom_parameters(:referring_transaction_guid => referring_guid)
end
end
|
#should_process_request(request_headers) ⇒ Object
105
106
107
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 105
def should_process_request()
return cross_app_enabled? && trusts?()
end
|
#trusts?(request) ⇒ Boolean
Expects an ID of format “12#345”, and will only accept that!
114
115
116
117
118
119
120
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 114
def trusts?(request)
id = decoded_id(request)
split_id = id.match(/(\d+)#\d+/)
return false if split_id.nil?
OneApm::Manager.config[:trusted_account_ids].include?(split_id.captures.first.to_i)
end
|