# encoding: utf-8 module OneApm module Agent module Threading class AgentThread @backing_thread_class = ::Thread class << self def create(label, &blk) OneApm::Manager.logger.debug("Creating OneApm thread: #{label}") wrapped_blk = Proc.new do begin blk.call rescue => e OneApm::Manager.logger.error("Thread #{label} exited with error", e) rescue Exception => e OneApm::Manager.logger.error("Thread #{label} exited with exception. Re-raising in case of interupt.", e) raise ensure OneApm::Manager.logger.debug("Exiting OneApm thread: #{label}") end end thread = backing_thread_class.new(&wrapped_blk) thread[:oneapm_label] = label thread end def list backing_thread_class.list end def bucket_thread(thread, profile_agent_code) if thread.key?(:oneapm_label) profile_agent_code ? :agent : :ignore else state = TransactionState.tl_state_for(thread) if state.in_background_transaction? :background elsif state.in_web_transaction? :request else :other end end end def scrub_backtrace(thread, profile_agent_code) begin bt = thread.backtrace rescue Exception => e OneApm::Manager.logger.debug("Failed to backtrace #{thread.inspect}: #{e.class.name}: #{e.to_s}") end return nil unless bt bt.reject! { |t| t.include?('one_apm') } unless profile_agent_code bt end def backing_thread_class @backing_thread_class end def backing_thread_class=(clazz) @backing_thread_class = clazz end end end end end end