module NewRelic::Agent::Instrumentation::GRPC::Client

Constants

INSTRUMENTATION_NAME

Public Instance Methods

issue_request_with_tracing(grpc_type, method, requests, marshal, unmarshal, deadline:, return_op:, parent:, credentials:, metadata:) { || ... } click to toggle source
# File lib/new_relic/agent/instrumentation/grpc/client/instrumentation.rb, line 17
def issue_request_with_tracing(grpc_type, method, requests, marshal, unmarshal,
  deadline:, return_op:, parent:, credentials:, metadata:)
  return yield unless trace_with_newrelic?

  NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)

  segment = request_segment(method)
  request_wrapper = NewRelic::Agent::Instrumentation::GRPC::Client::RequestWrapper.new(@host)
  # do not insert CAT headers for gRPC requests https://github.com/newrelic/newrelic-ruby-agent/issues/1730
  segment.add_request_headers(request_wrapper) unless CrossAppTracing.cross_app_enabled?
  metadata.merge!(request_wrapper.instance_variable_get(:@newrelic_metadata))
  grpc_message = nil
  grpc_status = 0

  NewRelic::Agent.disable_all_tracing do
    begin
      yield
    rescue => e
      NewRelic::Agent.notice_error(e)
      grpc_status, grpc_message = grpc_status_and_message_from_exception(e)
      raise
    end
  end
ensure
  add_attributes(segment, grpc_message: grpc_message, grpc_status: grpc_status, grpc_type: grpc_type)
  ::NewRelic::Agent::Transaction::Segment.finish(segment)
end

Private Instance Methods

add_attributes(segment, attributes_hash) click to toggle source
# File lib/new_relic/agent/instrumentation/grpc/client/instrumentation.rb, line 47
def add_attributes(segment, attributes_hash)
  return unless segment

  attributes_hash.each do |attr, value|
    segment.add_agent_attribute(attr, value)
  end
  segment.record_agent_attributes = true
end
grpc_status_and_message_from_exception(exception) click to toggle source
# File lib/new_relic/agent/instrumentation/grpc/client/instrumentation.rb, line 56
def grpc_status_and_message_from_exception(exception)
  return unless exception.message =~ /^(\d+):(\w+)\./

  [Regexp.last_match(1).to_i, Regexp.last_match(2)]
end
interceptor?() click to toggle source
# File lib/new_relic/agent/instrumentation/grpc/client/instrumentation.rb, line 77
def interceptor?
  self.class.name.eql?('GRPC::InterceptorRegistry')
end
method_uri(method) click to toggle source
# File lib/new_relic/agent/instrumentation/grpc/client/instrumentation.rb, line 71
def method_uri(method)
  return unless @host && method

  "grpc://#{@host}/#{method}"
end
request_segment(method) click to toggle source
# File lib/new_relic/agent/instrumentation/grpc/client/instrumentation.rb, line 62
def request_segment(method)
  cleaned = cleaned_method(method)
  NewRelic::Agent::Tracer.start_external_request_segment(
    library: 'gRPC',
    uri: method_uri(cleaned),
    procedure: cleaned
  )
end
trace_with_newrelic?() click to toggle source
# File lib/new_relic/agent/instrumentation/grpc/client/instrumentation.rb, line 81
def trace_with_newrelic?
  return @trace_with_newrelic unless @trace_with_newrelic.nil? # check for nil, not false

  @trace_with_newrelic = if interceptor?
    false
  else
    !host_denylisted?(@host)
  end
end