///////////////////////////////////////////////////////////////////////////////

    Copyright (c) 2018, 2020 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.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

///////////////////////////////////////////////////////////////////////////////

= Tracing
:description: Helidon MP Tracing Support
= :keywords: helidon, tracing, microprofile, micro-profile

== Configuring Tracing with Helidon MP
Tracing support is implemented for both for Helidon MP Server and for Jersey client.

Declare the following dependency in your project:

[source,xml]
----
<dependency>
    <groupId>io.helidon.microprofile.tracing</groupId>
    <artifactId>helidon-microprofile-tracing</artifactId>
</dependency>
----

In addition you need to add one of the tracer implementations (Zipkin or Jaeger).

The minimal required configuration is `tracing.service` that contains
the service name to be associated with tracing spans sent by this instance.

All tracer specific configuration is expected in config under `tracing`.

Example `microprofile-config.properties` with minimal tracer configuration:

----
tracing.service=helidon-mp
----

For additional supported properties, please see <<tracing/01_tracing.adoc#Tracing-config,tracing configuration>>

== Creating custom spans
MicroProfile OpenTracing implementation will add support to simply
add custom spans by annotation. Until we implement this support, you
can configure custom spans as follows (in JAX-RS resources):

[source,java]
----
@Context
io.helidon.webserver.ServerRequest serverRequest;

//...

Span span = GlobalTracer.get()
        .buildSpan("my-operation")
        .asChildOf(serverRequest.spanContext())
        .start();
----

== Trace propagation across services
Automated trace propagation is supported currently only with Jersey client.

Tracing propagation works automatically as long as you execute
the client call in the same thread as the Jersey server side.

_Exceptions that require manual handling_:

- When the resource method is annotated with Fault Tolerance annotations (e.g. `@Fallback`)
- When you use `async()` on the Jersey client request

In such cases, you must provide the SpanContext by hand:
[source,java]
.Tracing propagation with Jersey client (on a different thread)
----
import static io.helidon.tracing.jersey.client.ClientTracingFilter.CURRENT_SPAN_CONTEXT_PROPERTY_NAME;
import static io.helidon.tracing.jersey.client.ClientTracingFilter.TRACER_PROPERTY_NAME;

// ...

Response response = client.target(serviceEndpoint)
    .request()
    // tracer should be provided unless available as GlobalTracer
    .property(TRACER_PROPERTY_NAME, tracer)
    .property(CURRENT_SPAN_CONTEXT_PROPERTY_NAME, spanContext)
    .get();
----

Tracer and SpanContext can be obtained from `ServerRequest` that can be injected into Resource classes:

----
@Context
io.helidon.webserver.ServerRequest serverRequest;

//...

SpanContext spanContext = serverRequest.spanContext();
// optional, you could also use GlobalTracer.get() if it is configured
Tracer tracer = req.webServer().configuration().tracer();
----
