Paulo Henrique de Morais Santiago
11/01/2022, 1:09 PM// tracing.js
'use strict'
const process = require('process');
const opentelemetry = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
const { Resource } = require('@opentelemetry/resources');
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { RedisInstrumentation } = require('@opentelemetry/instrumentation-redis-4');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
const exporterOptions = {
url: '<http://IP-OF-MY-SIGNOZ-COLLECTOR:4318/v1/traces>'
}
const traceExporter = new OTLPTraceExporter(exporterOptions);
const sdk = new opentelemetry.NodeSDK({
traceExporter,
instrumentations: [getNodeAutoInstrumentations()],
resource: new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: 'nodejs-example-app-for-signoz'
})
});
// start redis block
const provider = new NodeTracerProvider();
provider.register();
const redisInstrumentation = new RedisInstrumentation({
dbStatementSerializer: function (cmdName, cmdArgs) {
return [cmdName, ...cmdArgs].join(" ");
},
});
// end redis block
// initialize the SDK and register with the OpenTelemetry API
// this enables the API to record telemetry
sdk.start()
.then(() => console.log('Tracing initialized'))
.catch((error) => console.log('Error initializing tracing', error));
// gracefully shut down the SDK on process exit
process.on('SIGTERM', () => {
sdk.shutdown()
.then(() => console.log('Tracing terminated'))
.catch((error) => console.log('Error terminating tracing', error))
.finally(() => process.exit(0));
});
Vishal Sharma
11/01/2022, 3:34 PMPaulo Henrique de Morais Santiago
11/01/2022, 6:24 PMVishal Sharma
11/02/2022, 1:57 AM[{"columns":["__time","SpanId","TraceId","ServiceName","Name","Kind","DurationNano","TagsKeys","TagsValues","References","Events","HasError"],"events":[[1667353831984,"4be43f91aa677b5b","00000000000000005a9c4d0d42bb4bd0","frontend","HTTP GET","3","295455000",["component","http.status_code","http.url","net/http.reused","net/http.was_idle","opencensus.exporterversion","service.name","client-uuid","http.method","ip","host.name"],["net/http","200","0.0.0.0:8081","true","true","Jaeger-Go-2.30.0","frontend","13ae176b70f37f61","GET","172.19.0.4","88cd39c1b1ef"],["{TraceId=00000000000000005a9c4d0d42bb4bd0, SpanId=67b017fb8f949b7d, RefType=CHILD_OF}"],["{\"name\":\"GetConn\",\"timeUnixNano\":1667353831984879000}","{\"name\":\"GotConn\",\"timeUnixNano\":1667353831984885000}","{\"name\":\"WroteHeaders\",\"timeUnixNano\":1667353831984909000}","{\"name\":\"WroteRequest\",\"timeUnixNano\":1667353831984911000}","{\"name\":\"GotFirstResponseByte\",\"timeUnixNano\":1667353832280238000}","{\"name\":\"PutIdleConn\",\"timeUnixNano\":1667353832280264000}","{\"name\":\"ClosedBody\",\"timeUnixNano\":1667353832280314000}"],false],[1667353831984,"67b017fb8f949b7d","00000000000000005a9c4d0d42bb4bd0","frontend","HTTP GET: /customer","0","295687000",["ip","opencensus.exporterversion","service.name","client-uuid","host.name"],["172.19.0.4","Jaeger-Go-2.30.0","frontend","13ae176b70f37f61","88cd39c1b1ef"],["{TraceId=00000000000000005a9c4d0d42bb4bd0, SpanId=5a9c4d0d42bb4bd0, RefType=CHILD_OF}"],[],false],[1667353831985,"059b5373638de025","00000000000000005a9c4d0d42bb4bd0","mysql","SQL SELECT","3","294858000",["host.name","ip","opencensus.exporterversion","peer.service","request","service.name","sql.query","client-uuid"],["88cd39c1b1ef","172.19.0.4","Jaeger-Go-2.30.0","mysql","","mysql","SELECT * FROM customer WHERE ],[1667353832314,"5eac6b698809c079","00000000000000005a9c4d0d42bb4bd0","redis","GetDriver","3","9240000",["client-uuid","host.name","ip","opencensus.exporterversion","param.driverID","service.name"],["619d567fd07605c0","88cd39c1b1ef","172.19.0.4","Jaeger-Go-2.30.0","T785299C","redis"],["{TraceId=00000000000000005a9c4d0d42bb4bd0, SpanId=16a51c92fefbfae8, RefType=CHILD_OF}"],[],false],[1667353832323,"32cae8380b8241de","00000000000000005a9c4d0d42bb4bd0","redis","GetDriver","3","28749000",["opencensus.exporterversion","param.driverID","service.name","client-uuid","host.name","ip"],["Jaeger-Go-2.30.0","T744257C","redis","619d567fd07605c0","88cd39c1b1ef","172.19.0.4"],["{TraceId=00000000000000005a9c4d0d42bb4bd0, SpanId=16a51c92fefbfae8, RefType=CHILD_OF}"],["{\"name\":\"redis 19.0.4","Jaeger-Go-2.30.0","4bc856f7c150ca8f","/route?dropoff=728%2C326\u0026pickup=698%2C555","route","GET"],["{TraceId=00000000000000005a9c4d0d42bb4bd0, SpanId=3f22ba1a010ee296, RefType=CHILD_OF}"],["{\"name\":\"HTTP request received\",\"timeUnixNano\":1667353832505822000,\"attributeMap\":{\"level\":\"info\",\"method\":\"GET\",\"url\":\"/route?dropoff=728%2C326\\u0026pickup=698%2C555\"}}"],false],64775000,\"attributeMap\":{\"level\":\"info\"}}","{\"name\":\"Dispatch "172.19.0.4","Jaeger-Go-2.30.0","T719697C","redis","619d567fd07605c0","88cd39c1b1ef"],["{TraceId=00000000000000005a9c4d0d42bb4bd0, SpanId=16a51c92fefbfae8, RefType=CHILD_OF}"],[],false]]}]
Paulo Henrique de Morais Santiago
11/02/2022, 2:46 PMhttp.route
/cached-users
http.status_text
NOT MODIFIED
telemetry.sdk.name
opentelemetry
process.command
/home/application/current/appwithcaching.js
process.pid
1
process.runtime.version
18.12.0
http.method
GET
http.url
<http://nodejs-example-app-for-signoz.apps.tsuru.gcp.i.globo/cached-users>
net.host.port
8888
net.transport
ip_tcp
telemetry.sdk.version
1.7.0
process.runtime.name
nodejs
http.user_agent
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36
net.peer.port
46308
http.target
/cached-users
telemetry.sdk.language
nodejs
http.flavor
1.1
http.status_code
304
net.host.name
nodejs-example-app-for-signoz.apps.tsuru.gcp.i.globo
net.peer.ip
::ffff:100.88.12.91
net.host.ip
::ffff:100.88.24.125
process.executable.name
node
service.name
nodejs-example-app-for-signoz
http.client_ip
10.254.137.80
http.host
nodejs-example-app-for-signoz.apps.tsuru.gcp.i.globo
process.command_line
/home/ubuntu/.nvm/versions/node/v18.12.0/bin/node /home/application/current/appwithcaching.js
process.runtime.description
Node.js
Vishal Sharma
11/02/2022, 2:48 PMPaulo Henrique de Morais Santiago
11/02/2022, 2:49 PMtelemetry.sdk.version
1.7.0
process.runtime.version
18.12.0
service.name
nodejs-example-app-for-signoz
telemetry.sdk.name
opentelemetry
process.executable.name
node
process.runtime.description
Node.js
telemetry.sdk.language
nodejs
http.route
/
process.command
/home/application/current/appwithcaching.js
process.command_line
/home/ubuntu/.nvm/versions/node/v18.12.0/bin/node /home/application/current/appwithcaching.js
process.runtime.name
nodejs
express.name
query
express.type
middleware
process.pid
1
app.get('/cached-users', (req, res) => {
try {
client.get('users', (err, data) => {
if (err) {
console.error(err);
throw err;
}
if (data) {
console.log('Users retrieved from Redis');
res.status(200).send(JSON.parse(data));
} else {
axios.get(`${USERS_API}`).then(function (response) {
const users = response.data;
client.setex('users', 600, JSON.stringify(users));
console.log('Users retrieved from the API');
res.status(200).send(users);
});
}
});
} catch (err) {
res.status(500).send({ error: err.message });
}
});
Vishal Sharma
11/02/2022, 2:52 PMPaulo Henrique de Morais Santiago
11/02/2022, 2:52 PMconst redis = require('redis');
Vishal Sharma
11/02/2022, 2:55 PMPaulo Henrique de Morais Santiago
11/02/2022, 2:55 PMVishal Sharma
11/02/2022, 2:56 PMPaulo Henrique de Morais Santiago
11/02/2022, 2:57 PMVishal Sharma
11/02/2022, 2:57 PMPaulo Henrique de Morais Santiago
11/02/2022, 2:59 PMnet.host.name
nodejs-example-app-for-signoz.apps.tsuru.gcp.i.globo
net.host.port
8888
net.peer.ip
::ffff:100.88.12.91
process.runtime.description
Node.js
telemetry.sdk.name
opentelemetry
http.status_text
NOT MODIFIED
http.status_code
304
http.url
<http://nodejs-example-app-for-signoz.apps.tsuru.gcp.i.globo/cached-users>
http.host
nodejs-example-app-for-signoz.apps.tsuru.gcp.i.globo
net.host.ip
::ffff:100.88.8.110
process.pid
1
process.runtime.name
nodejs
http.flavor
1.1
http.method
GET
process.command
/home/application/current/appwithcaching-ioredis.js
service.name
nodejs-example-app-for-signoz
http.client_ip
10.254.137.80
telemetry.sdk.version
1.7.0
net.peer.port
35052
process.command_line
/home/ubuntu/.nvm/versions/node/v18.12.0/bin/node /home/application/current/appwithcaching-ioredis.js
process.runtime.version
18.12.0
telemetry.sdk.language
nodejs
http.user_agent
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36
http.target
/cached-users
net.transport
ip_tcp
process.executable.name
node
http.route
/cached-users
Vishal Sharma
11/02/2022, 4:09 PMPaulo Henrique de Morais Santiago
11/02/2022, 4:12 PMconst axios = require('axios');
const express = require('express');
const Redis = require('ioredis');
const redis = new Redis({
host: 'REDISHOST',
port: 6379,
password: 'REDIS_PASSWORD'
});
const PORT = process.env.PORT || "8080";
const USERS_API = '<https://jsonplaceholder.typicode.com/users/>'; // public fake api
const USERS_API2 = '<https://mocki.io/v1/d4867d8b-b5d5-4a48-a4ab-79131b5809b8>'; // public fake api
const app = express();
app.get("/", (req, res) => {
res.send("Hello World");
});
app.get("/page1", (req, res) => {
res.send("Hello page1");
});
app.get("/page2", (req, res) => {
res.send("Hello page2");
});
app.get("/healthcheck", (req, res) => {
res.send("ok");
});
app.get('/users', (req, res) => {
try {
axios.get(`${USERS_API}`).then(function (response) {
const users = response.data;
console.log('Users retrieved from the API');
res.status(200).send(users);
});
} catch (err) {
res.status(500).send({ error: err.message });
}
});
app.get('/user2', (req, res) => {
try {
axios.get(`${USERS_API2}`).then(function (response) {
const users = response.data;
console.log('Users retrieved from the API');
res.status(200).send(users);
});
} catch (err) {
res.status(500).send({ error: err.message });
}
});
app.get('/cached-users', (req, res) => {
try {
redis.get('users', (err, data) => {
if (err) {
console.error(err);
throw err;
}
if (data) {
console.log('Users retrieved from Redis');
res.status(200).send(JSON.parse(data));
} else {
axios.get(`${USERS_API}`).then(function (response) {
const users = response.data;
redis.setex('users', 600, JSON.stringify(users));
console.log('Users retrieved from the API');
res.status(200).send(users);
});
}
});
} catch (err) {
res.status(500).send({ error: err.message });
}
});
app.listen(parseInt(PORT, 10), () => {
console.log(`Listening for requests on <http://localhost>:${PORT}`);
});
Vishal Sharma
11/02/2022, 4:13 PM