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

gRPC reference documentation #4575

Merged
merged 1 commit into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
** xref:reference/commons-pool.adoc[Apache Commons Pool]
** xref:reference/jvm.adoc[JVM]
** xref:reference/cache.adoc[Cache]
** xref:reference/grpc.adoc[gRPC]
** xref:reference/okhttpclient.adoc[OkHttpClient]
** xref:reference/jetty.adoc[Jetty and Jersey]
** xref:reference/netty.adoc[Netty]
Expand Down
35 changes: 35 additions & 0 deletions docs/modules/ROOT/pages/reference/grpc.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[[overview]]
= gRPC Instrumentation

https://grpc.io/[gRPC] is a modern open source high performance Remote Procedure Call (RPC) framework that can run in any environment.

Below you can find an example of how to instrument gRPC with Micrometer.

First, client and server side interceptors need to be setup.

[source,java,subs=+attributes]
-----
// Setting up interceptors
include::{include-core-test-java}/io/micrometer/core/instrument/binder/grpc/GrpcObservationTest.java[tags=setup, indent=0]

include::{include-core-test-java}/io/micrometer/core/instrument/binder/grpc/GrpcObservationTest.java[tags=setup_2, indent=0]
-----

Next, server and channels need to have the interceptors added.

[source,java,subs=+attributes]
-----
// Adding them to the server and client side
include::{include-core-test-java}/io/micrometer/core/instrument/binder/grpc/GrpcObservationTest.java[tags=example, indent=0]
-----

Below you have an example of usage with the result assertions.

[source,java,subs=+attributes]
-----
// Usage example
include::{include-core-test-java}/io/micrometer/core/instrument/binder/grpc/GrpcObservationTest.java[tags=result, indent=0]

// Observation outcome
include::{include-core-test-java}/io/micrometer/core/instrument/binder/grpc/GrpcObservationTest.java[tags=assertion, indent=0]
-----
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,13 @@ class GrpcObservationTest {

ContextAndEventHoldingObservationHandler<GrpcClientObservationContext> clientHandler;

// tag::setup[]
ObservationGrpcServerInterceptor serverInterceptor;

ObservationGrpcClientInterceptor clientInterceptor;

// end::setup[]

TestObservationRegistry observationRegistry = TestObservationRegistry.create();

@BeforeEach
Expand All @@ -97,8 +100,10 @@ void setUp() {
.observationHandler(serverHandler)
.observationHandler(clientHandler);

// tag::setup_2[]
this.serverInterceptor = new ObservationGrpcServerInterceptor(observationRegistry);
this.clientInterceptor = new ObservationGrpcClientInterceptor(observationRegistry);
// end::setup_2[]
}

@AfterEach
Expand All @@ -116,6 +121,7 @@ class WithEchoService {

@BeforeEach
void setUpEchoService() throws Exception {
// tag::example[]
EchoService echoService = new EchoService();
server = InProcessServerBuilder.forName("sample")
.addService(echoService)
Expand All @@ -124,15 +130,18 @@ void setUpEchoService() throws Exception {
server.start();

channel = InProcessChannelBuilder.forName("sample").intercept(clientInterceptor).build();
// end::example[]
}

@Test
void unaryRpc() {
// tag::result[]
SimpleServiceBlockingStub stub = SimpleServiceGrpc.newBlockingStub(channel);

SimpleRequest request = SimpleRequest.newBuilder().setRequestMessage("Hello").build();
SimpleResponse response = stub.unaryRpc(request);
assertThat(response.getResponseMessage()).isEqualTo("Hello");
// end::result[]

verifyServerContext("grpc.testing.SimpleService", "UnaryRpc", "grpc.testing.SimpleService/UnaryRpc",
MethodType.UNARY);
Expand All @@ -144,6 +153,11 @@ void unaryRpc() {
GrpcServerEvents.MESSAGE_SENT);
assertThat(clientHandler.getEvents()).containsExactly(GrpcClientEvents.MESSAGE_SENT,
GrpcClientEvents.MESSAGE_RECEIVED);
// tag::assertion[]
TestObservationRegistryAssert.assertThat(observationRegistry)
.hasAnObservation(observationContextAssert -> observationContextAssert.hasNameEqualTo("grpc.client"))
.hasAnObservation(observationContextAssert -> observationContextAssert.hasNameEqualTo("grpc.server"));
// end::assertion[]
}

@Test
Expand Down Expand Up @@ -174,6 +188,9 @@ public void onFailure(Throwable t) {

await().until(() -> futures.stream().allMatch(Future::isDone));
assertThat(responses).hasSize(count).containsExactlyInAnyOrderElementsOf(messages);
TestObservationRegistryAssert.assertThat(observationRegistry)
.hasAnObservation(observationContextAssert -> observationContextAssert.hasNameEqualTo("grpc.client"))
.hasAnObservation(observationContextAssert -> observationContextAssert.hasNameEqualTo("grpc.server"));
}

@Test
Expand Down Expand Up @@ -213,6 +230,9 @@ void clientStreamingRpc() {
verifyServerContext("grpc.testing.SimpleService", "ClientStreamingRpc",
"grpc.testing.SimpleService/ClientStreamingRpc", MethodType.CLIENT_STREAMING);
assertThat(serverHandler.getContext().getStatusCode()).isEqualTo(Code.OK);
TestObservationRegistryAssert.assertThat(observationRegistry)
.hasAnObservation(observationContextAssert -> observationContextAssert.hasNameEqualTo("grpc.client"))
.hasAnObservation(observationContextAssert -> observationContextAssert.hasNameEqualTo("grpc.server"));
}

@Test
Expand Down Expand Up @@ -244,6 +264,9 @@ void serverStreamingRpc() {
assertThat(clientHandler.getContext().getStatusCode()).isEqualTo(Code.OK);
assertThat(clientHandler.getEvents()).containsExactly(GrpcClientEvents.MESSAGE_SENT,
GrpcClientEvents.MESSAGE_RECEIVED, GrpcClientEvents.MESSAGE_RECEIVED);
TestObservationRegistryAssert.assertThat(observationRegistry)
.hasAnObservation(observationContextAssert -> observationContextAssert.hasNameEqualTo("grpc.client"))
.hasAnObservation(observationContextAssert -> observationContextAssert.hasNameEqualTo("grpc.server"));
}

@Test
Expand Down Expand Up @@ -293,6 +316,9 @@ void bidiStreamingRpc() {

assertThat(serverHandler.getContext().getStatusCode()).isEqualTo(Code.OK);
assertThat(clientHandler.getContext().getStatusCode()).isEqualTo(Code.OK);
TestObservationRegistryAssert.assertThat(observationRegistry)
.hasAnObservation(observationContextAssert -> observationContextAssert.hasNameEqualTo("grpc.client"))
.hasAnObservation(observationContextAssert -> observationContextAssert.hasNameEqualTo("grpc.server"));
}

private StreamObserver<SimpleResponse> createResponseObserver(List<String> messages, AtomicBoolean completed) {
Expand Down