Hello Everyone, i`m trying to setting up signoz wi...
# support
p
Hello Everyone, i`m trying to setting up signoz with node app express that have a redis. Using this package. https://www.npmjs.com/package/@opentelemetry/instrumentation-redis-4 But dont are working. We have a doc how to configure? The official doc have the package we need to use but not how configure. https://signoz.io/docs/instrumentation/express/#redis-instrumentation After the correct configuration the page database calls (Database Calls RPS, Database Calls Avg Duration) will work?
Here the tracing,js i`m trying,.
Copy code
// 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));
});
v
@Paulo Henrique de Morais Santiago redis and express instrumentation is part of node auto instrumentation and you don’t need to define it seperately. Just follow this instrumentation: https://signoz.io/docs/instrumentation/javascript/ and tracing.js
p
@Vishal Sharma thanks for response. Ok i remove the code you mentioned.
The redis we are using are for cache
As you see on pic 2 request, 1 without redis. And another with redis cached. Muuch less latency.
But when i go to database calls on signoz, dont appear nothing.
If you need i can send my app code.
v
@Paulo Henrique de Morais Santiago Can you please send me trace detail along with all tags? Similar to shown below
Also if your trace data is not sensitive, it will be great if you can share response of trace detail from network tab as shown below:
Copy code
[{"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]]}]
p
@Vishal Sharma here all tags
Copy code
http.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
message has been deleted
v
@Paulo Henrique de Morais Santiago Can you please send tags of span which belongs to redis query?
p
ok
Copy code
telemetry.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
message has been deleted
here the js code
Copy code
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 });
  }
});
v
client is the redis client, right?
p
Copy code
const redis = require('redis');
yes
the framework used is this
the most popular are redis and ioredis.
v
Actually span doesn’t mention db details at all, so signoz is not showing it in database calls. Need to check if this is an issue with auto instrumentation.
p
Maybe i try with ioredis can work?
p
great, but with the auto telemetry will get it right
v
Yes it should get by default.
p
Thanks, I’ll try and get back with the information.
Hey @Vishal Sharma, I change to ioredis framework. But still the same. here the tags of request getting a key of redis
Copy code
net.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
if you want i can send you the code of node app.
Hey bro, this databases call is the last thing i need to make a presentation on my company to show signoz as alternative to newrellic that are our apm today. But the signoz is really good, congrats.
because is very usefull for us redis the caching on redis is ok
v
Thanks @Paulo Henrique de Morais Santiago! Let me try this on a sample app.
p
Here my sample app, maybe can help on /cached-users
appwithcaching-ioredis.js
Copy code
const 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}`);
  });
v
Thanks @Paulo Henrique de Morais Santiago Let me try it