• Stars
    star
    106
  • Rank 325,871 (Top 7 %)
  • Language
    JavaScript
  • License
    Apache License 2.0
  • Created over 7 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A self-guided OpenTracing walkthrough / demo project

MicroDonuts: An OpenTracing Walkthrough

Welcome to MicroDonuts! This is a sample application and OpenTracing walkthrough, written in Java.

OpenTracing is a vendor-neutral, open standard for distributed tracing. To learn more, check out opentracing.io, and try the walkthrough below!

Note that there are two git branches of note here.

  • git checkout master illustrates a trivial multi-service app with cross-service tracing via OpenTracing
  • git checkout no-tracing removes the tracing instrumentation, allowing the reader to add it in themselves

Step 0: Setup MicroDonuts

Getting it

Clone this repository and build the jar file (for this, Maven must be installed):

git clone [email protected]:opentracing-contrib/java-opentracing-walkthrough.git
cd java-opentracing-walkthrough/microdonuts
mvn package

Docker image

From the main directory:

cd java-opentracing-walkthrough/microdonuts
mvn package
cd ..
docker build . -t microdonuts

Running

Locally

MicroDonuts has two server components, API and Kitchen, which communicate each other over HTTP - they are, however, part of the same process:

cd java-opentracing-walkthrough/microdonuts
mvn package exec:exec

Docker

docker run -p 10001:10001 microdonuts

Accessing

In your web browser, navigate to http://127.0.0.1:10001 and order yourself some ยต-donuts.

Pick a Tracer

Several OpenTracing-compatible Tracer implementations are supported out-of-the-box for convenience. Others can be added easily with a local change to App.java.

Jaeger

To run Jaeger locally (via Docker):

$ docker run -d -p 5775:5775/udp -p 16686:16686 jaegertracing/all-in-one:latest

Then add the following to microdonuts/tracer_config.properties:

tracer=jaeger
jaeger.reporter_host=localhost
jaeger.reporter_port=5775

Note that the all-in-one docker image presents the Jaeger UI at localhost:16686.

Zipkin

To run Zipkin locally (via Docker):

$ docker run -d -p 9411:9411 openzipkin/zipkin

Then add the following to microdonuts/tracer_config.properties:

tracer=zipkin
zipkin.reporter_host=localhost
zipkin.reporter_port=9411

Note that the all-in-one docker image presents the Zipkin UI at localhost:9411.

LightStep

If you have access to LightStep, you will need your access token. Add the following to microdonuts/tracer_config.properties:

tracer=lightstep
lightstep.collector_host=collector.lightstep.com
lightstep.collector_port=443
lightstep.access_token=XXXXXXXXXXXXXXX  // TODO: replace with your token

Step 1: Check out the no-tracing branch

The master branch in this repository has tracing instrumentation added as described below. To maximize your learnings, do a ...

git checkout no-tracing

... to start with a version of the code that's not instrumented yet. The guide below will let you learn-by-doing as you re-introduce that tracing instrumentation.

Step 2: Turnkey Tracing

When you go to add tracing to a system, the best place to start is by installing OpenTracing plugins for the OSS components you are using. Instrumenting your networking libraries, web frameworks, and service clients quickly gives you a lot of information about your distributed system, without requiring you to change a lot of code.

To do this, let's change the startup of the application to include tracing.

Start the GlobalTracer

In OpenTracing, there is a concept of a global tracer for everyone to access, As a convenience, we already have a function configureGlobalTracer that works with the MicroDonuts configuration file. In the main of microdonuts/src/main/java/com/otsample/api/App.java, right after the configuration file was loaded, we add:

        Properties config = loadConfig(args);
        if (!configureGlobalTracer(config, "MicroDonuts"))
            throw new Exception("Could not configure the global tracer");

After this, the tracer will be available globally through io.opentracing.GlobalTracer.get().

Instrument the outgoing HTTP requests

Our api component communicates with the kitchen one over HTTP using the OkHttp library, so we will instrument those requests using a middleware. In microdonuts/src/main/java/com/otsample/api/KitchenConsumer.java, inside the the KitchenConsumer constructor:

    TracingInterceptor tracingInterceptor = new TracingInterceptor(
             GlobalTracer.get(),
             Arrays.asList(SpanDecorator.STANDARD_TAGS));
    client = new OkHttpClient.Builder()
            .addInterceptor(tracingInterceptor)
            .addNetworkInterceptor(tracingInterceptor)
            .build();

