class GrpcOpencensusInterceptor::ServerInterceptor

Public Class Methods

new(exporter: nil, span_modifier: nil) click to toggle source

@param [#export] exporter The exported used to export captured spans

at the end of the request. Optional: If omitted, uses the exporter
in the current config.

@param [SpanModifier, call] span_modifier Modify span if necessary. It takes span, request, call, method as its parameters.

# File lib/grpc_opencensus_interceptor/server_interceptor.rb, line 12
def initialize(exporter: nil, span_modifier: nil)
  @exporter      = exporter || OpenCensus::Trace.config.exporter
  @span_modifier = span_modifier
  @deserializer  = OpenCensus::Trace::Formatters::Binary.new
end

Public Instance Methods

request_response(request:, call:, method:) { || ... } click to toggle source

Intercept a unary request response call.

@param [Object] request @param [GRPC::ActiveCall::SingleReqView] call @param [Method] method

# File lib/grpc_opencensus_interceptor/server_interceptor.rb, line 25
def request_response(request:, call:, method:)
  context_bin = call.metadata[Util::OPENCENSUS_TRACE_BIN_KEY]
  if context_bin
    context = deserialize(context_bin)
  else
    context = nil
  end

  OpenCensus::Trace.start_request_trace(
    trace_context:          context,
    same_process_as_parent: false) do |span_context|
    begin
      OpenCensus::Trace.in_span get_name(method) do |span|
        modify_span(span, request, call, method)

        start_request(span, call, method)
        begin
          grpc_ex = GRPC::Ok.new
          yield
        rescue StandardError => e
          grpc_ex = Util.to_grpc_ex(e)
          raise e
        ensure
          finish_request(span, grpc_ex)
        end
      end
    ensure
      @exporter.export span_context.build_contained_spans
    end
  end
end

Private Instance Methods

camelize(term) click to toggle source

@param [String] term @return [String]

# File lib/grpc_opencensus_interceptor/server_interceptor.rb, line 85
def camelize(term)
  term.split("_").map(&:capitalize).join
end
deserialize(context_bin) click to toggle source

@param [String] context_bin OpenCensus span context in binary format @return [OpenCensus::Trace::TraceContextData, nil]

# File lib/grpc_opencensus_interceptor/server_interceptor.rb, line 63
def deserialize(context_bin)
  @deserializer.deserialize(context_bin)
end
finish_request(span, exception) click to toggle source

@param [OpenCensus::Trace::SpanBuilder] span @param [GRPC::BadStatus] exception

# File lib/grpc_opencensus_interceptor/server_interceptor.rb, line 114
def finish_request(span, exception)
  # Set gRPC server status
  # https://github.com/census-instrumentation/opencensus-specs/blob/master/trace/gRPC.md#spans
  span.set_status exception.code
  span.put_attribute "http.status_code", Util.to_http_status(exception)
end
get_name(method) click to toggle source

Span name is represented as $package.$service/$method cf. github.com/census-instrumentation/opencensus-specs/blob/master/trace/gRPC.md#spans

@param [Method] method @return [String]

# File lib/grpc_opencensus_interceptor/server_interceptor.rb, line 73
def get_name(method)
  "#{method.receiver.class.service_name}/#{camelize(method.name.to_s)}"
end
get_path(method) click to toggle source

@param [Method] method @return [String]

# File lib/grpc_opencensus_interceptor/server_interceptor.rb, line 79
def get_path(method)
  "/" + get_name(method)
end
modify_span(span, request, call, method) click to toggle source

Modify span by custom span modifier

@param [OpenCensus::Trace::SpanBuilder] span @param [Object] request @param [GRPC::ActiveCall::SingleReqView] call @param [Method] method

# File lib/grpc_opencensus_interceptor/server_interceptor.rb, line 96
def modify_span(span, request, call, method)
  @span_modifier.call(span, request, call, method) if @span_modifier
end
start_request(span, call, method) click to toggle source

@param [OpenCensus::Trace::SpanBuilder] span @param [GRPC::ActiveCall::SingleReqView] call @param [Method] method

# File lib/grpc_opencensus_interceptor/server_interceptor.rb, line 103
def start_request(span, call, method)
  span.kind = OpenCensus::Trace::SpanBuilder::SERVER
  span.put_attribute "http.path", get_path(method)
  span.put_attribute "http.method", "POST"  # gRPC always uses "POST"
  if call.metadata['user-agent']
    span.put_attribute "http.user_agent", call.metadata['user-agent']
  end
end