Class: OneApm::Agent::CrossAppMonitor
Constant Summary
collapse
'X-BlueWare-ID'
'X-BlueWare-Transaction'
'X-BlueWare-App-Data'
'HTTP_X_BLUEWARE_ID'.freeze
'HTTP_X_BLUEWARE_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
127
128
129
130
131
132
133
134
135
136
137
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 127
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
60
61
62
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 60
def clear_client_cross_app_id(state)
state.client_cross_app_id = nil
end
|
#client_referring_transaction_guid(state) ⇒ Object
70
71
72
73
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 70
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
85
86
87
88
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 85
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
75
76
77
78
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 75
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
80
81
82
83
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 80
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
166
167
168
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 166
def content_length_from_request(request)
request[OA_CONTENT_LENGTH_HEADER_KEY] || -1
end
|
#cross_app_enabled? ⇒ Boolean
#decoded_id(request) ⇒ Object
159
160
161
162
163
164
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 159
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
170
171
172
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 170
def hash_transaction_name(identifier)
Digest::MD5.digest(identifier).unpack("@12N").first & 0xffffffff
end
|
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 90
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
22
23
24
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 22
def on_finished_configuring(events)
register_event_listeners(events)
end
|
#path_hash(txn_name, seed) ⇒ Object
174
175
176
177
178
179
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 174
def path_hash(txn_name, seed)
rotated = ((seed << 1) | (seed >> 31)) & 0xffffffff
app_name = OneApm::Manager.config.app_name
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
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
54
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 29
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
56
57
58
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 56
def save_client_cross_app_id(state, )
state.client_cross_app_id = decoded_id()
end
|
#save_referring_transaction_info(state, request_headers) ⇒ Object
64
65
66
67
68
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 64
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
150
151
152
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 150
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
154
155
156
157
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 154
def set_metrics(id, timings)
metric_name = "ClientApplication/#{id}/all"
OneApm::Manager.record_metric(metric_name, timings.app_time_in_seconds)
end
|
123
124
125
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 123
def (state, , timings, content_length)
[ONEAPM_APPDATA_HEADER] = build_payload(state, timings, content_length)
end
|
#set_transaction_custom_parameters(state) ⇒ Object
139
140
141
142
143
144
145
146
147
148
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 139
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
106
107
108
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 106
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!
115
116
117
118
119
120
121
|
# File 'lib/one_apm/agent/cross_app/cross_app_monitor.rb', line 115
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
|