Skip to main content
Version: 3.69.0

Telemetry with Jaeger

Introduction​

Platformatic supports Open Telemetry integration. This allows you to send telemetry data to one of the OTLP compatible servers (see here) over HTTP or gRPC, or to a Zipkin server. Let's show this with Jaeger.

Advanced Setup

For manual OpenTelemetry SDK setup with custom instrumentations or exporters, see the Advanced OpenTelemetry Setup guide.

Jaeger setup​

The quickest way is to use docker:

docker run -d --name jaeger \
-e COLLECTOR_OTLP_ENABLED=true \
-p 16686:16686 \
-p 4317:4317 \
-p 4318:4318 \
jaegertracing/all-in-one:latest

Check that the server is running by opening http://localhost:16686/ in your browser.

OTLP transport selection

The examples below use OTLP over HTTP with http://localhost:4318/v1/traces.

You can also use OTLP over gRPC by setting "protocol": "grpc" (or "transport": "grpc") and changing the URL to http://localhost:4317.

{
"telemetry": {
"applicationName": "test-db",
"exporter": {
"type": "otlp",
"options": {
"protocol": "grpc",
"url": "http://localhost:4317"
}
}
}
}

When using gRPC, do not include /v1/traces in the URL.

Platformatic setup​

We'll test this with a Platformatic Gateway that proxies requests to a Watt Application, which in turn invokes a Platformatic DB Application. In this way we show that the telemetry is propagated from the Gateway throughout the applications and the collected correctly. Let's setup all these components:

Platformatic DB Application​

Create a DB application using npm create wattpm:

mkdir test-db
cd test-db
npm create wattpm

To make it simple, use sqlite and create/apply the default migrations. This DB Application is exposed on port 5042:

Hello YOURNAME, welcome to Platformatic 3.0.0!
? Where would you like to create your project? .
? Which kind of application do you want to create? @platformatic/db
? What is the name of the application? main
? What is the connection string? sqlite://./db.sqlite
? Do you want to create default migrations? yes
? Do you want to use TypeScript? no
? Do you want to create another application? no
? What port do you want to use? 5042

Open the web/main/platformatic.json file and add the telemetry configuration:

  "telemetry": {
"applicationName": "test-db",
"exporter": {
"type": "otlp",
"options": {
"url": "http://localhost:4318/v1/traces"
}
}
}

Finally, start the application:

npm run start

Watt Application​

Create at the same level of test-db another folder for Application and cd into it:

mkdir test-application
cd test-application
npm create wattpm

Then create a service on the 5043 port in the folder using npm create wattpm:

Hello YOURNAME, welcome to Platformatic 3.0.0!
? Where would you like to create your project? .
? Which kind of application do you want to create? @platformatic/service
? What is the name of the application? main
? Do you want to use TypeScript? no
? Do you want to create another application? no
? What port do you want to use? 5043

Open the web/main/platformatic.json file and add the following telemetry configuration (it's exactly the same as DB, but with a different applicationName)

  "telemetry": {
"applicationName": "test-service",
"exporter": {
"type": "otlp",
"options": {
"url": "http://localhost:4318/v1/traces"
}
}
}

We want this application to invoke the DB application, so we need to add a Massimo client for test-db to it:

cd web/main
npm install massimo
npx massimo-cli http://127.0.0.1:5042 --name movies

Then add the url to .env:

PLT_MOVIES_URL=http://127.0.0.1:5042/

Now open routes/root.js and changes as follows:

'use strict'

const { buildOpenAPIClient } = require('massimo')
const { resolve } = require('node:path')

module.exports = async function (fastify, opts) {
const client = await buildOpenAPIClient({
url: process.env.PLT_MOVIES_URL,
path: resolve(__dirname, '../movies/movies.openapi.json'),
fullResponse: false
})

fastify.get('/movies-length', async (request, reply) => {
const movies = await client.getMovies()
return { length: movies.length }
})
}

This code calls movies to get all the movies and returns the length of the array.

Finally, start the application:

npm run start

Platformatic Gateway​

Create at the same level of test-db and test-service another folder for Gateway and cd into it:

mkdir test-gateway
cd test-gateway
npm create wattpm
Hello YOURNAME, welcome to Platformatic 3.0.0!
? Where would you like to create your project? .
? Which kind of application do you want to create? @platformatic/gateway
? What is the name of the application? main
? Do you want to use TypeScript? no
? Do you want to create another application? no
? What port do you want to use? 5044

Open web/main/platformatic.json and change it to the following:

{
"$schema": "https://schemas.platformatic.dev/@platformatic/gateway/3.0.0.json",
"gateway": {
"applications": [
{
"id": "example",
"origin": "http://127.0.0.1:5043",
"openapi": {
"url": "/documentation/json"
}
}
],
"refreshTimeout": 3000
},
"telemetry": {
"applicationName": "test-gateway",
"exporter": {
"type": "otlp",
"options": {
"url": "http://localhost:4318/v1/traces"
}
}
},
"watch": true
}

Note that we just added test-service as origin of the proxied application and added the usual telemetry configuration, with a different applicationName.

Finally, start the gateway:

npm run start

Run the Test​

Check that the gateway is exposing movies-length opening: http://127.0.0.1:5044/documentation/

You should see: image

To add some data, we can POST directly to the DB application (port 5042):

curl -X POST -H "Content-Type: application/json" -d '{"title":"The Matrix"}' http://127.0.0.1:5042/movies
curl -X POST -H "Content-Type: application/json" -d '{"title":"The Matrix Reloaded"}' http://127.0.0.1:5042/movies

Now, let's check that the gateway (port 5044) is working:

curl http://127.0.0.1:5044/movies-length

If the gateway is working correctly, you should see:

{ "length": 2 }

However, the main interest of this example is to show how to use the Platformatic Telemetry, so let's check it. Open the Jaeger UI at http://localhost:16686/ and you should see something like this:

image

Select on the left the test-gateway service and the GET /movies-length operation, click on "Find traces" and you should see something like this:

image

You can then click on the trace and see the details:

image

Note that every time a request is received or client call is done, a new span is started. So we have:

  • One span for the request received by the test-gateway
  • One span for the client call to test-service
  • One span for the request received by test-service
  • One span for the client call to test-db
  • One span for the request received by test-db

All these spans are linked together, so you can see the whole trace.

What if you want to use Zipkin?​

Starting from this example, it's also possible to run the same test using Zipkin. To do so, you need to start the Zipkin server:

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

Then, you need to change the telemetry configuration in all the platformatic.*.json files to the following (only the exporter object is different):

  "telemetry": {
(...)
"exporter": {
"type": "zipkin",
"options": {
"url": "http://127.0.0.1:9411/api/v2/spans"
}
}
}

The zipkin ui is available at http://localhost:9411/