Author: buildbot
Date: Sun Aug 27 17:42:53 2023
New Revision: 1084032
Log:
Production update by buildbot for cxf
Modified:
websites/production/cxf/content/cache/docs.pageCache
websites/production/cxf/content/docs/using-opentelemetry.html
Modified: websites/production/cxf/content/cache/docs.pageCache
==============================================================================
Binary files - no diff available.
Modified: websites/production/cxf/content/docs/using-opentelemetry.html
==============================================================================
--- websites/production/cxf/content/docs/using-opentelemetry.html (original)
+++ websites/production/cxf/content/docs/using-opentelemetry.html Sun Aug 27
17:42:53 2023
@@ -107,15 +107,15 @@ Apache CXF -- Using OpenTelemetry
<td height="100%">
<!-- Content -->
<div class="wiki-content">
-<div id="ConfluenceContent"><h1
id="UsingOpenTelemetry-/*<![CDATA[*/div.rbtoc1693154570052{padding:0px;}div.rbtoc1693154570052ul{margin-left:0px;}div.rbtoc1693154570052li{margin-left:0px;padding-left:0px;}/*]]>*/#UsingOpenTelemetry-Overview#UsingOpenTelemetry-OverviewDistributedTracinginApa"><style
type="text/css">/*<![CDATA[*/
-div.rbtoc1693154570052 {padding: 0px;}
-div.rbtoc1693154570052 ul {margin-left: 0px;}
-div.rbtoc1693154570052 li {margin-left: 0px;padding-left: 0px;}
+<div id="ConfluenceContent"><h1
id="UsingOpenTelemetry-/*<![CDATA[*/div.rbtoc1693158169471{padding:0px;}div.rbtoc1693158169471ul{margin-left:0px;}div.rbtoc1693158169471li{margin-left:0px;padding-left:0px;}/*]]>*/#UsingOpenTelemetry-Overview#UsingOpenTelemetry-OverviewDistributedTracinginApa"><style
type="text/css">/*<![CDATA[*/
+div.rbtoc1693158169471 {padding: 0px;}
+div.rbtoc1693158169471 ul {margin-left: 0px;}
+div.rbtoc1693158169471 li {margin-left: 0px;padding-left: 0px;}
-/*]]>*/</style></h1><div class="toc-macro rbtoc1693154570052">
+/*]]>*/</style></h1><div class="toc-macro rbtoc1693158169471">
<ul class="toc-indentation"><li><a shape="rect"
href="#UsingOpenTelemetry-"></a></li><li><a shape="rect"
href="#UsingOpenTelemetry-Overview">Overview</a></li><li><a shape="rect"
href="#UsingOpenTelemetry-DistributedTracinginApacheCXFusingOpenTelemetry">Distributed
Tracing in Apache CXF using OpenTelemetry</a></li><li><a shape="rect"
href="#UsingOpenTelemetry-ConfiguringClient">Configuring Client</a></li><li><a
shape="rect" href="#UsingOpenTelemetry-ConfiguringServer">Configuring
Server</a></li><li><a shape="rect"
href="#UsingOpenTelemetry-DistributedTracingInAction:UsageScenarios">Distributed
Tracing In Action: Usage Scenarios</a>
<ul class="toc-indentation"><li><a shape="rect"
href="#UsingOpenTelemetry-Example#1:ClientandServerwithdefaultdistributedtracingconfigured">Example
#1: Client and Server with default distributed tracing
configured</a></li><li><a shape="rect"
href="#UsingOpenTelemetry-Example#2:ClientandServerwithnestedtrace">Example #2:
Client and Server with nested trace</a></li><li><a shape="rect"
href="#UsingOpenTelemetry-Example#3:ClientandServertracewithannotations">Example
#3: Client and Server trace with annotations</a></li><li><a shape="rect"
href="#UsingOpenTelemetry-Example#4:ClientandServerwithbinaryannotations(key/value)">Example
#4: Client and Server with binary annotations (key/value)</a></li><li><a
shape="rect"
href="#UsingOpenTelemetry-Example#5:ClientandServerwithparalleltrace(involvingthreadpools)">Example
#5: Client and Server with parallel trace (involving thread
pools)</a></li><li><a shape="rect"
href="#UsingOpenTelemetry-Example#6:ClientandServerwithasynchronousJAX-RSservice(se
rver-side)">Example #6: Client and Server with asynchronous JAX-RS service
(server-side)</a></li><li><a shape="rect"
href="#UsingOpenTelemetry-Example#7:ClientandServerwithasynchronousinvocation(client-side)">Example
#7: Client and Server with asynchronous invocation (client-side)</a></li></ul>
-</li><li><a shape="rect"
href="#UsingOpenTelemetry-DistributedTracingwithOpenTelemetryandJAX-WSsupport">Distributed
Tracing with OpenTelemetry and JAX-WS support</a></li><li><a shape="rect"
href="#UsingOpenTelemetry-DistributedTracingwithOpenTelemetryandOSGi">Distributed
Tracing with OpenTelemetry and OSGi</a></li><li><a shape="rect"
href="#UsingOpenTelemetry-SpringXML-Configuration">Spring
XML-Configuration</a></li><li><a shape="rect"
href="#UsingOpenTelemetry-Usingnon-JAX-RSclients">Using non-JAX-RS
clients</a></li></ul>
+</li><li><a shape="rect"
href="#UsingOpenTelemetry-DistributedTracingwithOpenTelemetryandJAX-WSsupport">Distributed
Tracing with OpenTelemetry and JAX-WS support</a></li><li><a shape="rect"
href="#UsingOpenTelemetry-DistributedTracingwithOpenTelemetryandOSGi">Distributed
Tracing with OpenTelemetry and OSGi</a></li><li><a shape="rect"
href="#UsingOpenTelemetry-AccessingOpenTelemetryAPIs">Accessing OpenTelemetry
APIs</a></li><li><a shape="rect"
href="#UsingOpenTelemetry-Usingnon-JAX-RSclients">Using non-JAX-RS
clients</a></li></ul>
</div><h1 id="UsingOpenTelemetry-Overview">Overview</h1><p><a shape="rect"
class="external-link" href="https://opentelemetry.io/"
rel="nofollow">OpenTelemetry</a> (formed through a merger of the <a
shape="rect" class="external-link" href="http://opentracing.io/"
rel="nofollow">OpenTracing</a> and <a shape="rect" class="external-link"
href="https://opencensus.io/" rel="nofollow">OpenCensus</a> projects) is a
collection of APIs, SDKs, and tools to instrument, generate, collect, and
export telemetry data like metrics, logs, and distributed traces. <a
shape="rect" class="external-link" href="https://opentelemetry.io/"
rel="nofollow">OpenTelemetry</a> is vendor-neutral open-source <a shape="rect"
class="external-link"
href="https://opentelemetry.io/docs/concepts/observability-primer/#what-is-observability"
rel="nofollow">observability</a> framework and as an industry-standard, it is
<a shape="rect" class="external-link"
href="https://opentelemetry.io/ecosystem/vendors/" rel="nofollow">na
tively supported by a number of vendors</a>. From the instrumentation
perspective, there is support for quite a few programming languages, including
dedicated <a shape="rect" class="external-link"
href="https://github.com/open-telemetry/opentelemetry-java" rel="nofollow">Java
APIs</a>. Starting from <strong>3.5.7 /3.6.2</strong> <strong>/ 4.0.3</strong>
releases, Apache CXF fully supports integration (through
<strong>cxf-integration-tracing-opentelemetry </strong>module) with <a
shape="rect" class="external-link" href="https://opentelemetry.io/"
rel="nofollow">OpenTelemetry</a> distributed tracing capabilities.</p><p>The
section <a shape="rect"
href="https://cwiki.apache.org/confluence/display/CXF20DOC/Using+Apache+HTrace">dedicated
to Apache HTrace </a>has pretty good introduction into distributed tracing
basics however <a shape="rect" class="external-link"
href="https://opentelemetry.io/" rel="nofollow">OpenTelemetry</a> specification
abstracts a lot of things, outlining just a ge
neral APIs to denote the <strong>Span </strong>lifecycle and injection
points to propagate the context across many distributed components. As such,
the intrinsic details about HTTP headers f.e. becomes an integral part of the
distributed tracer of your choice, out of reach for Apache CXF.</p><h1
id="UsingOpenTelemetry-DistributedTracinginApacheCXFusingOpenTelemetry">Distributed
Tracing in Apache CXF using OpenTelemetry</h1><p>The current integration of
the <a shape="rect" class="external-link" href="https://opentelemetry.io/"
rel="nofollow">OpenTelemetry</a>'s distributed tracing in <a shape="rect"
href="http://cxf.apache.org/">Apache CXF</a> supports <a shape="rect"
class="external-link"
href="https://github.com/open-telemetry/opentelemetry-java"
rel="nofollow">OpenTelemetry Java SDK</a> <strong>1</strong><strong
class="external-link">.28.0+</strong> (using <a shape="rect"
class="external-link"
href="https://github.com/open-telemetry/opentelemetry-java/blob/main/semconv"
rel="nofollow">semantic conventions</a>) and provides full-fledged support of
JAX-RS 2.x / JAX-WS applications. From high-level prospective, the JAX-RS
integration consists of three main
parts:</p><ul><li><strong>TracerContext</strong> (injectable through
<strong>@Context</strong>
annotation)</li><li><strong>OpenTelemetryProvider</strong> (server-side JAX-RS
provider) and <strong>OpenTelemetryClientProvider</strong> (client-side JAX-RS
provider)</li><li class="external-link"><strong>OpenTelemetryFeature</strong>
(server-side JAX-RS feature) to simplify the configuration and
integration</li></ul><p>Similarly, from high-level perspective, JAX-WS
integration includes:</p><ul><li><strong>OpenTelemetryStartInterceptor</strong>
/ <strong>OpenTelemetryStopInterceptor</strong> / <strong>OpenTelemetryFeature
</strong><a shape="rect" href="http://cxf.apache.org/">Apache CXF</a> feature
(server-side JAX-WS
support)</li><li><strong>OpenTelemetryClientStartInterceptor</strong> /
<strong>Ope
nTelemetryClientStopInterceptor</strong> / <strong>OpenTelemetryClientFeature
</strong><a shape="rect" href="http://cxf.apache.org/">Apache CXF</a> feature
(client-side JAX-WS support)</li></ul><p><a shape="rect"
href="http://cxf.apache.org/">Apache CXF</a> uses HTTP headers to hand off
tracing context from the client to the service and from the service to service.
Those headers are specific to distributing tracing framework you have picked
and are not configurable at the moment (unless the framework itself has a way
to do that).</p><p>By default, <strong>OpenTelemetryClientProvider</strong>
will use configured propagators to pass the currently active
<strong>span</strong> through HTTP headers on each service invocation. If there
is no active spans, the new span will be created and passed through HTTP
headers on per-invocation basis. Essentially, for JAX-RS applications just
registering <strong>OpenTelemetryClientProvider</strong> on the client and
<strong>OpenTelemetryProvider</str
ong> on the server is enough to have tracing context to be properly passed
everywhere. The only configuration part which is necessary are <strong>span
exporters(s)</strong> and <strong>sampler(s)</strong> which are, not
surprisingly, specific to distributing tracing vendor you have chosen.</p><p>It
is also worth to mention the way <a shape="rect"
href="http://cxf.apache.org/">Apache CXF</a> attaches the description to
<strong>spans</strong>. With regards to the client integration, the description
becomes a full URL being invoked prefixed by HTTP method, for example:
<strong>GET </strong><a shape="rect" class="external-link"
href="http://localhost:8282/books"
rel="nofollow"><strong>http://localhost:8282</strong>/books</a>. On the server
side integration, the description becomes a relative JAX-RS resource path
prefixed by HTTP method, f.e.: <strong>GET books, POST book/123</strong></p><h1
id="UsingOpenTelemetry-ConfiguringClient">Configuring Client</h1><p>There are a
couple of ways th
e JAX-RS client could be configured, depending on the client implementation.
<a shape="rect" href="http://cxf.apache.org/">Apache CXF</a> provides its own
<strong>WebClient</strong> which could be configured just like that (in future
versions, there would be a simpler ways to do that using client specific
features):</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default">final
SdkTracerProvider sdkTracerProvider = SdkTracerProvider
.builder()
@@ -316,7 +316,94 @@ public Collection<Book> getBooks()
.accept(MediaType.APPLICATION_JSON)
.async()
.get();</pre>
-</div></div><p>In this respect, there is no difference from the caller
prospective however a bit more work is going under the hood to transfer the
active tracing span from JAX-RS client request filter to client response filter
as in general those are executed in different threads (similarly to server-side
asynchronous JAX-RS resource invocation). The actual invocation of the request
by the client (with service name <strong>tracer-<span class="label
label-default service-filter-label
service-tag-filtered">client</span></strong>) and consequent invocation of the
service on the server side (service name<strong> tracer-<span class="label
label-default service-filter-label">server</span></strong>) is going to
generate the following sample traces (taken from <a shape="rect"
class="external-link" href="https://github.com/uber/jaeger-ui"
rel="nofollow">Jaeger UI</a>):</p><p><span
class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img
class="confluence-embedded-image"
draggable="false" width="900"
src="using-opentelemetry.data/image-2023-8-27_12-25-58.png"></span></p><h1
id="UsingOpenTelemetry-DistributedTracingwithOpenTelemetryandJAX-WSsupport">Distributed
Tracing with OpenTelemetry and JAX-WS support</h1><p>TBD</p><h1
id="UsingOpenTelemetry-DistributedTracingwithOpenTelemetryandOSGi">Distributed
Tracing with OpenTelemetry and OSGi</h1><p>TBD</p><h1
id="UsingOpenTelemetry-SpringXML-Configuration">Spring
XML-Configuration</h1><p>TBD</p><h1
id="UsingOpenTelemetry-Usingnon-JAX-RSclients">Using non-JAX-RS
clients</h1><p>TBD</p><p><br clear="none"></p></div>
+</div></div><p>In this respect, there is no difference from the caller
prospective however a bit more work is going under the hood to transfer the
active tracing span from JAX-RS client request filter to client response filter
as in general those are executed in different threads (similarly to server-side
asynchronous JAX-RS resource invocation). The actual invocation of the request
by the client (with service name <strong>tracer-<span class="label
label-default service-filter-label
service-tag-filtered">client</span></strong>) and consequent invocation of the
service on the server side (service name<strong> tracer-<span class="label
label-default service-filter-label">server</span></strong>) is going to
generate the following sample traces (taken from <a shape="rect"
class="external-link" href="https://github.com/uber/jaeger-ui"
rel="nofollow">Jaeger UI</a>):</p><p><span
class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img
class="confluence-embedded-image"
draggable="false" width="900"
src="using-opentelemetry.data/image-2023-8-27_12-25-58.png"></span></p><h1
id="UsingOpenTelemetry-DistributedTracingwithOpenTelemetryandJAX-WSsupport">Distributed
Tracing with OpenTelemetry and JAX-WS support</h1><p>Distributed tracing in
the <a shape="rect" href="http://cxf.apache.org/">Apache CXF</a> is build
primarily around JAX-RS 2.x implementation. However, JAX-WS is also supported
but it requires to write some boiler-plate code and use <a shape="rect"
class="external-link"
href="https://github.com/open-telemetry/opentelemetry-java"
rel="nofollow">OpenTelemetry Java SDK</a> directly (the JAX-WS integration is
going to be enhanced in the future). Essentially, from the server-side
prospective the in/out interceptors,
<strong>OpenTelemetryStartInterceptor</strong> and
<strong>OpenTelemetryStopInterceptor </strong>respectively, should be
configured as part of interceptor chains, either manually or using
<strong>OpenTelemetryFeature</strong>. For examp
le:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default">final
SdkTracerProvider sdkTracerProvider = SdkTracerProvider
+ .builder()
+ ...
+ .build();
+
+final OpenTelemetry openTelemetry = OpenTelemetrySdk
+ .builder()
+ .setTracerProvider(sdkTracerProvider)
+ ...
+ .buildAndRegisterGlobal();
+
+final Tracer tracer = openTelemetry.getTracer("tracer");
+final JaxWsServerFactoryBean sf = new JaxWsServerFactoryBean();
+...
+sf.getFeatures().add(new OpenTelemetryFeature(openTelemetry, tracer));
+...
+sf.create();</pre>
+</div></div><p>Similarly to the server-side, client-side needs own set of
out/in interceptors, <strong>OpenTelemetryClientStartInterceptor</strong> and
<strong>OpenTelemetryClientStopInterceptor</strong> (or
<strong>OpenTelemetryClientFeature</strong>). Please notice the difference from
server-side:  <strong>OpenTelemetryClientStartInterceptor</strong> becomes
out-interceptor while <strong>OpenTelemetryClientStopInterceptor</strong>
becomes in-interceptor. For example:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default">final
SdkTracerProvider sdkTracerProvider = SdkTracerProvider
+ .builder()
+ ...
+ .build();
+
+final OpenTelemetry openTelemetry = OpenTelemetrySdk
+ .builder()
+ .setTracerProvider(sdkTracerProvider)
+ ...
+ .buildAndRegisterGlobal();
+
+final Tracer tracer = openTelemetry.getTracer("tracer");
+final JaxWsProxyFactoryBean sf = new JaxWsProxyFactoryBean();
+...
+sf.getFeatures().add(new OpenTelemetryClientFeature(openTelemetry, tracer));
+...
+sf.create();</pre>
+</div></div><p>As it was mentioned before, you may use
<strong>GlobalOpenTelemetry</strong> utility class to pass the tracer around
so, for example, any JAX-WS service will be able to retrieve the current tracer
by invoking <strong>GlobalOpenTelemetry</strong>.<strong>get()</strong>
method.</p><h1
id="UsingOpenTelemetry-DistributedTracingwithOpenTelemetryandOSGi">Distributed
Tracing with OpenTelemetry and OSGi</h1><p>TBD</p><h1
id="UsingOpenTelemetry-AccessingOpenTelemetryAPIs">Accessing OpenTelemetry
APIs</h1><p>The <a shape="rect" href="http://cxf.apache.org/">Apache
CXF</a>  abstracts as much of the tracer-specific APIs behind
<strong>TracerContext</strong> as possible. However, sometimes there is a need
to get access to <a shape="rect" class="external-link"
href="https://opentelemetry.io/docs/instrumentation/java/"
rel="nofollow">OpenTelemetry</a> APIs in order to leverages the rich set of
available instrumentations. To make it possible, <strong>TracerContext</strong>
has a dedicated <strong>unwrap</strong> method which returns underlying
<strong>Tracer</strong> instance. The snippet below shows off how to use this
API and use <a shape="rect" class="external-link"
href="https://opentelemetry.io/docs/instrumentation/java/"
rel="nofollow">OpenTelemetry</a> instrumentation for <a shape="rect"
class="external-link" href="https://github.com/OpenFeign/feign-opentracing"
rel="nofollow">OpenFeign client</a> through <a shape="rect"
class="external-link" href="http://opentracing.io/"
rel="nofollow">OpenTracing</a> shim (as of today, <a shape="rect"
class="external-link" href="https://github.com/OpenFeign/feign-opentracing"
rel="nofollow">OpenFeign client</a> does not provide native support for <a
shape="rect" class="external-link"
href="https://opentelemetry.io/docs/instrumentation/java/"
rel="nofollow">OpenTelemetry</a>).</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default">final
SdkTracerProvider sdkTracerProvider = SdkTracerProvider
+ .builder()
+ ...
+ .build();
+
+final OpenTelemetry openTelemetry = OpenTelemetrySdk
+ .builder()
+ .setTracerProvider(sdkTracerProvider)
+ ...
+ .buildAndRegisterGlobal();
+
+// Use OpenTelemetru OpenTracing shim for Feign OpenTracing integration
+GlobalTracer.registerIfAbsent(OpenTracingShim.createTracerShim(openTelemetry));</pre>
+</div></div><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default">@GET
+@Path("/search")
+@Produces(MediaType.APPLICATION_JSON)
+public JsonObject search(@QueryParam("q") final String query, @Context final
TracerContext tracing) throws Exception {
+ final GoogleBooksApi api = Feign.builder()
+ .client(new TracingClient(new ApacheHttpClient(),
tracing.unwrap(Tracer.class)))
+ .target(GoogleBooksApi.class, "https://www.googleapis.com");
+
+ final Response response = api.search(query);
+ try (final Reader reader = response.body().asReader()) {
+ return Json.createReader(reader).readObject();
+ }
+}</pre>
+</div></div><p>The usage of tracer-specific APIs is not generally advisable
(because of portability reasons) but in case there are no other options
available, it is available.</p><h1
id="UsingOpenTelemetry-Usingnon-JAX-RSclients">Using non-JAX-RS
clients</h1><p>The  <a shape="rect" href="http://cxf.apache.org/">Apache
CXF</a>  uses native <a shape="rect" class="external-link"
href="https://opentelemetry.io/docs/instrumentation/java/"
rel="nofollow">OpenTelemetry</a> capabilities so the existing instrumentations
for different HTTP clients work as expected. The usage of only JAX-RS client is
not required. For example, the following snippet demonstrates the usage of
traceble <a shape="rect" class="external-link"
href="http://square.github.io/okhttp/" rel="nofollow">OkHttp</a> client 
to call JAX-RS resources, backed by <a shape="rect"
href="http://cxf.apache.org/">Apache CXF</a> and <a shape="rect"
class="external-link" href="https://github.com/open-telemetry/opentelemet
ry-java-instrumentation/tree/main/instrumentation/okhttp/okhttp-3.0"
rel="nofollow">OpenTelemetry OkHttp3 instrumentation</a>.</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default">final
SdkTracerProvider sdkTracerProvider = SdkTracerProvider
+ .builder()
+ ...
+ .build();
+
+final OpenTelemetry openTelemetry = OpenTelemetrySdk
+ .builder()
+ .setTracerProvider(sdkTracerProvider)
+ ...
+ .buildAndRegisterGlobal();
+
+final OkHttpClient client = OkHttpClient.Builder().build();
+final Call.Factory factory =
OkHttpTelemetry.builder(openTelemetry).build().newCallFactory(client));
+
+final Request request = new Request.Builder()
+ .url("http://localhost:9000/catalog")
+ .header("Accept", "application/json")
+ .build();
+
+try (final Response response = factory.newCall(request).execute()) {
+ // Do something with response.body()
+}</pre>
+</div></div><p><br clear="none"></p><p><br clear="none"></p></div>
</div>
<!-- Content -->
</td>