Consultando o percentual de uso da CPU com NodeJs + Socket.io

Standard

Tempos atrás fiz um post mostrando como podemos monitorar o consumo de CPU de um servidor e exibi-lo em tempo real utilizando Asp.net + SignalR. Na verdade a principal intenção não foi a utilidade do monitoramento, mas sim aprender como podemos trabalhar em uma aplicação com informações em tempo real, com transmissão de notificações, etc.

Pois bem, hoje em dia estou usando e estudando bastante NodeJs e decidi refazer o exemplo citado acima, porém, agora com NodeJs + Socket.io. Então, vamos lá:

Para Neste exemplo não vou utilizar o Visual Studio, mas sim o bom e velho commandline com algum editor de texto qualquer, desta forma vamos primeiramente criar um diretório para nosso projeto:

md cpu-usage-node-socketio

Em seguida vamos até o diretório criado e executar o comando:

npm install

Isto deverá gerar um arquivo package.json dentro do diretório. Em seguida vamos adicionar os seguintes pacotes ao projeto:

npm install express socket.io --save

Nas linhas acima eu adiciono 2 pacotes ao projeto separando-os por um espaço. O –save define que os pacotes serão incluídos no arquivo package.json como dependências. Não vou entrar no detalhe de explicar o pacote express faz. Já o pacote socket.io será utilizado para a transmissão de mensagens em tempo real via server/client.

Agora vamos a uma das coisas que acho mais bacana no NodeJs, que é a facilidade de fazer as coisas. Vamos criar um web server e deixa-lo rodando sob a porta 3500, para tanto crie um arquivo chamado server.js no projeto e inclua as seguintes linhas:

1
2
3
4
5
6
7
8
9
10
var app = require('express')();
var http = require('http').Server(app);
 
app.get('/', function(req, res){
    res.sendFile(__dirname + '/index.html');
});
 
http.listen(3500, function(){
  console.log('Listening on *:3500');
});

Em poucas linhas criamos um server e o deixamos rodando na porta 3500, agora vamos na linha de comando dentro do diretório e digitaremos o comando abaixo:

node server.js

Veja, é exibido a mensagem “Listening on *:3500”, ou seja, nosso server já está pronto e rodando! \0/

Porém, se entrarmos no browser em http://localhost:3500 será gerado um erro pois ainda não temos nosso arquivo “index.html” definido na chamada app.get. Então vamos cria-lo como mostrado abaixo:

1
2
3
4
5
6
7
8
<!doctype html>
<html>
  <head>
    <title>CPU Usage</title>
  </head>
 
  <body>Hello!</body>
</html>

Agora sim, se entrarmos novamente a página será exibida mostrando a mensagem Hello! Nossa aplicação agora está pronta para implementarmos o socket.io para a transmissão do percentual de uso da cpu. Vamos primeiramente criar o modulo de cálculo da cpu, então crie um arquivo chamado cpu.js e insira o código a seguir:

OBS: Já existem diversos pacotes que fazem este cálculo com muito mais recursos, como o perfmon, typeperf e io-utils. Porém, achei um gist bem simples e bacana que implementa apenas o consumo da cpu! Dei uma leve refatorada e deixei como mostrado abaixo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
var os = require("os");
 
exports.getPercentageUsage = function(interval, callback){
    getPercentageUsage(callback, interval);
}
 
function getPercentageUsage(callback, interval){
    var start = cpuAverage();
   
    setTimeout(function() {
        var end = cpuAverage();
        var idleDif = end.idle - start.idle;
        var totalDif = end.total - start.total;

        callback(100 - (100 * idleDif/totalDif));  
    }, interval);
}
 
function cpuAverage() {
    var totalIdle = 0, totalTick = 0;
    var cpus = os.cpus();
 
    for(var i in cpus){
        var cpu = cpus[i];

        for(t in cpu.times)
            totalTick += cpu.times[t];
       
        totalIdle += cpu.times.idle;      
    }

    return {idle: totalIdle/cpus.length,  total: totalTick/cpus.length};
}

Bem simples e objetivo, agora temos que alterar nosso arquivo server.js para utilizarmos esse módulo e transmitir o percentual via socket.io, veja:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var cpu = require('./cpu.js');
var interval = 1000;
 
app.get('/', function(req, res){
    res.sendFile(__dirname + '/index.html');
});
 
setInterval(function(){
    cpu.getPercentageUsage(interval, function(percentage){
        io.emit('cpu_usage', percentage);
    });
}, interval);
 
http.listen(3500, function(){
  console.log('Listening on *:3500');
});

Também bastante claro, importamos o módulo cpu.js e o utilizamos chamando a função getPercentageUsage, a cada 1 segundo transmitimos o percentual obtido pela chamada io.emit para o mesmo socket do client que possua o nome ‘cpu_usage’. Vejamos como fica nosso index.html agora:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<html>
  <head>
    <title>CPU Usage</title>
    <script src="/socket.io/socket.io.js"></script>
  </head>
 
  <body>
    CPU Usage: %<label id="cpu_list"></label>
    <br />
  </body>
 
  <script type="text/javascript">        
         var socket = io();
         socket.on('cpu_usage', function(msg){
            document.getElementById('cpu_list').innerHTML = msg;
         });
    </script>
</html>

Neste ponto nossa aplicação já funciona perfeitamente :), porém, para dar um “up” vamos implementar um gráfico da mesma forma como foi feito no artigo citado no início deste post (feito com SignalR), veja:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<html>
  <head>
    <title>CPU Usage</title>
    <script src="/socket.io/socket.io.js"></script>
    <script src="http://smoothiecharts.org/smoothie.js"></script>
  </head>
 
  <body>
    CPU Usage: %<label id="cpu_list"></label>
    <br />
    <canvas id="chart" width="500" height="100"></canvas>
  </body>
 
  <script type="text/javascript">        
         var socket = io();
         var sequence = new TimeSeries();
             
         socket.on('cpu_usage', function(msg){
            document.getElementById('cpu_list').innerHTML = msg;
            sequence.append(new Date().getTime(), msg);
         });
         
        var chart = new SmoothieChart();
        chart.addTimeSeries(sequence);
        chart.streamTo(document.getElementById('chart'), 1000);
    </script>
</html>

Agora sim, com tudo pronto, se iniciarmos nosso server novamente e entramos no navegador em http://localhost:3500 teremos o seguinte resultado:

One thought on “Consultando o percentual de uso da CPU com NodeJs + Socket.io

Leave a Reply

Your email address will not be published. Required fields are marked *