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-/*&lt;![CDATA[*/div.rbtoc1693154570052{padding:0px;}div.rbtoc1693154570052ul{margin-left:0px;}div.rbtoc1693154570052li{margin-left:0px;padding-left:0px;}/*]]&gt;*/#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-/*&lt;![CDATA[*/div.rbtoc1693158169471{padding:0px;}div.rbtoc1693158169471ul{margin-left:0px;}div.rbtoc1693158169471li{margin-left:0px;padding-left:0px;}/*]]&gt;*/#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&#160;</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&#160;<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,&#160;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&lt;Book&gt; 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:&#160; <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>&#160; abstracts as much of the tracer-specific APIs behind 
<strong>TracerContext</strong> as possible. However, sometimes there is a need 
to get access to&#160;<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&#160; <a shape="rect" href="http://cxf.apache.org/";>Apache 
CXF</a>&#160; 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&#160; 
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>


Reply via email to