grpc-ecosystem / grpc-spring

Spring Boot starter module for gRPC framework.
https://grpc-ecosystem.github.io/grpc-spring/
Apache License 2.0
3.48k stars 812 forks source link

CallOptions.withStreamTracerFactory api #954

Closed 313hemant313 closed 9 months ago

313hemant313 commented 1 year ago

Wanted to use below grpc-java api's to trace network issues / retry logging.

CallOptions.withStreamTracerFactory(ClientStreamTracer.Factory factory)
ClientStreamTracer.inboundTrailers(Metadata trailers)
StreamTracer.streamClosed(Status status)

How i can use these with spring grpc ?

313hemant313 commented 1 year ago

@ST-DDT please guide.

ST-DDT commented 1 year ago

The same way as in plain grpc java. Although you could use a configurer bean to set the options globally.

Please don't ping me if you posted the issues just a few hours ago.

313hemant313 commented 1 year ago

@ST-DDT Sorry accidentally tagged you here... wanted to tag on https://github.com/yidongnan/grpc-spring-boot-starter/issues/951

Thanks for your reply.

313hemant313 commented 1 year ago

@ST-DDT please help

Not able to find withStreamTracerFactory in both the options GrpcChannelConfigurer or StubTransformer.

Tried this but not sure if this will replace any existing ClientStreamTracker or not.

@Bean
public StubTransformer customStubTransformer() {
    return (name, stub) -> stub.withOption(CallOptions.Key.create("streamTracerFactories"), List.of(new ClientStreamTracer.Factory() {
        @Override
        public ClientStreamTracer newClientStreamTracer(ClientStreamTracer.StreamInfo info, Metadata headers) {
            return new CustomClientStreamTracer(info);
        }
    }));
}
313hemant313 commented 12 months ago

@ST-DDT Grpc-java suggested to use newStub(channel, callOptions) https://github.com/grpc/grpc-java/issues/2143,

How to go about it in grpc-spring-boot-starter ?

ST-DDT commented 12 months ago

Grpc-java suggested to use newStub(channel, callOptions) grpc/grpc-java#2143,

You can replace the stub with a stub transformer or provide a custom stub factory.

But it was also mentioned that you could use an interceptor to set it. Which I would recommend.

313hemant313 commented 12 months ago

Not sure how to attach Tracer with interceptor.

This is how we create stub. AbstractStub<S> modifiedStub = stub.withInterceptors(MetadataUtils.newAttachHeadersInterceptor(metadata));

This is the client tracer that i need to attach.

public class CustomClientStreamTracer extends ClientStreamTracer {

    private final ClientStreamTracer.StreamInfo streamInfo;

    public CustomClientStreamTracer(ClientStreamTracer.StreamInfo streamInfo) {
        this.streamInfo = streamInfo;
    }

    @Override
    public void streamClosed(Status status) {
        if (status != Status.OK) {
            log.warn("For gRPC streamClosed with status: {}, isTransparentRetry: {} and previousAttempts: {}", status,
                    streamInfo.isTransparentRetry(), streamInfo.getPreviousAttempts());
        }
        super.streamClosed(status);
    }
}

@ST-DDT please guide.

ST-DDT commented 12 months ago

Somewhat like this:

@GrpcGlobalClientInterceptor
class MyInterceptor implements ClientInterceptor {

    @Override
    public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
      return next.newCall(method, callOptions.withStreamTracerFactory(tracerFactory));
  }

}