Instrument the inbound HTTP kitchen server

Similarly, we will use a middleware to trace the incoming HTTP requests for the kitchen component. In microdonuts/src/main/java/com/otsample/api/KitchenContextHandler.java, inside the constructor do:

    TracingFilter tracingFilter = new TracingFilter(GlobalTracer.get());
    addFilter(new FilterHolder(tracingFilter), "/*", EnumSet.allOf(DispatcherType.class));

After this, the incoming requests to kitchen will be traced, too.

Check it out in your Tracer

Now that we're all hooked up, try ordering some donuts in the browser. You should see the traces appear in your tracer.

Search for traces starting belonging to the MicroDonuts component to see the patterns of requests that occur when you click the order button.

Step 3: Enhance

Now that the components in our system are linked up at the networking level, we can start adding application level tracing by tying multiple network calls together into a single trace.

In MicroDonuts, we'd like to know the time and resources involved with buying a donut, from the moment it is ordered to when it is delivered. Let's add OpenTracing's context to the requests from the api component to the kitchen one. In microdonuts/src/main/java/com/otsample/api/ApiContextHandler.java in OrderServlet do:

        @Override
        public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
        {
            Span orderSpan = GlobalTracer.get().buildSpan("order_span").start();
            request.setAttribute("span", orderSpan);

And then, at the end of this same method:

            Utils.writeJSON(response, statusRes);
            orderSpan.finish();
        }

Here we are creating a top level span that will be the parent of all the traced operations happening when ordering a set of donuts, and after that we store it in our HttpServletRequest object, so we can retrive this information next. In microdonuts/src/main/java/com/otsample/api/KitchenConsumer.java inside addDonut add a TagWrapper instance with the parent span:

    Span parentSpan = (Span) request.getAttribute("span");
    Request req = new Request.Builder()
        .url("http://127.0.0.1:10001/kitchen/add_donut")
        .post(body)
        .tag(new TagWrapper(parentSpan.context())) 
        .build();

This way, we are marking these requests as children of our main Span, and they will appear in the tracer properly organized, as belonging to the same operation.

And we're done! Buy some donuts, check out the spans under the MicroDonuts component and notice how the order and polling requests are now grouped under a single span, with timing information for the entire operation.

Step 4: Have fun

If you still have time, try to trace other things and/or improve the instrumentation. For example:

  • Maybe we would like to have an overarching span when calling the status operation (the one polling the status of the order) at the StatusServlet and the KitchenConsumer.getDonuts call, like we did in the previous step with OrderServlet and KitchenConsumer.addDonut
  • The automatic span names are sometimes overly general (e.g., "post"): try to override them with something more revealing
  • Add span tags to make traces more self-descriptive and contextualized

Thanks for playing, and welcome to OpenTracing!

Thanks for joining us in this walkthrough! Hope you enjoyed it. If you did, let us know, and consider spreading the love!

A great way to get the feel for OpenTracing is to try your hand at instrumenting the OSS servers, frameworks, and client libraries that we all share. If you make one, consider adding it to the growing ecosystem at http://github.com/opentracing-contrib. If you maintain a library yourself, plase consider adding built-in OT support.

We also need walkthroughs for languages other than Golang. Feel free to reuse the client, protobufs, and other assets from here if you'd like to make one.

For a more detailed explanation of OSS Instrumentation, check out the Turnkey Tracing proposal at http://bit.ly/turnkey-tracing.

Aloha!

More Repositories

1

opentracing-specification-zh

OpenTracingๆ ‡ๅ‡†๏ผˆไธญๆ–‡็‰ˆ๏ผ‰ `zh` (Chinese) translation of the opentracing/specification
929
star
2

nginx-opentracing

NGINX plugin for OpenTracing
C++
499
star
3

java-spring-cloud

Distributed tracing for Spring Boot, Cloud and other Spring projects
Java
386
star
4

csharp-netcore

