diff --git a/README-zh.md b/README-zh.md index d00650292..36d7c014c 100644 --- a/README-zh.md +++ b/README-zh.md @@ -28,7 +28,7 @@ Java技术交流群:294712648 interceptors) { GrpcChannelProperties channelProperties = properties.getChannel(name); - Channel channel = NettyChannelBuilder.forTarget(name) + NettyChannelBuilder builder = NettyChannelBuilder.forTarget(name) .loadBalancerFactory(loadBalancerFactory) .nameResolverFactory(nameResolverFactory) - .usePlaintext(channelProperties.isPlaintext()) - .enableKeepAlive(channelProperties.isEnableKeepAlive(), channelProperties.getKeepAliveDelay(), TimeUnit.SECONDS, channelProperties.getKeepAliveTimeout(), TimeUnit.SECONDS) - .build(); + .usePlaintext(channelProperties.isPlaintext()); + if (channelProperties.isEnableKeepAlive()) { + builder.keepAliveWithoutCalls(channelProperties.isKeepAliveWithoutCalls()) + .keepAliveTime(channelProperties.getKeepAliveTime(), TimeUnit.SECONDS) + .keepAliveTimeout(channelProperties.getKeepAliveTimeout(), TimeUnit.SECONDS); + } + Channel channel = builder.build(); + List globalInterceptorList = globalClientInterceptorRegistry.getClientInterceptors(); - Set interceptorSet = new HashSet<>(); + Set interceptorSet = Sets.newHashSet(); if (globalInterceptorList != null && !globalInterceptorList.isEmpty()) { interceptorSet.addAll(globalInterceptorList); } diff --git a/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/AddressChannelNameResolver.java b/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/AddressChannelNameResolver.java index e4755c981..f11a97589 100644 --- a/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/AddressChannelNameResolver.java +++ b/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/AddressChannelNameResolver.java @@ -10,9 +10,8 @@ import javax.annotation.concurrent.GuardedBy; import io.grpc.Attributes; +import io.grpc.EquivalentAddressGroup; import io.grpc.NameResolver; -import io.grpc.ResolvedServerInfo; -import io.grpc.ResolvedServerInfoGroup; import io.grpc.Status; import io.grpc.internal.SharedResourceHolder; import lombok.extern.slf4j.Slf4j; @@ -100,16 +99,15 @@ public void run() { return; } - List resolvedServerInfoGroupList = Lists.newArrayList(); + List equivalentAddressGroups = Lists.newArrayList(); for (int i = 0; i < properties.getHost().size(); i++) { String host = properties.getHost().get(i); Integer port = properties.getPort().get(i); log.info("Found gRPC server {} {}:{}", name, host, port); - ResolvedServerInfoGroup.Builder servers = ResolvedServerInfoGroup.builder(); - ResolvedServerInfo resolvedServerInfo = new ResolvedServerInfo(new InetSocketAddress(host, port), Attributes.EMPTY); - resolvedServerInfoGroupList.add(servers.add(resolvedServerInfo).build()); + EquivalentAddressGroup addressGroup = new EquivalentAddressGroup(new InetSocketAddress(host, port), Attributes.EMPTY); + equivalentAddressGroups.add(addressGroup); } - savedListener.onUpdate(resolvedServerInfoGroupList, Attributes.EMPTY); + savedListener.onAddresses(equivalentAddressGroups, Attributes.EMPTY); } finally { synchronized (AddressChannelNameResolver.this) { resolving = false; diff --git a/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/DiscoveryClientChannelFactory.java b/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/DiscoveryClientChannelFactory.java index ed1c9a49b..fc7bcf464 100644 --- a/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/DiscoveryClientChannelFactory.java +++ b/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/DiscoveryClientChannelFactory.java @@ -1,10 +1,10 @@ package net.devh.springboot.autoconfigure.grpc.client; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import org.springframework.cloud.client.discovery.DiscoveryClient; -import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -42,14 +42,19 @@ public Channel createChannel(String name) { @Override public Channel createChannel(String name, List interceptors) { GrpcChannelProperties channelProperties = properties.getChannel(name); - Channel channel = NettyChannelBuilder.forTarget(name) + NettyChannelBuilder builder = NettyChannelBuilder.forTarget(name) .loadBalancerFactory(loadBalancerFactory) .nameResolverFactory(new DiscoveryClientResolverFactory(client)) - .usePlaintext(properties.getChannel(name).isPlaintext()) - .enableKeepAlive(channelProperties.isEnableKeepAlive(), channelProperties.getKeepAliveDelay(), TimeUnit.SECONDS, channelProperties.getKeepAliveTimeout(), TimeUnit.SECONDS) - .build(); + .usePlaintext(properties.getChannel(name).isPlaintext()); + if (channelProperties.isEnableKeepAlive()) { + builder.keepAliveWithoutCalls(channelProperties.isKeepAliveWithoutCalls()) + .keepAliveTime(channelProperties.getKeepAliveTime(), TimeUnit.SECONDS) + .keepAliveTimeout(channelProperties.getKeepAliveTimeout(), TimeUnit.SECONDS); + } + Channel channel = builder.build(); + List globalInterceptorList = globalClientInterceptorRegistry.getClientInterceptors(); - Set interceptorSet = new HashSet<>(); + Set interceptorSet = Sets.newHashSet(); if (globalInterceptorList != null && !globalInterceptorList.isEmpty()) { interceptorSet.addAll(globalInterceptorList); } diff --git a/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/DiscoveryClientNameResolver.java b/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/DiscoveryClientNameResolver.java index 0ab7a16fa..5f43c1dc9 100644 --- a/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/DiscoveryClientNameResolver.java +++ b/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/DiscoveryClientNameResolver.java @@ -18,9 +18,8 @@ import javax.annotation.concurrent.GuardedBy; import io.grpc.Attributes; +import io.grpc.EquivalentAddressGroup; import io.grpc.NameResolver; -import io.grpc.ResolvedServerInfo; -import io.grpc.ResolvedServerInfoGroup; import io.grpc.Status; import io.grpc.internal.LogExceptionRunnable; import io.grpc.internal.SharedResourceHolder; @@ -116,20 +115,19 @@ public void run() { } else { return; } - List resolvedServerInfoGroupList = Lists.newArrayList(); + List equivalentAddressGroups = Lists.newArrayList(); for (ServiceInstance serviceInstance : serviceInstanceList) { - ResolvedServerInfoGroup.Builder servers = ResolvedServerInfoGroup.builder(); Map metadata = serviceInstance.getMetadata(); if (metadata.get("gRPC") != null) { Integer port = Integer.valueOf(metadata.get("gRPC")); log.info("Found gRPC server {} {}:{}", name, serviceInstance.getHost(), port); - ResolvedServerInfo resolvedServerInfo = new ResolvedServerInfo(new InetSocketAddress(serviceInstance.getHost(), port), Attributes.EMPTY); - resolvedServerInfoGroupList.add(servers.add(resolvedServerInfo).build()); + EquivalentAddressGroup addressGroup = new EquivalentAddressGroup(new InetSocketAddress(serviceInstance.getHost(), port), Attributes.EMPTY); + equivalentAddressGroups.add(addressGroup); } else { log.error("Can not found gRPC server {}", name); } } - savedListener.onUpdate(resolvedServerInfoGroupList, Attributes.EMPTY); + savedListener.onAddresses(equivalentAddressGroups, Attributes.EMPTY); } else { savedListener.onError(Status.UNAVAILABLE.withCause(new RuntimeException("UNAVAILABLE: NameResolver returned an empty list"))); } diff --git a/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/GlobalClientInterceptorRegistry.java b/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/GlobalClientInterceptorRegistry.java index 2d1ed8a08..93ac5fa55 100644 --- a/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/GlobalClientInterceptorRegistry.java +++ b/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/GlobalClientInterceptorRegistry.java @@ -1,10 +1,11 @@ package net.devh.springboot.autoconfigure.grpc.client; +import com.google.common.collect.Lists; + import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; -import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -21,7 +22,7 @@ @Getter public class GlobalClientInterceptorRegistry implements ApplicationContextAware { - private final List clientInterceptors = new ArrayList<>(); + private final List clientInterceptors = Lists.newArrayList(); private ApplicationContext applicationContext; @PostConstruct diff --git a/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/GrpcChannelProperties.java b/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/GrpcChannelProperties.java index 3b8464d81..9abbd6bd2 100644 --- a/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/GrpcChannelProperties.java +++ b/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/GrpcChannelProperties.java @@ -35,15 +35,27 @@ public class GrpcChannelProperties { private boolean plaintext = true; + /** + * Setting to enable keepalive. + * Default to {@code false} + */ private boolean enableKeepAlive = false; + /** + * Sets whether keepalive will be performed when there are no outstanding RPC on a connection. + * Defaults to {@code false}. + */ + private boolean keepAliveWithoutCalls = false; + /** * The default delay in seconds before we send a keepalive. + * Defaults to {@code 180} */ - private long keepAliveDelay = 60; + private long keepAliveTime = 180; /** * The default timeout in seconds for a keepalive ping request. + * Defaults to {@code 20} */ - private long keepAliveTimeout = 120; + private long keepAliveTimeout = 20; } diff --git a/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/GrpcChannelsProperties.java b/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/GrpcChannelsProperties.java index d9fc4c3c9..ab0a0f8fd 100644 --- a/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/GrpcChannelsProperties.java +++ b/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/GrpcChannelsProperties.java @@ -1,9 +1,10 @@ package net.devh.springboot.autoconfigure.grpc.client; +import com.google.common.collect.Maps; + import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.NestedConfigurationProperty; -import java.util.HashMap; import java.util.Map; import lombok.Data; @@ -18,7 +19,7 @@ public class GrpcChannelsProperties { @NestedConfigurationProperty - private Map client = new HashMap<>(); + private Map client = Maps.newHashMap(); public GrpcChannelProperties getChannel(String name) { GrpcChannelProperties grpcChannelProperties = client.get(name); diff --git a/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/GrpcClientBeanPostProcessor.java b/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/GrpcClientBeanPostProcessor.java index c3279c69c..3e491bd07 100644 --- a/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/GrpcClientBeanPostProcessor.java +++ b/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/GrpcClientBeanPostProcessor.java @@ -1,6 +1,7 @@ package net.devh.springboot.autoconfigure.grpc.client; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import org.springframework.aop.framework.Advised; import org.springframework.aop.support.AopUtils; @@ -13,7 +14,6 @@ import java.lang.reflect.Field; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -28,7 +28,7 @@ */ public class GrpcClientBeanPostProcessor implements org.springframework.beans.factory.config.BeanPostProcessor { - private Map> beansToProcess = new HashMap<>(); + private Map> beansToProcess = Maps.newHashMap(); @Autowired private DefaultListableBeanFactory beanFactory; @@ -73,7 +73,7 @@ public Object postProcessAfterInitialization(Object bean, String beanName) throw } else { try { clientInterceptor = clientInterceptorClass.newInstance(); - } catch (InstantiationException | IllegalAccessException e) { + } catch (Exception e) { throw new BeanCreationException("Failed to create interceptor instance", e); } } diff --git a/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/MetadataInjector.java b/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/MetadataInjector.java index 438e2d2ad..d248f41fa 100644 --- a/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/MetadataInjector.java +++ b/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/MetadataInjector.java @@ -3,6 +3,8 @@ import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.SpanInjector; +import java.util.Map; + import io.grpc.Metadata; /** @@ -12,6 +14,8 @@ */ class MetadataInjector implements SpanInjector { + private static final String HEADER_DELIMITER = "-"; + @Override public void inject(Span span, Metadata carrier) { setIdMetadata(carrier, Span.TRACE_ID_NAME, span.getTraceId()); @@ -23,6 +27,17 @@ public void inject(Span span, Metadata carrier) { if (parentId != null) { setIdMetadata(carrier, Span.PARENT_ID_NAME, parentId); } + for (Map.Entry entry : span.baggageItems()) { + setMetadata(carrier, prefixedKey(entry.getKey()), entry.getValue()); + } + } + + + private String prefixedKey(String key) { + if (key.startsWith(Span.SPAN_BAGGAGE_HEADER_PREFIX + HEADER_DELIMITER)) { + return key; + } + return Span.SPAN_BAGGAGE_HEADER_PREFIX + HEADER_DELIMITER + key; } private void setMetadata(Metadata metadata, String name, String value) { diff --git a/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/TraceClientInterceptor.java b/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/TraceClientInterceptor.java index 4a24f13fd..5c868140e 100644 --- a/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/TraceClientInterceptor.java +++ b/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/client/TraceClientInterceptor.java @@ -42,8 +42,15 @@ protected void checkedStart(ClientCall.Listener responseListener, Metadat spanInjector.inject(span, headers); Listener tracingResponseListener = new ForwardingClientCallListener .SimpleForwardingClientCallListener(responseListener) { + @Override + public void onReady() { + span.logEvent(Span.CLIENT_SEND); + super.onReady(); + } + @Override public void onClose(Status status, Metadata trailers) { + span.logEvent(Span.CLIENT_RECV); if (status.getCode().value() == 0) { log.debug("Call finish success"); } else { diff --git a/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/server/AnnotationGrpcServiceDiscoverer.java b/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/server/AnnotationGrpcServiceDiscoverer.java index b187c59cf..113791ed5 100644 --- a/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/server/AnnotationGrpcServiceDiscoverer.java +++ b/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/server/AnnotationGrpcServiceDiscoverer.java @@ -1,16 +1,15 @@ package net.devh.springboot.autoconfigure.grpc.server; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanCreationException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.HashSet; import java.util.List; import java.util.Set; @@ -44,7 +43,7 @@ public Collection findGrpcServiceBeanNames() { @Override public Collection findGrpcServices() { Collection beanNames = findGrpcServiceBeanNames(); - List definitions = new ArrayList<>(beanNames.size()); + List definitions = Lists.newArrayListWithCapacity(beanNames.size()); GlobalServerInterceptorRegistry globalServerInterceptorRegistry = applicationContext.getBean(GlobalServerInterceptorRegistry.class); List globalInterceptorList = globalServerInterceptorRegistry.getServerInterceptors(); for (String beanName : beanNames) { @@ -59,7 +58,7 @@ public Collection findGrpcServices() { } private ServerServiceDefinition bindInterceptors(ServerServiceDefinition serviceDefinition, GrpcService grpcServiceAnnotation, List globalInterceptorList) { - Set interceptorSet = new HashSet<>(); + Set interceptorSet = Sets.newHashSet(); interceptorSet.addAll(globalInterceptorList); for (Class serverInterceptorClass : grpcServiceAnnotation.interceptors()) { ServerInterceptor serverInterceptor; @@ -68,7 +67,7 @@ private ServerServiceDefinition bindInterceptors(ServerServiceDefinition service } else { try { serverInterceptor = serverInterceptorClass.newInstance(); - } catch (InstantiationException | IllegalAccessException e) { + } catch (Exception e) { throw new BeanCreationException("Failed to create interceptor instance", e); } } diff --git a/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/server/GlobalServerInterceptorRegistry.java b/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/server/GlobalServerInterceptorRegistry.java index 39fbe29a8..0aa07b29b 100644 --- a/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/server/GlobalServerInterceptorRegistry.java +++ b/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/server/GlobalServerInterceptorRegistry.java @@ -1,10 +1,11 @@ package net.devh.springboot.autoconfigure.grpc.server; +import com.google.common.collect.Lists; + import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; -import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -16,7 +17,7 @@ @Getter public class GlobalServerInterceptorRegistry implements ApplicationContextAware { - private final List serverInterceptors = new ArrayList<>(); + private final List serverInterceptors = Lists.newArrayList(); private ApplicationContext applicationContext; @PostConstruct diff --git a/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/server/MetadataExtractor.java b/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/server/MetadataExtractor.java index 8e48a68d8..8ad0a2fdf 100644 --- a/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/server/MetadataExtractor.java +++ b/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/server/MetadataExtractor.java @@ -17,6 +17,8 @@ public class MetadataExtractor implements SpanExtractor { private static final String GRPC_COMPONENT = "gRPC"; + private static final String HEADER_DELIMITER = "-"; + @Override public Span joinTrace(Metadata carrier) { if (getMetadata(carrier, Span.TRACE_ID_NAME) == null) { @@ -44,6 +46,10 @@ private long spanId(Metadata carrier, long traceId) { } } + private String unprefixedKey(String key) { + return key.substring(key.indexOf(HEADER_DELIMITER) + 1); + } + private Span buildParentSpan(Metadata carrier, boolean skip, long traceId, long spanId) { Span.SpanBuilder span = Span.builder().traceId(traceId).spanId(spanId); String processId = getMetadata(carrier, Span.PROCESS_ID_NAME); @@ -63,6 +69,11 @@ private Span buildParentSpan(Metadata carrier, boolean skip, long traceId, long if (skip) { span.exportable(false); } + for (String key : carrier.keys()) { + if (key.startsWith(Span.SPAN_BAGGAGE_HEADER_PREFIX + HEADER_DELIMITER)) { + span.baggage(unprefixedKey(key), carrier.get(Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER))); + } + } return span.build(); } } diff --git a/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/server/NettyGrpcServerFactory.java b/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/server/NettyGrpcServerFactory.java index 5a18a9302..ccb4e4e1d 100644 --- a/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/server/NettyGrpcServerFactory.java +++ b/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/server/NettyGrpcServerFactory.java @@ -1,15 +1,16 @@ package net.devh.springboot.autoconfigure.grpc.server; +import com.google.common.collect.Lists; import com.google.common.net.InetAddresses; -import io.grpc.Server; -import io.grpc.netty.NettyServerBuilder; -import lombok.extern.slf4j.Slf4j; import java.io.File; import java.net.InetSocketAddress; -import java.util.LinkedList; import java.util.List; +import io.grpc.Server; +import io.grpc.netty.NettyServerBuilder; +import lombok.extern.slf4j.Slf4j; + /** * User: Michael * Email: yidongnan@gmail.com @@ -19,7 +20,7 @@ public class NettyGrpcServerFactory implements GrpcServerFactory { private final GrpcServerProperties properties; - private final List services = new LinkedList<>(); + private final List services = Lists.newLinkedList(); public NettyGrpcServerFactory(GrpcServerProperties properties) { this.properties = properties; diff --git a/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/server/TraceServerInterceptor.java b/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/server/TraceServerInterceptor.java index caed82923..b9f31c91c 100644 --- a/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/server/TraceServerInterceptor.java +++ b/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/springboot/autoconfigure/grpc/server/TraceServerInterceptor.java @@ -3,12 +3,14 @@ import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.SpanExtractor; import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.util.ExceptionUtils; -import io.grpc.ForwardingServerCallListener; +import io.grpc.ForwardingServerCall; import io.grpc.Metadata; import io.grpc.ServerCall; import io.grpc.ServerCallHandler; import io.grpc.ServerInterceptor; +import io.grpc.Status; import lombok.extern.slf4j.Slf4j; /** @@ -20,28 +22,43 @@ public class TraceServerInterceptor implements ServerInterceptor { private Tracer tracer; + private SpanExtractor spanExtractor; + private static final String GRPC_COMPONENT = "gRPC"; public TraceServerInterceptor(Tracer tracer, SpanExtractor spanExtractor) { this.tracer = tracer; this.spanExtractor = spanExtractor; } - @SuppressWarnings("unchecked") @Override - public ServerCall.Listener interceptCall(ServerCall call, Metadata headers, ServerCallHandler next) { - Span span = spanExtractor.joinTrace(headers); - this.tracer.continueSpan(span); + public ServerCall.Listener interceptCall(final ServerCall call, Metadata headers, ServerCallHandler next) { + final Span span = spanExtractor.joinTrace(headers); + tracer.continueSpan(span); + return next.startCall(new ForwardingServerCall.SimpleForwardingServerCall(call) { + + private Span gRPCSpan; - final Span grpcSpan = this.tracer.createSpan("gRPC:" + call.getMethodDescriptor().getFullMethodName()); - final ServerCall.Listener original = next.startCall(call, headers); - return new ForwardingServerCallListener.SimpleForwardingServerCallListener(original) { + @Override + public void request(int numMessages) { + gRPCSpan = tracer.createSpan("gRPC:" + call.getMethodDescriptor().getFullMethodName()); + gRPCSpan.logEvent(Span.SERVER_RECV); + gRPCSpan.tag(Span.SPAN_LOCAL_COMPONENT_TAG_NAME, GRPC_COMPONENT); + super.request(numMessages); + } + @SuppressWarnings("ConstantConditions") @Override - public void onComplete() { - tracer.close(grpcSpan); - super.onComplete(); + public void close(Status status, Metadata trailers) { + gRPCSpan.logEvent(Span.SERVER_SEND); + Status.Code statusCode = status.getCode(); + tracer.addTag("gRPC statue code", String.valueOf(statusCode.value())); + if (!status.isOk()) { + tracer.addTag(Span.SPAN_ERROR_TAG_NAME, ExceptionUtils.getExceptionMessage(status.getCause())); + } + tracer.close(gRPCSpan); + super.close(status, trailers); } - }; + }, headers); } } diff --git a/settings.gradle b/settings.gradle index c8a99cb1b..1468b6ed3 100644 --- a/settings.gradle +++ b/settings.gradle @@ -11,4 +11,5 @@ include "examples:local-grpc-client" include "examples:local-grpc-server" include "examples:cloud-eureka-server" include "examples:cloud-grpc-client" -include "examples:cloud-grpc-server" \ No newline at end of file +include "examples:cloud-grpc-server" +include "examples:cloud-zipkin-server" \ No newline at end of file