collect_data.js 4.22 KB
/**
 * 采集数据
 * 
 * @class Collect
 * @author shenzm<zhimin.shen@yoho.cn>
 * @date 2016/10/12
 */
'use strict';
const ssh = require('ssh2');
const Rp = require('request-promise');
const Trace = require('../logger/trace.js');
const config = require('../../config/config.js');

const {
    Server
} = require('../models');

var tracer = new Trace({
    host: config.influxdb.host,
    port: config.influxdb.port
});

class Collect {
    constructor(host, projectname, cloud) {
        this.host = host;
        this.projectname = projectname;
        this.cloud = cloud;
        this.scriptRunning = false;
        this.retry = {};
    }

    async collect() {
        let self = this;
        let server = await Server.findByHost(self.host);
        self.server = {
            host: server.host,
            username: server.username,
            password: server.password,
            port: server.port
        }

        let obj = {
            'total': 0,
            'status': {}
        };

        Rp({
            uri: `http://${self.host}:9615`,
            json: true
        }).then(function(data) {
            var processes = data.processes || [];
            processes.forEach(function(p) {
                if (p.name === 'pm2-server-monit') {
                    var cpuUsg = p.pm2_env.axm_monitor['CPU usage'].value;
                    var freeMem = p.pm2_env.axm_monitor['Free memory'].value;

                    obj.cpuUsg = cpuUsg ? parseFloat(cpuUsg.replace('%', '')) : 0;
                    obj.freeMem = freeMem ? parseFloat(freeMem.replace('%', '')) : 0;
                }

                if (p.name === self.projectname) {
                    obj.total++;

                    if (!obj.status[p.pm2_env.status]) {
                        obj.status[p.pm2_env.status] = 1;
                    } else {
                        obj.status[p.pm2_env.status]++;
                    }
                }
            });

            if (obj.cpuUsg === undefined) { // install server monit
                const script = 'pm2 install pm2-server-monit';
                self.execScript(script);
            }

            // add into influxDB todo
            tracer.report('server_data', {
                host: self.host,
                cloud: self.cloud
            }, obj);
        }).catch(function(err) {
            const script = 'pm2 web';
            self.execScript(script);
        });
    }

    execScript(script) {
        let self = this;
        if (self.scriptRunning || self.retry[`${self.host}_${script}`] > 5) {
            // 脚本执行中,或者重试次数大于5次以上时,不执行脚本
            return;
        }

        let retryCount = self.retry[`${self.host}_${script}`] || 0;
        self.retry[`${self.host}_${script}`] = ++retryCount;
        self.scriptRunning = true;

        let conn = new ssh.Client();
        conn.on('ready', () => {
            self._log(`>>>>host:[${self.host}] script[${script}]`);
            conn.exec(`${script}`, (err, stream) => {
                if (err) {
                    conn.end();
                    self._log(`host:[${self.host}] script:[${script}] exec fail error: ${err}`);
                    self.scriptRunning = false;
                } else {
                    stream.stdout.on('data', (data) => {
                        //self._log(data.toString());
                    });
                    stream.stderr.on('data', (data) => {
                        //self._log(data.toString());
                    });
                    stream.on('exit', (code) => {
                        conn.end();
                        if (code === 0) {
                            self._log(`host:[${self.host}] script[${script}] exec success`);
                        } else {
                            self._log(`host:[${self.host}] script[${script}] exec fail`);
                        }
                        self.scriptRunning = false;
                    });
                }
            });
        }).on('error', (err) => {
            self._log(`connect error ${self.host} ${err}`);
            self.scriptRunning = false;
        }).connect(Object.assign(self.server, {
            readyTimeout: 5000
        }));
    }

    _log(msg) {
        console.log(msg);
    }
}

module.exports = Collect;