The Trainer
The Trainer

Reputation: 695

open-telemetry observable gauge in js - how to access field used in observable gauge inside socket.io method

I'm struggling with that case: I need to expose some metrics (simple monitoring of incoming number of requests, time of processing etc).

const app = require('express')();
const http = require('http').Server(app);
const io = require('socket.io')(http);
const port = process.env.PORT || 3000;

//instrumentation
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { ConsoleSpanExporter } = require('@opentelemetry/sdk-trace-node');

//prometheus exporter
const opentelemetry = require('@opentelemetry/sdk-node');
const {
  getNodeAutoInstrumentations,
} = require('@opentelemetry/auto-instrumentations-node');
const { PrometheusExporter } = require('@opentelemetry/exporter-prometheus');
const { PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics');
const { Resource } = require('@opentelemetry/resources');
const { metrics } = require('@opentelemetry/api');
const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-grpc');
const { MeterProvider }  = require('@opentelemetry/sdk-metrics-base');
const { HostMetrics } = require('@opentelemetry/host-metrics');


//const memoryData = process.memoryUsage();
//const cpuData = process.cpuUsage();
//const data = process.resourceUsage

const exporter = new PrometheusExporter(
  {
    startServer: true,
    port : 56326
  }, () => {
    console.log('prometheus scrape endpoint: http://localhost:56326/metrics')
  }
)
const meterProvider = new MeterProvider()
meterProvider.addMetricReader(exporter)

var counter = meterProvider.getMeter('prometheus').createCounter("failed_requests_metric", {
  description: "Indicates failed requests",
  monotonic: true,
  labelKeys: ["failed_requests_metric"],
});


var timeOfProcessing =56;
var time_of_processing_observable_gauge = meterProvider.getMeter('prometheus').createObservableGauge("time_of_processing", {
  description: "sum of all messages processing time",
  monotonic: true,
  labelKeys: ["time_of_processing"],
});
time_of_processing_observable_gauge.addCallback(()=> timeOfProcessing)

var processed = 0;
var counterOfProcessed_observable_gauge = meterProvider.getMeter('prometheus').createObservableGauge("counter_of_processed", {
  description: "all processed messages",
  monotonic: true,
  labelKeys: ["counter_of_processed"],
});
counterOfProcessed_observable_gauge.addCallback(()=> processed)

var timeBetweenReceiveAndSend;
var time_between_receive_and_send_observable_gauge = meterProvider.getMeter('prometheus').createObservableGauge("time_between_receive_and_send", {
  description: "sum of all messages receive plus send time",
  monotonic: true,
  labelKeys: ["time_between_receive_and_send"],
});
time_between_receive_and_send_observable_gauge.addCallback(()=> timeBetweenReceiveAndSend);

let timeOfTransport;
var time_of_transport_observable_gauge = meterProvider.getMeter('prometheus').createObservableGauge("time_of_transport", {
  description: "sum of all messages transport (from client to server) time",
  monotonic: true,
  labelKeys: ["time_of_transport"],
});
time_of_transport_observable_gauge.addCallback(()=>timeOfTransport);

const hostMetrics = new HostMetrics({ meterProvider, name: 'example-host-metrics' })
hostMetrics.start();

function method1()
{
  this.processed+=1;
}

try{
app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', (socket) => {
  socket.on('chat message', msg => {

    var currentTime = Date.now();

    var splitted = msg.split("//");
    var time = splitted[1];
    var message = splitted[0];
    var timeOfTransportLocal = currentTime - time;

    //counterOfProcessed_observable_gauge+=1;
    this.processed+=1;
    this.timeOfTransport+=timeOfTransportLocal;
    this.method1();
    var timeStart = Date.now();
    io.emit('chat message', msg);//Object.keys(io.eio.clients));
    var timeEnd = Date.now();
    this.timeOfProcessing+=timeEnd-timeStart;


  });
});

http.listen(port, () => {
  console.log(`Socket.IO server running at http://localhost:${port}/`);
});
}
catch(e){
  counter.add(1);
  throw e;
}

I cannot access to method1() nor variables that are used in observableGauge callbacks (like this.timeOfProcessing) inside socket.on methods. I know i should avoid this but i don't know how to access to my global fields. I read this thread: How to access the correct `this` inside a callback but i don't know how to use this knowledge in my issue.

Upvotes: 0

Views: 119

Answers (0)

Related Questions