-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
1,104 additions
and
593 deletions.
There are no files selected for viewing
34 changes: 34 additions & 0 deletions
34
docs/src/main/asciidoc/_includes/opentelemetry-config.adoc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
There are no mandatory configurations for the extension to work. | ||
|
||
If you need to change any of the default property values, here is an example on how to configure the default OTLP gRPC Exporter within the application, using the `src/main/resources/application.properties` file: | ||
|
||
[source,properties] | ||
---- | ||
quarkus.application.name=myservice // <1> | ||
quarkus.otel.exporter.otlp.endpoint=http://localhost:4317 // <2> | ||
quarkus.otel.exporter.otlp.headers=authorization=Bearer my_secret // <3> | ||
quarkus.log.console.format=%d{HH:mm:ss} %-5p traceId=%X{traceId}, parentId=%X{parentId}, spanId=%X{spanId}, sampled=%X{sampled} [%c{2.}] (%t) %s%e%n // <4> | ||
# Alternative to the console log | ||
quarkus.http.access-log.pattern="...traceId=%{X,traceId} spanId=%{X,spanId}" // <5> | ||
---- | ||
|
||
<1> All spans created from the application will include an OpenTelemetry `Resource` indicating the telemetry was created by the `myservice` application. If not set, it will default to the artifact id. | ||
<2> gRPC endpoint to send the telemetry. If not set, it will default to `http://localhost:4317`. | ||
<3> Optional gRPC headers commonly used for authentication | ||
<4> Add tracing information into log messages. | ||
<5> You can also only put the trace info into the access log. In this case you must omit the info in the console log format. | ||
|
||
We provide signal agnostic configurations for the connection related properties, meaning that you can use the same properties for both tracing and metrics when you set: | ||
[source,properties] | ||
---- | ||
quarkus.otel.exporter.otlp.endpoint=http://localhost:4317 | ||
---- | ||
If you need different configurations for each signal, you can use the specific properties: | ||
[source,properties] | ||
---- | ||
quarkus.otel.exporter.otlp.traces.endpoint=http://trace-uri:4317 // <1> | ||
quarkus.otel.exporter.otlp.metrics.endpoint=http://metrics-uri:4317 // <2> | ||
---- | ||
<1> The endpoint for the traces exporter. | ||
<2> The endpoint for the metrics exporter. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,308 @@ | ||
//// | ||
This guide is maintained in the main Quarkus repository | ||
and pull requests should be submitted there: | ||
https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc | ||
//// | ||
= Using OpenTelemetry Metrics | ||
include::_attributes.adoc[] | ||
:categories: observability | ||
:summary: This guide explains how your Quarkus application can utilize OpenTelemetry to provide metrics for interactive web applications. | ||
:topics: observability,opentelemetry,metrics | ||
:extensions: io.quarkus:quarkus-opentelemetry | ||
|
||
This guide explains how your Quarkus application can utilize https://opentelemetry.io/[OpenTelemetry] (OTel) to provide | ||
metrics for interactive web applications. | ||
|
||
[NOTE] | ||
==== | ||
- The xref:opentelemetry.adoc[OpenTelemetry Guide] is available with high-level information about OpenTelemetry and for signal independent, common functionality. | ||
- If you search more information about OpenTelemetry Tracing, please refer to the xref:opentelemetry-tracing.adoc[OpenTelemetry Tracing Guide]. | ||
==== | ||
|
||
|
||
== Prerequisites | ||
|
||
:prerequisites-docker-compose: | ||
include::{includes}/prerequisites.adoc[] | ||
|
||
== Architecture | ||
|
||
In this guide, we create a straightforward REST application to demonstrate distributed tracing. | ||
|
||
== Solution | ||
|
||
We recommend that you follow the instructions in the next sections and create the application step by step. | ||
However, you can skip right to the completed example. | ||
|
||
Clone the Git repository: `git clone {quickstarts-clone-url}`, or download an {quickstarts-archive-url}[archive]. | ||
|
||
The solution is located in the `opentelemetry-quickstart` link:{quickstarts-tree-url}/opentelemetry-quickstart[directory]. | ||
|
||
== Creating the Maven project | ||
|
||
First, we need a new project. Create a new project with the following command: | ||
|
||
:create-app-artifact-id: opentelemetry-quickstart | ||
:create-app-extensions: rest,quarkus-opentelemetry | ||
include::{includes}/devtools/create-app.adoc[] | ||
|
||
This command generates the Maven project and imports the `quarkus-opentelemetry` extension, | ||
which includes the default OpenTelemetry support, | ||
and a gRPC span exporter for https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md[OTLP]. | ||
|
||
If you already have your Quarkus project configured, you can add the `quarkus-opentelemetry` extension | ||
to your project by running the following command in your project base directory: | ||
|
||
:add-extension-extensions: opentelemetry | ||
include::{includes}/devtools/extension-add.adoc[] | ||
|
||
This will add the following to your build file: | ||
|
||
[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] | ||
.pom.xml | ||
---- | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-opentelemetry</artifactId> | ||
</dependency> | ||
---- | ||
|
||
[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] | ||
.build.gradle | ||
---- | ||
implementation("io.quarkus:quarkus-opentelemetry") | ||
---- | ||
|
||
=== Examine the Jakarta REST resource | ||
|
||
Create a `src/main/java/org/acme/opentelemetry/MetricResource.java` file with the following content: | ||
|
||
[source,java] | ||
---- | ||
package org.acme.opentelemetry; | ||
import jakarta.ws.rs.GET; | ||
import jakarta.ws.rs.Path; | ||
import jakarta.ws.rs.Produces; | ||
import jakarta.ws.rs.core.MediaType; | ||
import org.jboss.logging.Logger; | ||
@Path("/hello") | ||
public class MetricResource { | ||
private static final Logger LOG = Logger.getLogger(MetricResource.class); | ||
@GET | ||
@Produces(MediaType.TEXT_PLAIN) | ||
public String hello() { | ||
LOG.info("hello"); | ||
return "hello"; | ||
} | ||
} | ||
---- | ||
|
||
Quarkus is not currently producing metrics out of the box. | ||
|
||
=== Create the configuration | ||
|
||
There are no mandatory configurations for the extension to work. | ||
|
||
If you need to change any of the default property values, here is an example on how to configure the default OTLP gRPC Exporter within the application, using the `src/main/resources/application.properties` file: | ||
|
||
[source,properties] | ||
---- | ||
quarkus.application.name=myservice // <1> | ||
quarkus.otel.exporter.otlp.traces.endpoint=http://localhost:4317 // <2> | ||
quarkus.otel.exporter.otlp.traces.headers=authorization=Bearer my_secret // <3> | ||
quarkus.log.console.format=%d{HH:mm:ss} %-5p traceId=%X{traceId}, parentId=%X{parentId}, spanId=%X{spanId}, sampled=%X{sampled} [%c{2.}] (%t) %s%e%n // <4> | ||
# Alternative to the console log | ||
quarkus.http.access-log.pattern="...traceId=%{X,traceId} spanId=%{X,spanId}" // <5> | ||
---- | ||
|
||
<1> All spans created from the application will include an OpenTelemetry `Resource` indicating the span was created by the `myservice` application. If not set, it will default to the artifact id. | ||
<2> gRPC endpoint to send spans. If not set, it will default to `http://localhost:4317`. | ||
<3> Optional gRPC headers commonly used for authentication | ||
<4> Add tracing information into log messages. | ||
<5> You can also only put the trace info into the access log. In this case you must omit the info in the console log format. | ||
|
||
[NOTE] | ||
==== | ||
All configurations have been updated from `quarkus.opentelemetry.\*` -> `quarkus.otel.*` | ||
The legacy configurations are now deprecated but will still work during a transition period. | ||
==== | ||
|
||
=== Disable all or parts of the OpenTelemetry extension | ||
|
||
Once you add the dependency, the extension will be enabled by default but there are a few ways to disable the OpenTelemetry extension globally or partially. | ||
|
||
|=== | ||
|Property name |Default value |Description | ||
|
||
|`quarkus.otel.enabled` | ||
|true | ||
|If false, disable the OpenTelemetry usage at *build* time. | ||
|
||
|`quarkus.otel.sdk.disabled` | ||
|false | ||
|Comes from the OpenTelemetry autoconfiguration. If true, will disable the OpenTelemetry SDK usage at *runtime*. | ||
|
||
|`quarkus.otel.traces.enabled` | ||
|true | ||
|If false, disable the OpenTelemetry tracing usage at *build* time. | ||
|
||
|`quarkus.otel.exporter.otlp.enabled` | ||
|true | ||
|If false will disable the default OTLP exporter at *build* time. | ||
|=== | ||
|
||
If you need to enable or disable the exporter at runtime, you can use the <<sampler>> because it has the ability to filter out all the spans if needed. | ||
|
||
|
||
== Run the application | ||
|
||
First we need to start a system to visualise the OpenTelemetry data. | ||
We have 2 options: | ||
|
||
* Start an all-in-one Grafana OTel LGTM system for traces and metrics. | ||
* Jaeger system just for traces. | ||
|
||
=== Grafana OTel LGTM option | ||
|
||
* Take a look at: xref:observability-devservices-lgtm.adoc[Getting Started with Grafana-OTel-LGTM]. | ||
|
||
This features a Quarkus Dev service including a Grafana for visualizing data, Loki to store logs, Tempo to store traces and Prometheus to store metrics. Also provides and OTel collector to receive the data. | ||
|
||
=== Start the application | ||
|
||
Now we are ready to run our application. If using `application.properties` to configure the tracer: | ||
|
||
include::{includes}/devtools/dev.adoc[] | ||
|
||
or if configuring the OTLP gRPC endpoint via JVM arguments: | ||
|
||
:dev-additional-parameters: -Djvm.args="-Dquarkus.otel.exporter.otlp.traces.endpoint=http://localhost:4317" | ||
include::{includes}/devtools/dev.adoc[] | ||
:!dev-additional-parameters: | ||
|
||
With the OpenTelemetry Collector, the Jaeger system and the application running, you can make a request to the provided endpoint: | ||
|
||
[source,shell] | ||
---- | ||
$ curl http://localhost:8080/hello | ||
hello | ||
---- | ||
|
||
When the first request has been submitted, you will be able to see the tracing information in the logs: | ||
|
||
[source] | ||
---- | ||
10:49:02 INFO traceId=, parentId=, spanId=, sampled= [io.quarkus] (main) Installed features: [cdi, opentelemetry, resteasy-client, resteasy, smallrye-context-propagation, vertx] | ||
10:49:03 INFO traceId=17ceb8429b9f25b0b879fa1503259456, parentId=3125c8bee75b7ad6, spanId=58ce77c86dd23457, sampled=true [or.ac.op.TracedResource] (executor-thread-1) hello | ||
10:49:03 INFO traceId=ad23acd6d9a4ed3d1de07866a52fa2df, parentId=, spanId=df13f5b45cf4d1e2, sampled=true [or.ac.op.TracedResource] (executor-thread-0) hello | ||
---- | ||
|
||
|
||
Then visit the http://localhost:16686[Jaeger UI] to see the tracing information. | ||
|
||
Hit `CTRL+C` or type `q` to stop the application. | ||
|
||
|
||
|
||
=== Resource | ||
|
||
|
||
==== End User attributes | ||
|
||
|
||
== Additional instrumentation | ||
|
||
Some Quarkus extensions will require additional code to ensure traces are propagated to subsequent execution. | ||
These sections will outline what is necessary to propagate traces across process boundaries. | ||
|
||
The instrumentation documented in this section has been tested with Quarkus and works in both standard and native mode. | ||
|
||
=== CDI | ||
|
||
Annotating a method in any CDI aware bean with the `io.opentelemetry.instrumentation.annotations.WithSpan` | ||
annotation will create a new Span and establish any required relationships with the current Trace context. | ||
|
||
Annotating a method in any CDI aware bean with the `io.opentelemetry.instrumentation.annotations.AddingSpanAttributes` will not create a new span but will add annotated method parameters to attributes in the current span. | ||
|
||
If a method is annotated by mistake with `@AddingSpanAttributes` and `@WithSpan` annotations, the `@WithSpan` annotation will take precedence. | ||
|
||
Method parameters can be annotated with the `io.opentelemetry.instrumentation.annotations.SpanAttribute` annotation to | ||
indicate which method parameters should be part of the span. The parameter name can be customized as well. | ||
|
||
Example: | ||
[source,java] | ||
---- | ||
@ApplicationScoped | ||
class SpanBean { | ||
@WithSpan | ||
void span() { | ||
} | ||
@WithSpan("name") | ||
void spanName() { | ||
} | ||
@WithSpan(kind = SERVER) | ||
void spanKind() { | ||
} | ||
@WithSpan | ||
void spanArgs(@SpanAttribute(value = "arg") String arg) { | ||
} | ||
@AddingSpanAttributes | ||
void addArgumentToExistingSpan(@SpanAttribute(value = "arg") String arg) { | ||
} | ||
} | ||
---- | ||
|
||
=== Available OpenTelemetry CDI injections | ||
|
||
As per MicroProfile Telemetry Tracing specification, Quarkus supports the CDI injections of the | ||
following classes: | ||
|
||
* `io.opentelemetry.api.OpenTelemetry` | ||
* `io.opentelemetry.api.trace.Tracer` | ||
* `io.opentelemetry.api.trace.Span` | ||
* `io.opentelemetry.api.baggage.Baggage` | ||
|
||
You can inject these classes in any CDI enabled bean. For instance, the `Tracer` is particularly useful to start custom spans: | ||
|
||
[source,java] | ||
---- | ||
@Inject | ||
Tracer tracer; | ||
... | ||
public void tracedWork() { | ||
Span span = tracer.spanBuilder("My custom span") | ||
.setAttribute("attr", "attr.value") | ||
.setParent(Context.current().with(Span.current())) | ||
.setSpanKind(SpanKind.INTERNAL) | ||
.startSpan(); | ||
// traced work | ||
span.end(); | ||
} | ||
---- | ||
|
||
== Exporters | ||
|
||
|
||
|
||
[[configuration-reference]] | ||
== OpenTelemetry Configuration Reference | ||
|
Oops, something went wrong.