Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/openliberty/guide-microprofile-opentracing
A guide on how to enable and customize tracing of JAX-RS and non-JAX-RS methods by using MicroProfile OpenTracing: https://openliberty.io/guides/microprofile-opentracing.html
https://github.com/openliberty/guide-microprofile-opentracing
Last synced: 3 months ago
JSON representation
A guide on how to enable and customize tracing of JAX-RS and non-JAX-RS methods by using MicroProfile OpenTracing: https://openliberty.io/guides/microprofile-opentracing.html
- Host: GitHub
- URL: https://github.com/openliberty/guide-microprofile-opentracing
- Owner: OpenLiberty
- License: other
- Created: 2018-02-02T20:11:19.000Z (almost 7 years ago)
- Default Branch: prod
- Last Pushed: 2024-09-12T15:01:03.000Z (4 months ago)
- Last Synced: 2024-09-13T02:56:14.608Z (4 months ago)
- Language: Java
- Homepage:
- Size: 751 KB
- Stars: 11
- Watchers: 6
- Forks: 16
- Open Issues: 0
-
Metadata Files:
- Readme: README.adoc
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
// Copyright (c) 2017, 2022 IBM Corporation and others.
// Licensed under Creative Commons Attribution-NoDerivatives
// 4.0 International (CC BY-ND 4.0)
// https://creativecommons.org/licenses/by-nd/4.0/
//
// Contributors:
// IBM Corporation
:projectid: microprofile-opentracing
:page-layout: guide-multipane
:page-duration: 20 minutes
:page-guide-category: microprofile
:page-essential: false
:page-releasedate: 2018-03-16
:page-description: Explore how to enable and customize tracing of JAX-RS and non-JAX-RS methods by using Zipkin and MicroProfile OpenTracing.
:page-tags: ['MicroProfile']
:page-permalink: /guides/{projectid}
:page-related-guides: ['cdi-intro', 'microprofile-opentracing-jaeger']
:common-includes: https://raw.githubusercontent.com/OpenLiberty/guides-common/prod
:page-seo-title: Enabling distributed tracing in Java microservices using Eclipse MicroProfile OpenTracing and the Zipkin tracing system.
:page-seo-description: A getting started tutorial and an example on how to enable distributed tracing in Java microservices to easily trace request flows that span multiple resources by using MicroProfile OpenTracing and Zipkin tracing system.
:source-highlighter: prettify
:guide-author: Open Liberty
= Enabling distributed tracing in microservices with Zipkin[.hidden]
NOTE: This repository contains the guide documentation source. To view the guide in published form, view it on the https://openliberty.io/guides/{projectid}.html[Open Liberty website].Explore how to enable and customize tracing of JAX-RS and non-JAX-RS methods by using MicroProfile OpenTracing and the Zipkin tracing system.
:inv-url: http://localhost:9081/inventory/systems
:inv-url-docker: http://localhost:9080/inventory/systems
:sys-url: http://localhost:9080/system/properties
:zipkin-url: http://localhost:9411== What you'll learn
You'll learn how to enable automatic tracing for JAX-RS methods and how to create custom tracers for non-JAX-RS methods by using MicroProfile OpenTracing.
OpenTracing is a standard API for instrumenting microservices for distributed tracing. Distributed tracing helps troubleshoot microservices by examining and logging requests as they propagate through a distributed system. Distributed tracing allows developers to tackle the otherwise difficult task of debugging these requests. Without a distributed tracing system in place, analyzing the workflows of operations becomes difficult. Pinpointing when and where a request is received and when responses are sent becomes difficult.
MicroProfile OpenTracing enables distributed tracing in microservices without adding any explicit distributed tracing code to the application. Note that the MicroProfile OpenTracing specification does not address the problem of defining, implementing, or configuring the underlying distributed tracing system. Rather, the specification makes it easier to instrument services with distributed tracing given an existing distributed tracing system.
You'll configure the provided `inventory` and `system` services to use distributed tracing with MicroProfile OpenTracing. You'll run these services in two separate JVMs made of two server instances to demonstrate tracing in a distributed environment. If all the components were to run on a single server, then any logging software would do the trick.
// =================================================================================================
// Getting Started
// =================================================================================================
[role='command']
include::{common-includes}/gitclone.adoc[]For this guide, Zipkin is used as the distributed tracing system. You can find the installation instructions for Zipkin at the Zipkin https://zipkin.io/pages/quickstart.html[quickstart page^]. You're not required to use Zipkin. You may choose to use another tracing system. However, this guide is written using Zipkin. If you use a different tracing system, the required instructions may differ.
// static guide instructions:
ifndef::cloud-hosted[]
Before you continue, confirm your Zipkin server is up and running. By default, Zipkin can be found at the {zipkin-url}[{zipkin-url}^] URL.
endif::[]// cloud-hosted guide instructions:
ifdef::cloud-hosted[]
Start Zipkin by running the following command:
```bash
docker run -d --name zipkin -p 9411:9411 openzipkin/zipkin
```Before you continue, make sure your Zipkin server is up and running. Click the following button to visit Zipkin service at port ***9411***.
::startApplication{port="9411" display="external" name="Visit Zipkin" route="/"}
endif::[]=== Try what you'll build
The `finish` directory in the root directory of this guide contains two services that are configured to use MicroProfile OpenTracing. Give them a try before you continue.
To try out the services, navigate to the `finish` directory and run the Maven `install` phase to build the services
[role='command']
```
cd finish
mvn install
```Then, run the Maven `liberty:start-server` goal to start them in two Open Liberty servers:
[role='command']
```
mvn liberty:start-server
```// static guide instructions:
ifndef::cloud-hosted[]
Make sure your Zipkin server is running and point your browser to the {inv-url}/localhost[{inv-url}/localhost^] URL. When you visit this URL, you make two HTTP GET requests, one to the `system` service and one to the `inventory` service. Both of these requests are configured to be traced, so a new trace will be recorded in Zipkin. Visit the {zipkin-url}[{zipkin-url}^] URL or another location where you configured Zipkin to run. Run an empty query and sort the traces by latest start time first.
endif::[]// cloud-hosted guide instructions:
ifdef::cloud-hosted[]
Make sure your Zipkin server is running and run the following curl command:
```bash
curl -s http://localhost:9081/inventory/systems/localhost | jq
```When you make this curl request, you make two HTTP GET requests, one to the ***system*** service and one to the ***inventory*** service. Because tracing is configured for both these requests, a new trace is recorded in Zipkin. Visit the Zipkin service. Run an empty query and sort the traces by latest start time first.
::startApplication{port="9411" display="external" name="Visit Zipkin" route="/"}
endif::[]Verify that the new trace contains three spans with the following names:
* `get:io.openliberty.guides.inventory.inventoryresource.getpropertiesforhost`
* `get:io.openliberty.guides.system.systemresource.getproperties`
* `add() span`You can inspect each span by clicking it to reveal more detailed information, such as the time at which the request was received and the time at which a response was sent back.
If you examine the other traces, you might notice a red trace entry, which indicates the span caught an error. In this case, one of the tests accesses the `/inventory/systems/badhostname` endpoint, which is invalid, so an error is thrown. This behavior is expected.
When you're done checking out the services, stop both Open Liberty servers using the Maven `liberty:stop-server` goal:
[role='command']
```
mvn liberty:stop-server
```// =================================================================================================
// Running the services
// =================================================================================================== Running the services
Navigate to the `start` directory to begin.
//cloud hosted instructions
ifdef::cloud-hosted[]
```bash
cd /home/project/guide-microprofile-opentracing/start
```
endif::[]You'll need to start the services to see basic traces appear in Zipkin. So, before you proceed, build and start the provided `system` and `inventory` services in the starting project by running the Maven `install` goal:
[role='command']
```
mvn install
```Then, run the `liberty:start-server` goal:
[role='command']
```
mvn liberty:start-server
```// static guide instructions:
ifndef::cloud-hosted[]
When the servers start, you can find the `system` and `inventory` services at the following URLs:* {sys-url}[{sys-url}^]
* {inv-url}[{inv-url}^]
endif::[]// cloud-hosted guide instructions:
ifdef::cloud-hosted[]
When the servers start, you can access the **system** service by running the following curl command:
```bash
curl -s http://localhost:9080/system/properties | jq
```and access the ***inventory*** service by running the following curl command:
```bash
curl -s http://localhost:9081/inventory/systems | jq
```
endif::[]// =================================================================================================
// Existing Tracer implementation
// =================================================================================================== Existing Tracer implementation
To collect traces across your systems, you need to implement the OpenTracing `Tracer` interface. For this guide, you can access a bare-bones `Tracer` implementation for the Zipkin server in the form of a user feature for Open Liberty.
This feature is already configured for you in your [hotspot file=1]`pom.xml` and [hotspot file=0]`server.xml` files. It's automatically downloaded and installed into each service when you run a Maven build. You can find the [hotspot=zipkinUsr file=0]`opentracingZipkin` feature enabled in your [hotspot file=0]`server.xml` file.
The [hotspot=download file=1]`download-maven-plugin` Maven plug-in in your `pom.xml` downloads and installs the [hotspot=zipkinUsr file=0]`opentracingZipkin` feature.
If you want to install this feature yourself, see https://www.ibm.com/docs/en/was-liberty/base?topic=environment-enabling-distributed-tracing[Enabling distributed tracing^] in IBM Documentation.
// file 0
server.xml
[source, xml, linenums, role='code_column']
----
include::finish/inventory/src/main/liberty/config/server.xml[]
----// file 1
pom.xml
[source, xml, linenums, role='code_column']
----
include::finish/inventory/pom.xml[]
----// =================================================================================================
// Enabling distributed tracing
// =================================================================================================== Enabling distributed tracing
The MicroProfile OpenTracing feature enables tracing of all JAX-RS methods by default. To further control and customize these traces, use the `@Traced` annotation to enable and disable tracing of particular methods. You can also inject a custom `Tracer` object to create and customize spans.
=== Enabling distributed tracing without code instrumentation
Because tracing is enabled by default for all JAX-RS methods, you need to enable only the [hotspot=mpOpenTracing file=0]`mpOpenTracing` feature and the [hotspot=zipkinUsr file=0]`usr:opentracingZipkin` user feature in the `server.xml` file to see some basic traces in Zipkin.
Both of these features are already enabled in the `inventory` and `system` configuration files.
Make sure your services are running. Then, point your browser to any of their endpoints and check your Zipkin server for traces.
// file 0
server.xml
[source, xml, linenums, role='code_column']
----
include::finish/inventory/src/main/liberty/config/server.xml[]
----=== Enabling explicit distributed tracing
The [hotspot=Traced file=0]`@Traced` annotation defines explicit span creation for specific classes and methods. If you place the annotation on a class, then it's automatically applied to all methods within that class. If you place the annotation on a method, then it overrides the class annotation if one exists.
Enable tracing of the [hotspot=list file=0]`list()` non-JAX-RS method by adding the [hotspot=Traced file=0]`@Traced` annotation to the method.
[role="code_command hotspot file=0", subs="quotes"]
----
#Replace the `InventoryManager` class.#
`inventory/src/main/java/io/openliberty/guides/inventory/InventoryManager.java`
----// file 0
InventoryManager.java
[source, Java, linenums, role='code_column hide_tags=copyright,customTracer,Add']
----
include::finish/inventory/src/main/java/io/openliberty/guides/inventory/InventoryManager.java[]
----The [hotspot=Traced file=0]`@Traced` annotation can be configured with the following two parameters:
* The `value=[true|false]` parameter indicates whether a particular class or method is traced. For example, while all JAX-RS methods are traced by default, you can disable their tracing by using the `@Traced(false)` annotation. This parameter is set to `true` by default.
* The `operationName=` parameter indicates the name of the span that is assigned to the particular method that is traced. If you omit this parameter, the span will be named with the following form: `..`. If you use this parameter at a class level, then all methods within that class will have the same span name unless they're explicitly overridden by another `@Traced` annotation.Next, run the following command from the `start` directory to recompile your services.
[role='command']
```
mvn compile
```// static guide instructions:
ifndef::cloud-hosted[]
Visit the {inv-url}[{inv-url}^] URL, check your Zipkin server, and sort the traces by newest first.
endif::[]// cloud-hosted guide instructions:
ifdef::cloud-hosted[]
Run the following curl command, check your Zipkin server, and sort the traces by newest first:
```bash
curl -s http://localhost:9081/inventory/systems | jq
```
endif::[]Look for a new trace record that is two spans long with one span for the [hotspot=listContents file=1]`listContents()` JAX-RS method in the [hotspot file=1]`InventoryResource` class and another span for the [hotspot=list file=0]`list()` method in the [hotspot file=0]`InventoryManager` class. Verify that these spans have the following names:
* `get:io.openliberty.guides.inventory.inventoryresource.listcontents`
* `inventorymanager.list`Now, disable tracing on the `InventoryResource` class by setting [hotspot=Traced-false file=1]`@Traced(false)` on the [hotspot=listContents file=1]`listContents()` JAX-RS method.
[role="code_command hotspot file=1", subs="quotes"]
----
#Replace the `InventoryResource` class.#
`inventory/src/main/java/io/openliberty/guides/inventory/InventoryResource.java`
----// file 1
InventoryResource.java
[source, Java, linenums, role='code_column hide_tags=copyright']
----
include::finish/inventory/src/main/java/io/openliberty/guides/inventory/InventoryResource.java[]
----Again, run the `mvn compile` command from the `start` directory to recompile your services:
[role="command"]
```
mvn compile
```// static guide instructions:
ifndef::cloud-hosted[]
Visit the {inv-url}[{inv-url}^] URL again, check your Zipkin server, and sort the traces by newest first.
endif::[]// cloud-hosted guide instructions:
ifdef::cloud-hosted[]
Run the following curl command again, check your Zipkin server, and sort the traces by newest first:
```bash
curl -s http://localhost:9081/inventory/systems | jq
```
endif::[]Look for a new trace record that is just one span long for the remaining [hotspot=list file=0]`list()` method in the `InventoryManager` class. Verify that this span has the following name:
* `inventorymanager.list`
=== Injecting a custom Tracer object
The MicroProfile OpenTracing specification also makes the underlying OpenTracing `Tracer` instance available. The configured `Tracer` is accessed by injecting it into a bean by using the [hotspot=customTracer file=0]`@Inject` annotation from the Contexts and Dependency Injections API.
After injecting it, the [hotspot=customTracer file=0]`Tracer` will be used to build a [hotspot=span file=0]`Span`. The `Span` will be activated and used in a [hotspot=scope file=0]`Scope`.
[role="code_command hotspot file=0", subs="quotes"]
----
#Replace the `InventoryManager` class.#
`inventory/src/main/java/io/openliberty/guides/inventory/InventoryManager.java`
----// file 0
InventoryManager.java
[source, Java, linenums, role='code_column hide_tags=copyright']
----
include::finish/inventory/src/main/java/io/openliberty/guides/inventory/InventoryManager.java[]
----The [hotspot=scope file=0]`Scope` is used in a [hotspot=Try file=0]`try` block. The [hotspot=Try file=0]`try` block that you see here is called a `try-with-resources` statement, meaning that the [hotspot=scope file=0]`Scope` object is closed at the end of the statement. Defining custom spans inside such statements is a good practice. Otherwise, any exceptions that are thrown before the span is closed will leak the active span. The [hotspot=spanFinish file=0]`finish()` method sets the ending timestamp and records the span.
Next, run the following command from the `start` directory to recompile your services.
[role="command"]
```
mvn compile
```// static guide instructions:
ifndef::cloud-hosted[]
Visit the {inv-url}/localhost[{inv-url}/localhost^] URL, check your Zipkin server, and sort the traces by newest first.
endif::[]// cloud-hosted guide instructions:
ifdef::cloud-hosted[]
Run the following curl command, check your Zipkin server, and sort the traces by newest first:
```bash
curl -s http://localhost:9081/inventory/systems/localhost | jq
```
endif::[]Look for two new trace records, one for the `system` service and one for the `inventory` service. The `system` trace contains one span for the [hotspot=Properties file=1]`getProperties()` method in the [hotspot file=1]`SystemResource` class. The `inventory` trace contains two spans. The first span is for the [hotspot=getPropertiesForHost file=2]`getPropertiesForHost()` method in the [hotspot file=2]`InventoryResource` class. The second span is the custom span that you created around the [hotspot=Add file=0]`add()` call. Verify that all of these spans have the following names:
The `system` trace:
* `get:io.openliberty.guides.system.systemresource.getproperties`
The `inventory` trace:
* `get:io.openliberty.guides.inventory.inventoryresource.getpropertiesforhost`
* `add() span`This simple example shows what you can do with the injected `Tracer` object. More configuration options are available, including setting a timestamp for when a span was created and destroyed. However, these options require an implementation of their own, which does not come as a part of the Zipkin user feature that is provided. In a real-world scenario, implement all the OpenTracing interfaces that you consider necessary, which might include the `SpanBuilder` interface. You can use this interface for span creation and customization, including setting timestamps.
// file 1
SystemResource.java
[source, Java, linenums, role='code_column hide_tags=copyright']
----
include::finish/system/src/main/java/io/openliberty/guides/system/SystemResource.java[]
----// file 2
InventoryResource.java
[source, Java, linenums, role='code_column hide_tags=copyright']
----
include::finish/inventory/src/main/java/io/openliberty/guides/inventory/InventoryResource.java[]
----// =================================================================================================
// Testing the services
// =================================================================================================== Testing the services
No automated tests are provided to verify the correctness of the traces. Manually verify these traces by viewing them on the Zipkin server.
A few tests are included for you to test the basic functionality of the services. If a test failure occurs, then you might have introduced a bug into the code. These tests will run automatically as a part of the Maven build process when you run the `mvn install` command. You can also run these tests separately from the build by using the `mvn verify` command, but first make sure the servers are stopped.
When you're done checking out the services, stop the server by using the Maven
`liberty:stop-server` goal:[role='command']
```
mvn liberty:stop-server
```// cloud-hosted guide instructions:
ifdef::cloud-hosted[]
Stop the Zipkin service by running the following command:
```bash
docker stop zipkin
```
endif::[]// =================================================================================================
// Great work! You're done!
// =================================================================================================== Great work! You're done!
You have just used MicroProfile OpenTracing in Open Liberty to customize how and which traces are delivered to Zipkin.
Feel free to try one of the related MicroProfile guides. They demonstrate additional technologies that you can learn to expand on top of what you built here.
[role="command"]
include::{common-includes}/attribution.adoc[subs="attributes"]