# encoding: utf-8 module OneApm module Agent module CrossAppTracingMessage class Error < RuntimeError; end OA_ID_MESSAGE_HEADER = 'BlueWareID' OA_TXN_MESSAGE_HEADER = 'BlueWareTransaction' OA_SYNTHETICS_MESSAGE_HEADER = 'BlueWareSynthetics' ############### module_function ############### def request_data(state) rpc_request = {} inject_rpc_request_headers(state, rpc_request) if cross_app_enabled? json_rpc_request = OneApm::JSONWrapper.dump(rpc_request) # OneApm::Manager.logger.debug "Thrift Header Message: #{json_rpc_request}" obfuscator.obfuscate(json_rpc_request) rescue OneApm::Agent::CrossAppTracingMessage::Error => err OneApm::Manager.logger.debug "Not injecting x-process header", err end # TODO: just stub def process_request message OneApm::Manager.logger.debug "Thrift Process Message: #{message}" end def inject_rpc_request_headers state, rpc_request txn_guid = state.request_guid txn = state.current_transaction if txn trip_id = txn.cat_trip_id(state) path_hash = txn.cat_path_hash(state) if txn.raw_synthetics_header rpc_request[OA_SYNTHETICS_MESSAGE_HEADER] = txn.raw_synthetics_header end end rpc_request[OA_ID_MESSAGE_HEADER] = cross_app_id rpc_request[OA_TXN_MESSAGE_HEADER] = [txn_guid, true, trip_id, path_hash, ''] rescue OneApm::Agent::CrossAppTracingMessage::Error => err #TODO OneApm::Manager.logger.debug "Not injecting x-process header", err end def cross_app_id OneApm::Manager.config[:cross_process_id] or raise OneApm::Agent::CrossAppTracingMessage::Error, "no cross app ID configured" end def start_trace(state, t0, rpc_request) state.is_cross_app_caller = true stack = state.traced_method_stack segment = stack.push_frame(state, :rpc_request, t0) return segment rescue => err OneApm::Manager.logger.error "Uncaught exception while tracing RPC request", err return nil rescue Exception => e OneApm::Manager.logger.debug "Unexpected exception raised while tracing RPC request", e raise e end def finish_trace(state, t0, segment, request, metrics) unless t0 OneApm::Manager.logger.error("RPC request trace finished without start time. This is probably an agent bug.") return end t1 = Time.now duration = t1.to_f - t0.to_f begin if request scoped_metric, *other_metrics = metrics OneApm::Manager.agent.stats_engine.record_scoped_and_unscoped_metrics(state, scoped_metric, nil, duration) if segment segment.name = scoped_metric end end ensure # If we have a segment, always pop the traced method stack to avoid # an inconsistent state, which prevents tracing of whole transaction. if segment stack = state.traced_method_stack stack.pop_frame(state, segment, scoped_metric, t1) end end rescue OneApm::Agent::CrossAppTracingMessage::Error => err OneApm::Manager.logger.debug "while cross app tracing", err rescue => err OneApm::Manager.logger.error "Uncaught exception while finishing an RPC request trace", err end # Return +true+ if cross app tracing is enabled in the config. def cross_app_enabled? valid_cross_process_id? && valid_encoding_key? && cross_application_tracer_enabled? end def valid_cross_process_id? OneApm::Manager.config[:cross_process_id] && OneApm::Manager.config[:cross_process_id].length > 0 end def valid_encoding_key? OneApm::Manager.config[:encoding_key] && OneApm::Manager.config[:encoding_key].length > 0 end def cross_application_tracer_enabled? OneApm::Manager.config[:"cross_application_tracer.enabled"] end # Fetcher for the cross app encoding key. Raises a # OneApm::Agent::CrossAppTracingMessage::Error if the key isn't configured. def cross_app_encoding_key OneApm::Manager.config[:encoding_key] or raise OneApm::Agent::CrossAppTracingMessage::Error, "No encoding_key set." end def obfuscator @obfuscator ||= OneApm::Agent::Obfuscator.new(cross_app_encoding_key) end end end end