Sample Application
The sample application is a “dice game”: a game coordinator service will ask two (or more) player services for a random number between 1 and 6. The player with the highest number wins.
The first few chapters of this tutorial will focus on the player service, which
is a basic HTTP application, that has an API endpoint /rolldice
which returns
a random number between 1 and 6 on request.
Create and launch the player service
Let’s begin by setting up a new directory with the source code of the player service:
mkdir player-service
cd player-service
Dependencies
In that new directory, run the following command in a terminal window to initialize a new project, and to add all the dependencies needed.
go mod init dice
npm init -y
npm install express
npm init -y
npm install typescript \
ts-node \
@types/node \
express \
@types/express
# initialize typescript
npx tsc --init
Code
The player service consists of two files: an application file for the logic of the HTTP server, and a library file that will handle the dice rolling.
First, create the application file named
with the following code in it:/* main.go */
package main
import (
"log"
"net/http"
)
func main() {
http.HandleFunc("/rolldice", rolldice)
log.Fatal(http.ListenAndServe(":8080", nil))
}
/*app.js*/
const express = require('express');
const { rollTheDice } = require('./dice.js');
const PORT = parseInt(process.env.PORT || '8080');
const app = express();
app.get('/rolldice', (req, res) => {
const rolls = req.query.rolls ? parseInt(req.query.rolls.toString()) : NaN;
if (isNaN(rolls)) {
res
.status(400)
.send("Request parameter 'rolls' is missing or not a number.");
return;
}
res.send(JSON.stringify(rollTheDice(rolls, 1, 6)));
});
app.listen(PORT, () => {
console.log(`Listening for requests on http://localhost:${PORT}`);
});
/*app.ts*/
import express, { Request, Express } from 'express';
import { rollTheDice } from './dice';
const PORT: number = parseInt(process.env.PORT || '8080');
const app: Express = express();
app.get('/rolldice', (req, res) => {
const rolls = req.query.rolls ? parseInt(req.query.rolls.toString()) : NaN;
if (isNaN(rolls)) {
res
.status(400)
.send("Request parameter 'rolls' is missing or not a number.");
return;
}
res.send(JSON.stringify(rollTheDice(rolls, 1, 6)));
});
app.listen(PORT, () => {
console.log(`Listening for requests on http://localhost:${PORT}`);
});
Next, create the library file named
with the following code in it:package main
import (
"io"
"log"
"math/rand"
"net/http"
"strconv"
)
func rolldice(w http.ResponseWriter, r *http.Request) {
roll := 1 + rand.Intn(6)
resp := strconv.Itoa(roll) + "\n"
if _, err := io.WriteString(w, resp); err != nil {
log.Printf("Write failed: %v\n", err)
}
}
/*dice.js*/
function rollOnce(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
function rollTheDice(rolls, min, max) {
const result = [];
for (let i = 0; i < rolls; i++) {
result.push(rollOnce(min, max));
}
return result;
}
module.exports = { rollTheDice };
});
app.listen(PORT, () => {
console.log(`Listening for requests on http://localhost:${PORT}`);
});
/*dice.ts*/
function rollOnce(min: number, max: number) {
return Math.floor(Math.random() * (max - min) + min);
}
export function rollTheDice(rolls: number, min: number, max: number) {
const result: number[] = [];
for (let i = 0; i < rolls; i++) {
result.push(rollOnce(min, max));
}
return result;
}
Test
Build and run the application with the following command
$ node app.js
Listening for requests on http://localhost:8080
$ node app.js
Listening for requests on http://localhost:8080
$ npx ts-node app.ts
Listening for requests on http://localhost:8080
To verify that your player service is running, either open http://localhost:8080/rolldice in your web browser or run the following in the command line:
curl http://localhost:8080/rolldice
For the next sections of the tutorial all you need is the player service, so you can continue with setting up the OpenTelemetry SDK.
You can come back later here, when you will learn how to correlate telemetry across services.
Create and launch the game coordinator
For setting up the game coordinator, create another new directory, that lives side by side with the player service:
cd .. # if you are in the player-service directory
mkdir coordinator-service
cd coordinator-service
Dependencies
The game coordinator has the same dependencies. So, you can run the same code to initialize a new project, and to add all the dependencies needed.
go mod init dice
npm init -y
npm install express
npm init -y
npm install typescript \
ts-node \
@types/node \
express \
@types/express
# initialize typescript
npx tsc --init
Code
Create the application file named
with the following code in it:Test
To verify that your coordinator service is running and connecting properly to your one player service, run the following in the command line:
./game-coordinator
Since you only have one player service currently running, you will see something like the following printed to the console:
Player 1 wins: 6
Run multiple player services
To have multiple player compete, go back to the folder of the player service and run a second instance:
$ node app.js
Listening for requests on http://localhost:8080
$ node app.js
Listening for requests on http://localhost:8080
$ npx ts-node app.ts
Listening for requests on http://localhost:8080
Next Step
After you have setup your sample application, you can continue with setting up the OpenTelemetry SDK.
Feedback
Was this page helpful?
Thank you. Your feedback is appreciated!
Please let us know how we can improve this page. Your feedback is appreciated!