OpenTracing instrumentation for .NET Core 3.1 & .NET 6+ apps
C#
261
star
5

java-spring-jaeger

Java
243
star
6

go-stdlib

OpenTracing instrumentation for packages in the Go stdlib
Go
217
star
7

java-specialagent

Automatic instrumentation for 3rd-party libraries in Java applications with OpenTracing.
Java
185
star
8

python-flask

OpenTracing instrumentation for the Flask microframework
Python
135
star
9

java-kafka-client

OpenTracing Instrumentation for Apache Kafka Client
Java
120
star
10

java-spring-web

OpenTracing Spring Web instrumentation
Java
106
star
11

python-django

OpenTracing instrumentation for the Django framework
Python
105
star
12

java-jdbc

OpenTracing Instrumentation for JDBC
Java
81
star
13

java-jfr-tracer

This is a delegating tracer to be used with OpenTracing. It records span information into the JFR, allowing very deep tracing.
Java
77
star
14

go-grpc

Package otgrpc provides OpenTracing support for any gRPC client or server.
Go
71
star
15

go-gin

OpenTracing middleware for gin-gonic
Go
64
star
16

python-grpc

Python
53
star
17

java-grpc

OpenTracing Instrumentation for gRPC
Java
52
star
18

csharp-grpc

OpenTracing Instrumentation for gRPC
C#
43
star
19

java-agent

Agent-based OpenTracing instrumentation in Java
Java
40
star
20

javascript-express

OpenTracing middleware for express
JavaScript
39
star
21

java-jaxrs

OpenTracing Java JAX-RS instrumentation
Java
37
star
22

java-concurrent

OpenTracing-aware helpers related to java.util.concurrent
Java
36
star
23

meta

A meta-repository for OpenTracing contributions
34
star
24

java-redis-client

OpenTracing Instrumentation for Redis Client
Java
33
star
25

go-zap

Integration with go.uber.org/zap
Go
33
star
26

java-metrics

Java
31
star
27

go-amqp

AMQP instrumentation in Go
Go
29
star
28

scala-concurrent

OpenTracing instrumentation for scala.concurrent package
Scala
24
star
29

opentracing-erlang

Open Tracing Toolkit for ERlang
Erlang
24
star
30

java-web-servlet-filter

OpenTracing Java Web Servlet Filter Instrumentation
Java
23
star
31

java-xray-tracer

Java OpenTracing implementation backed by AWS X-Ray
Java
23
star
32

java-okhttp

OpenTracing Okhttp client instrumentation
Java
23
star
33

java-vertx-web

OpenTracing instrumentation for Vert.x web package
Java
21
star
34

python-redis

OpenTracing instrumentation for the Redis client.
Python
20
star
35

ruby-rack-tracer

Ruby
20
star
36

java-span-reporter

A Tracer implementation that writes all instrumented data to a conventional Logger
Java
20
star
37

goredis

a middleware for go-redis/redis to use opentracing
Go
18
star
38

java-spring-rabbitmq

OpenTracing RabbitMQ instrumentation
Java
18
star
39

java-spring-zipkin

Java
16
star
40

python-sqlalchemy

OpenTracing instrumentation for SQLAlchemy
Python
16
star
41

scala-akka

OpenTracing instrumentation for Scala Akka
Scala
16
star
42

java-dropwizard

(deprecated) OpenTracing instrumentation for the Dropwizard framework
Java
15
star
43

java-aws-sdk

OpenTracing instrumentation for AWS SDK
Java
15
star
44

java-specialagent-demo

A SpecialAgent Demo
Java
13
star
45

java-mongo-driver

OpenTracing Instrumentation for Mongo Driver
Java
12
star
46

java-reactor

OpenTracing instrumentation for Reactor
Java
12
star
47

javascript-tracedpromise

JavaScript
12
star
48

python-elasticsearch

OpenTracing instrumentation for the the Python's Elasticsearch clients
Python
11
star
49

java-apache-httpclient

OpenTracing Apache HttpClient instrumentation
Java
11
star
50

python-requests

OpenTracing instrumentation for Requests
Python
10
star
51

echo

a middleware for the echov4 web framework to use opentracing
Go
10
star
52

