diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc index 8a82fb9d61..c7f0bb09ca 100644 --- a/docs/modules/ROOT/nav.adoc +++ b/docs/modules/ROOT/nav.adoc @@ -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] diff --git a/docs/modules/ROOT/pages/reference/grpc.adoc b/docs/modules/ROOT/pages/reference/grpc.adoc new file mode 100644 index 0000000000..d43f77e2c6 --- /dev/null +++ b/docs/modules/ROOT/pages/reference/grpc.adoc @@ -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] +----- diff --git a/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/grpc/GrpcObservationTest.java b/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/grpc/GrpcObservationTest.java index d9f539baa8..39c2d594c8 100644 --- a/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/grpc/GrpcObservationTest.java +++ b/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/grpc/GrpcObservationTest.java @@ -79,10 +79,13 @@ class GrpcObservationTest { ContextAndEventHoldingObservationHandler clientHandler; + // tag::setup[] ObservationGrpcServerInterceptor serverInterceptor; ObservationGrpcClientInterceptor clientInterceptor; + // end::setup[] + TestObservationRegistry observationRegistry = TestObservationRegistry.create(); @BeforeEach @@ -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 @@ -116,6 +121,7 @@ class WithEchoService { @BeforeEach void setUpEchoService() throws Exception { + // tag::example[] EchoService echoService = new EchoService(); server = InProcessServerBuilder.forName("sample") .addService(echoService) @@ -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); @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 createResponseObserver(List messages, AtomicBoolean completed) {