From e70aebc3557ad9c226dfc564d9124994b21d3a42 Mon Sep 17 00:00:00 2001 From: Lisa Jamen <31409174+ljamen@users.noreply.github.com> Date: Tue, 7 Feb 2023 15:49:55 -0600 Subject: [PATCH 1/2] changes for tracing --- docs/includes/tracing/tracer-jaeger.adoc | 12 ++-- docs/se/guides/tracing.adoc | 92 +++++++++++++----------- docs/se/tracing.adoc | 24 ++++--- 3 files changed, 75 insertions(+), 53 deletions(-) diff --git a/docs/includes/tracing/tracer-jaeger.adoc b/docs/includes/tracing/tracer-jaeger.adoc index 2d9313341e6..83596335c8e 100644 --- a/docs/includes/tracing/tracer-jaeger.adoc +++ b/docs/includes/tracing/tracer-jaeger.adoc @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// - Copyright (c) 2019, 2022 Oracle and/or its affiliates. + Copyright (c) 2019, 2023 Oracle and/or its affiliates. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ The Jaeger builder is loaded through `ServiceLoader` and configured. You could also use the Jaeger builder directly, though this would create a source-code dependency on the Jaeger tracer. -Since Helidon 3.0.0, we use Jaeger OpenTelemetry Tracing client to +Helidon 3.0 uses the Jaeger OpenTelemetry Tracing client to integrate with Jaeger tracer. include::{rootdir}/includes/dependencies.adoc[] @@ -45,16 +45,20 @@ include::{rootdir}/includes/dependencies.adoc[] == Configuring Jaeger +NOTE: Jaeger changed its client implementation, so some Jaeger settings exposed by earlier releases of Helidon are no longer available. Please note the currently-supported settings in the table below. + include::{rootdir}/config/io_helidon_tracing_jaeger_JaegerTracerBuilder.adoc[tag=config,levelOffset=1] -The following is an example of a Jaeger configuration, specified in the YAML format. +The following is an example of a Jaeger configuration, specified in the YAML format. + +NOTE: The the Jaeger OpenTelemetry client uses port 14250, but you can override this value if needed. The default is defined by each tracing integration. [source,yaml] ---- tracing: service: "helidon-full-http" protocol: "https" host: "jaeger" - port: 14240 + port: 14250 ---- // end::jaeger-configuration[] diff --git a/docs/se/guides/tracing.adoc b/docs/se/guides/tracing.adoc index c34948a50f2..80565d3da78 100644 --- a/docs/se/guides/tracing.adoc +++ b/docs/se/guides/tracing.adoc @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// - Copyright (c) 2019, 2022 Oracle and/or its affiliates. + Copyright (c) 2019, 2023 Oracle and/or its affiliates. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ = Helidon SE Tracing Guide :description: Helidon tracing :keywords: helidon, tracing, microprofile, guide +:toc: :rootdir: {docdir}/../.. :imagesdir: {rootdir}/images @@ -163,30 +164,28 @@ WebServer server = WebServer.builder(createRouting(config)) [source,java] .Update the `GreetService` class; 1) Add a new import and 2) Replace the `getDefaultMessageHandler` method: ---- -import io.opentracing.Span; // <1> -... private void getDefaultMessageHandler(ServerRequest request, ServerResponse response) { - var spanBuilder = request.tracer() // <2> - .buildSpan("getDefaultMessageHandler"); // <3> - request.spanContext().ifPresent(spanBuilder::asChildOf); // <4> - Span span = spanBuilder.start(); // <5> + var span = request.tracer() // <1> + .spanBuilder("getDefaultMessageHandler") // <2> + .update(spanBuilder -> request.spanContext().ifPresent(spanBuilder::parent)) // <3> + .start(); // <4> try { sendResponse(response, "World"); - } finally { - span.finish(); // <6> + span.end(); // <5> + } catch (Throwable t) { + span.end(t); // <6> } } ---- -<1> Add new import statement. -<2> Get the `Tracer` object from the request. -<3> Build a new span named `getDefaultMessageHandler`. -<4> Make the new span a child of the current span. -<5> Start the span. The current timestamp is used as the starting time for the span. -<6> Finish the span. The current timestamp is used as the ending time for the span. - +<1> Get the `Tracer` object from the request. +<2> Build a new span named `getDefaultMessageHandler`. +<3> Make the new span a child of the request's span if it has one. +<4> Start the span. The current timestamp is used as the starting time for the span. +<5> End the span successfully. The current timestamp is used as the ending time for the span. +<6> End the span in the error case. [source,bash] .Build the application, skipping unit tests, then run it: @@ -383,25 +382,30 @@ WebServer server = WebServer.builder(createRouting(config)) ---- [source,java] -.Update the `GreetService` class; 1) Add new import and 2) Replace the `getDefaultMessageHandler` method: +.Update the `GreetService` class; 1) Add a new import and 2) Replace the `getDefaultMessageHandler` method: ---- -import io.opentracing.Span; -//... private void getDefaultMessageHandler(ServerRequest request, ServerResponse response) { - var spanBuilder = request.tracer() - .buildSpan("getDefaultMessageHandler"); - request.spanContext().ifPresent(spanBuilder::asChildOf); - Span span = spanBuilder.start(); + var span = request.tracer() // <1> + .spanBuilder("getDefaultMessageHandler") // <2> + .update(spanBuilder -> request.spanContext().ifPresent(spanBuilder::parent)) // <3> + .start(); // <4> try { sendResponse(response, "World"); - } finally { - span.finish(); + span.end(); // <5> + } catch (Throwable t) { + span.end(t); // <6> } } ---- +<1> Get the `Tracer` object from the request. +<2> Build a new span named `getDefaultMessageHandler`. +<3> Make the new span a child of the request's span if it has one. +<4> Start the span. The current timestamp is used as the starting time for the span. +<5> End the span successfully. The current timestamp is used as the ending time for the span. +<6> End the span in the error case. [source,bash] .Build the application, skipping unit tests, then run it: @@ -492,17 +496,19 @@ public class GreetService implements Service { .put("/greeting", this::updateGreetingHandler); } - private void getDefaultMessageHandler(ServerRequest request, ServerResponse response) { + private void getDefaultMessageHandler(ServerRequest request, + ServerResponse response) { - var spanBuilder = request.tracer() - .buildSpan("getDefaultMessageHandler"); - request.spanContext().ifPresent(spanBuilder::asChildOf); - Span span = spanBuilder.start(); + var span = request.tracer() + .spanBuilder("getDefaultMessageHandler") + .update(spanBuilder -> request.spanContext().ifPresent(spanBuilder::parent)) + .start(); try { sendResponse(response, "World"); - } finally { - span.finish(); + span.end(); + } catch (Throwable t) { + span.end(t); } } @@ -527,13 +533,13 @@ public class GreetService implements Service { } private void outboundMessageHandler(ServerRequest request, ServerResponse response) { - Invocation.Builder requestBuilder = webTarget.request(); + Invocation.Builder requestBuilder = webTarget.request(); // <2> - var spanBuilder = request.tracer() - .buildSpan("outboundMessageHandler"); - request.spanContext().ifPresent(spanBuilder::asChildOf); - Span span = spanBuilder.start(); + var span = request.tracer() + .spanBuilder("outboundMessageHandler") + .update(spanBuilder -> request.spanContext().ifPresent(spanBuilder::parent)) + .start(); try { requestBuilder.property( @@ -542,16 +548,20 @@ public class GreetService implements Service { requestBuilder // <4> .rx() .get(String.class) - .thenAccept(response::send) + .thenAccept(str -> { + response.send(str); + span.end(); // <5> + }) .exceptionally( throwable -> { // process exception response.status(Http.Status.INTERNAL_SERVER_ERROR_500); response.send("Failed with: " + throwable); + span.end(throwable); // <5> return null; }); - } finally { - span.finish(); // <5> + } catch (Throwable t) { + span.end(t); // <5> } } @@ -564,7 +574,7 @@ public class GreetService implements Service { <2> Create and start a span that is a child of the current span. <3> Set a property with the `SpanContext`. <4> Invoke the second service. -<5> Stop the span. +<5> End the span. [source,bash] .Build and run the application, then invoke the endpoint and check the response: diff --git a/docs/se/tracing.adoc b/docs/se/tracing.adoc index f63f44fe6b8..b22d35f56a0 100644 --- a/docs/se/tracing.adoc +++ b/docs/se/tracing.adoc @@ -126,20 +126,28 @@ GrpcServerConfiguration serverConfig = GrpcServerConfiguration.builder().port(0) .build(); ---- -=== Creating custom spans +=== Creating Custom Spans To create a custom span that is a child of the WebServer request: [source,java] ---- Span span = request.tracer() - .buildSpan("my-operation") - .asChildOf(request.spanContext()) - .start(); + .spanBuilder("my-operation") + .update(spanBuilder -> request.spanContext().ifPresent(spanBuilder::parent)) + .start(); + + try { + // Do some work and send a normal response. + span.end(); + } catch (Throwable t) { + // Send an error response. + span.end(t); + } ---- -=== Helidon Spans +== Helidon Spans include::{rootdir}/includes/tracing/common-spans.adoc[] @@ -149,7 +157,7 @@ The following configuration should be supported by all tracer implementations (i include::{rootdir}/config/io_helidon_tracing_Tracer.adoc[tag=config,levelOffset=1] -=== Traced spans configuration +=== Traced Spans Configuration Each component and its spans can be configured using Config. The traced configuration has the following layers: @@ -203,9 +211,9 @@ tracing: routing.register(WebTracingConfig.create(config.get("tracing"))); ---- -==== Path based configuration in Helidon Web Server +==== Path-based configuration in Helidon Web Server -For Web Server we have a path based support for configuring tracing, in addition +For Web Server we have path-based support for configuring tracing, in addition to the configuration described above. Configuration of path can use any path string supported by the From 1ff9d4835c6e31b03bb41bf41cc34062d8183636 Mon Sep 17 00:00:00 2001 From: Lisa Jamen <31409174+ljamen@users.noreply.github.com> Date: Wed, 8 Feb 2023 08:34:35 -0600 Subject: [PATCH 2/2] Tim's review comments --- docs/se/guides/tracing.adoc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/se/guides/tracing.adoc b/docs/se/guides/tracing.adoc index 80565d3da78..353c21ef404 100644 --- a/docs/se/guides/tracing.adoc +++ b/docs/se/guides/tracing.adoc @@ -162,7 +162,7 @@ WebServer server = WebServer.builder(createRouting(config)) <2> Build and register a `Tracer` object using the tracing configuration. [source,java] -.Update the `GreetService` class; 1) Add a new import and 2) Replace the `getDefaultMessageHandler` method: +.Update the `GreetService` class; Replace the `getDefaultMessageHandler` method: ---- private void getDefaultMessageHandler(ServerRequest request, ServerResponse response) { @@ -382,7 +382,7 @@ WebServer server = WebServer.builder(createRouting(config)) ---- [source,java] -.Update the `GreetService` class; 1) Add a new import and 2) Replace the `getDefaultMessageHandler` method: +.Update the `GreetService` class; Replace the `getDefaultMessageHandler` method: ---- private void getDefaultMessageHandler(ServerRequest request, ServerResponse response) { @@ -463,7 +463,6 @@ import io.helidon.webserver.Routing; import io.helidon.webserver.ServerRequest; import io.helidon.webserver.ServerResponse; import io.helidon.webserver.Service; -import io.opentracing.Span; import java.util.Collections; import java.util.concurrent.atomic.AtomicReference; import jakarta.json.Json;