Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add example for sleuth and zipkin integration #264 #568

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions examples/cloud-sleuth-zipkin-grpc-client/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
plugins {
id 'org.springframework.boot'
}

def discoveryProvider = project.findProperty('discovery') ?: 'consul';

dependencies {
switch (discoveryProvider) {
case "nacos": {
implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery'
break;
}
case "consul": {
implementation 'org.springframework.cloud:spring-cloud-starter-consul-discovery'
break;
}
case "eureka": {
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
break;
}
case "zookeeper": {
implementation 'org.springframework.cloud:spring-cloud-starter-zookeeper-discovery'
break;
}
}

implementation project(':grpc-client-spring-boot-starter') // Replace with actual dependency "net.devh:grpc-client-spring-boot-starter:${springBootGrpcVersion}"
implementation project(':examples:grpc-lib') // Replace with your grpc interface spec

// For demonstration only
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'

// zipkin and sleuth
implementation "org.springframework.cloud:spring-cloud-starter-zipkin:2.2.7.RELEASE"
implementation "org.springframework.cloud:spring-cloud-starter-sleuth"
implementation "io.zipkin.brave:brave-instrumentation-grpc:5.13.2"
}

bootRun {
args = ["--spring.profiles.active=" + discoveryProvider]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2016-2021 Michael Zhang <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

package net.devh.boot.grpc.examples.cloud.client;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
* Example grpc client application using cloud discovery.
*/
@EnableDiscoveryClient
@SpringBootApplication
public class CloudSleuthClientApplication {

/**
* Starts the grpc cloud discovery client application.
*
* @param args The arguments to pass to the application.
*/
public static void main(final String... args) {
SpringApplication.run(CloudSleuthClientApplication.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2016-2021 Michael Zhang <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

package net.devh.boot.grpc.examples.cloud.client;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
* Optional demo controller making the grpc service accessible via browser requests.
*/
@RestController
public class GrpcClientController {

@Autowired
private GrpcClientService grpcClientService;

@RequestMapping("/")
public String printMessage(@RequestParam(defaultValue = "Michael") final String name) {
return this.grpcClientService.sendMessage(name);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2016-2021 Michael Zhang <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

package net.devh.boot.grpc.examples.cloud.client;

import org.springframework.stereotype.Service;

import io.grpc.StatusRuntimeException;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.client.inject.GrpcClient;
import net.devh.boot.grpc.examples.lib.HelloReply;
import net.devh.boot.grpc.examples.lib.HelloRequest;
import net.devh.boot.grpc.examples.lib.SimpleGrpc.SimpleBlockingStub;

/**
* Example class demonstrating the usage of {@link GrpcClient}s inside an application.
*/
@Service
@Slf4j
public class GrpcClientService {

@GrpcClient("cloud-grpc-server")
private SimpleBlockingStub simpleStub;

public String sendMessage(final String name) {
try {
final HelloReply response = this.simpleStub.sayHello(HelloRequest.newBuilder().setName(name).build());
return response.getMessage();
} catch (final StatusRuntimeException e) {
log.error("Request failed", e);
return "FAILED with " + e.getStatus().getCode();
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright (c) 2016-2021 Michael Zhang <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

package net.devh.boot.grpc.examples.cloud.client;

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import brave.Span;
import brave.Tracing;
import brave.grpc.GrpcTracing;
import io.grpc.ClientInterceptor;
import io.grpc.ServerInterceptor;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.client.interceptor.GlobalClientInterceptorConfigurer;
import zipkin2.reporter.Reporter;

/**
* Example configuration class that add grpc client sleuth/brave and zipkin integration
*/
@ConditionalOnProperty(value = {"spring.sleuth.enabled", "spring.zipkin.enabled"}, havingValue = "true")
@Configuration
@Slf4j
public class GrpcSleuthClientConfig {

@Bean
public GrpcTracing grpcTracing(Tracing tracing) {
return GrpcTracing.create(tracing);
}

/**
* We also create a client-side interceptor and put that in the context, this interceptor can then be injected into
* gRPC clients and then applied to the managed channel.
*
* @param grpcTracing
* @return
*/
@Bean
ClientInterceptor grpcClientSleuthInterceptor(GrpcTracing grpcTracing) {
return grpcTracing.newClientInterceptor();
}

@Bean
ServerInterceptor grpcServerSleuthInterceptor(GrpcTracing grpcTracing) {
return grpcTracing.newServerInterceptor();
}
haochencheng marked this conversation as resolved.
Show resolved Hide resolved

/**
* Use this for debugging (or if there is no Zipkin server running on port 9411)
*
* @return
*/
@Bean
public Reporter<Span> spanReporter() {
return span -> {
if (log.isDebugEnabled()) {
log.debug("{}", span);
}
};
}

@Bean
public GlobalClientInterceptorConfigurer globalInterceptorConfigurerAdapter(
ClientInterceptor grpcClientSleuthInterceptor) {
return registry -> registry.add(grpcClientSleuthInterceptor);
}
haochencheng marked this conversation as resolved.
Show resolved Hide resolved


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
spring:
cloud:
consul:
discovery:
register: false
# hostname: localhost
# port: 8500
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
eureka:
instance:
prefer-ip-address: true
status-page-url-path: /actuator/info
health-check-url-path: /actuator/health
client:
register-with-eureka: false
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
spring:
cloud:
nacos:
discovery:
register-enabled: false
# server-addr: localhost:8848
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
spring:
cloud:
zookeeper:
# connect-string: localhost:2181
discovery:
registry: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
server:
port: 8080
spring:
application:
name: cloud-sleuth-zipkin-grpc-client
zipkin:
base-url: http://localhost:9411
enabled: true
sleuth:
sampler:
probability: 1

grpc:
client:
cloud-grpc-server:
address: 'discovery:///cloud-sleuth-zipkin-grpc-server'
enableKeepAlive: true
keepAliveWithoutCalls: true
negotiationType: plaintext
42 changes: 42 additions & 0 deletions examples/cloud-sleuth-zipkin-grpc-server/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
plugins {
id 'org.springframework.boot'
}

def discoveryProvider = project.findProperty('discovery') ?: 'consul';

dependencies {
switch (discoveryProvider) {
case "nacos": {
implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery'
break;
}
case "consul": {
implementation 'org.springframework.cloud:spring-cloud-starter-consul-discovery'
break;
}
case "eureka": {
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
break;
}
case "zookeeper": {
implementation 'org.springframework.cloud:spring-cloud-starter-zookeeper-discovery'
break;
}
}

implementation project(':grpc-server-spring-boot-starter') // Replace with actual dependency "net.devh:grpc-server-spring-boot-starter:${springBootGrpcVersion}"
implementation project(':examples:grpc-lib') // Replace with your grpc interface spec

// For demonstration only
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'

// zipkin and sleuth
implementation "org.springframework.cloud:spring-cloud-starter-zipkin:2.2.7.RELEASE"
implementation "org.springframework.cloud:spring-cloud-starter-sleuth"
implementation "io.zipkin.brave:brave-instrumentation-grpc:5.13.2"
}

bootRun {
args = ["--spring.profiles.active=" + discoveryProvider]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2016-2021 Michael Zhang <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

package net.devh.boot.grpc.examples.cloud.server;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
* Example grpc service application supporting cloud discovery.
*/
@EnableDiscoveryClient
@SpringBootApplication
public class CloudSleuthServerApplication {

/**
* Starts the grpc cloud server application.
*
* @param args The arguments to pass to the application.
*/
public static void main(final String... args) {
SpringApplication.run(CloudSleuthServerApplication.class, args);
}

}
Loading