go-aws-sdk

OpenTracing support for AWS SDK in Go
Go
10
star
53

java-thrift

OpenTracing instrumentation for Apache Thrift
Java
10
star
54

java-rabbitmq-client

OpenTracing Instrumentation for RabbitMQ Client
Java
9
star
55

python-tornado

OpenTracing instrumentation for Tornado
Python
9
star
56

java-rxjava

OpenTracing Instrumentation for RxJava
Java
9
star
57

examples

Examples (some trivial) for opentracing.io
Go
9
star
58

java-elasticsearch-client

OpenTracing Instrumentation for Elasticsearch Client
Java
8
star
59

go-observer

an Observer API for OpenTracing-Go Tracers
Go
8
star
60

java-examples

tested examples of common instrumentation patterns
Java
7
star
61

ruby-faraday-tracer

Ruby
7
star
62

java-tracerresolver

Resolver API for OpenTracing Tracer implementations.
Java
6
star
63

java-akka

Java
6
star
64

go-gorilla

OpenTracing instrumentation for Gorilla framework (github.com/gorilla)
Go
6
star
65

java-spanmanager

Current span management for Java
Java
6
star
66

java-jms

OpenTracing Instrumentation for JMS API
Java
5
star
67

csharp-decorators

C#
5
star
68

perfevents

Perf metrics library for go and java applications
Go
5
star
69

beego

a middleware for the beego web framework to use opentracing
Go
5
star
70

java-hprose

OpenTracing instrumentation for the Hprose Remote Object Service Engine
Java
4
star
71

python-pyramid

OpenTracing instrumentation for the Pyramid framework
Python
4
star
72

java-cassandra-driver

OpenTracing instrumentation for Cassandra Driver
Java
4
star
73

java-globaltracer

(deprecated) Global OpenTracing Tracer resolution for Java
Java
4
star
74

java-asynchttpclient

OpenTracing Instrumentation for https://github.com/AsyncHttpClient/async-http-client
Java
4
star
75

cpp-grpc

OpenTracing Instrumentation for gRPC
4
star
76

python-cassandra

OpenTracing instrumentation for cassandra-driver
Python
3
star
77

java-p6spy

OpenTracing Instrumentation for P6Spy
Java
3
star
78

java-redisson

OpenTracing Instrumentation for Redisson
Java
3
star
79

java-spring-messaging

OpenTracing Spring Messaging instrumentation
Java
3
star
80

java-jdbi

OpenTracing instrumentation for the JDBI database framework
Java
3
star
81

java-benchmarks

Set of benchmarks to assess the performance of different OpenTracing components and/or libraries
Java
3
star
82

python-examples

tester examples of common instrumentation patterns
Python
3
star
83

java-spring-tracer-configuration

Java
2
star
84

python-pymongo

OpenTracing instrumentation for PyMongo
Python
2
star
85

java-cdi

Java
2
star
86

go-restful

OpenTracing instrumentation for the go-restful framework
Go
2
star
87

java-neo4j-driver

OpenTracing instrumentation for Neo4j Driver
Java
2
star
88

java-ejb

Java
2
star
89

java-solr-client

OpenTracing Instrumentation for Solr Client
Java
2
star
90

python-gevent

OpenTracing instrumentation for gevent
Python
2
star
91

java-grizzly-http-server

OpenTracing instrumentation for Grizzly HttpServer
Java
1
star
92

ruby-redis-instrumentation

Ruby
1
star
93

java-grizzly-ahc

OpenTracing instrumentation for Grizzly AsyncHttpClient
Java
1
star
94

java-memcached-client

OpenTracing Instrumentation for Memcached Client
Java
1
star
95

ruby-mongodb-instrumentation

Ruby
1
star
96

java-opentelemetry-bridge

OpenTracing-OpenTelemetry Tracer Bridge
Java
1
star
97

java-common

Common utilities for OpenTracing Instrumentation Plugins.
Java
1
star
98

java-hazelcast

OpenTracing Instrumentation for Hazelcast
Java
1
star
99

java-api-extensions

This repository contains API extensions for use with the core Tracer and Span APIs.
Java
1
star
100

java-opentracing-jaeger-bundle

Java
1
star