UNPKG

ca-apm-probe

Version:

CA APM Node.js Agent monitors real-time health and performance of Node.js applications

144 lines (113 loc) 4.22 kB
/** * Copyright (c) 2015 CA. All rights reserved. * * This software and all information contained therein is confidential and proprietary and * shall not be duplicated, used, disclosed or disseminated in any way except as authorized * by the applicable license agreement, without the express written permission of CA. All * authorized reproductions must be marked with this language. * * EXCEPT AS SET FORTH IN THE APPLICABLE LICENSE AGREEMENT, TO THE EXTENT * PERMITTED BY APPLICABLE LAW, CA PROVIDES THIS SOFTWARE WITHOUT WARRANTY * OF ANY KIND, INCLUDING WITHOUT LIMITATION, ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL CA BE * LIABLE TO THE END USER OR ANY THIRD PARTY FOR ANY LOSS OR DAMAGE, DIRECT OR * INDIRECT, FROM THE USE OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, LOST * PROFITS, BUSINESS INTERRUPTION, GOODWILL, OR LOST DATA, EVEN IF CA IS * EXPRESSLY ADVISED OF SUCH LOSS OR DAMAGE. */ /*! * proc * Copyright(c) 2012 Daniel D. Shaw <dshaw@dshaw.com> * MIT Licensed */ // is there anything even left of the original version by dshaw? var fs = require('fs'); // // This gets all messed up on 64-bit Solaris because the initial version assumed // 32 bits for all longs. If this module ever get used for anything *other* // than Solaris, you'll want to verify that the sizes of these types are // still valid. // // typedef struct timespec { /* definition per POSIX.4 */ // time_t tv_sec; /* seconds */ // long tv_nsec; /* and nanoseconds */ // } timespec_t; // ... // typedef long time_t; /* time of day in seconds */ var sizeof_long = 4; // 32-bit var sizeof_timespec = 8; if (process.arch == 'x64') { sizeof_long = 8; sizeof_timespec = 16; } function readTimespec(buf, offset) { // this would be pretty janky for 64-bit, but because that 32-bit timestamp // isn't going to hit the 64-bit space until 2037, it's Good Enough[tm] return buf.readInt32LE(offset) + (buf.readInt32LE(offset + sizeof_long) / 1000000000); } exports.usage = function usage(pid, callback) { fs.readFile('/proc/' + pid + '/usage', function(err, buf) { if (err) { return callback(err, null); }; var data = {}; var offset = 0; // lwp id. 0: process or defunct data.lwpid = buf.readUInt32LE(offset); offset += 4; // number of contributing lwps data.count = buf.readUInt32LE(offset); offset += 4; // current time stamp data.tstamp = readTimespec(buf, offset); offset += sizeof_timespec; // process/lwp creation time stamp data.create = readTimespec(buf, offset); offset += sizeof_timespec; // process/lwp termination time stamp data.term = readTimespec(buf, offset); offset += sizeof_timespec; // total lwp real (elapsed) time data.rtime = readTimespec(buf, offset); offset += sizeof_timespec; // user level cpu time data.utime = readTimespec(buf, offset); offset += sizeof_timespec; // system call cpu time data.stime = readTimespec(buf, offset); offset += sizeof_timespec; // there's normally another big pile of values we could read, but // don't need any of them callback(null, data); }); }; // we only check this on linux, need to make sure that the field numbers // are valid on other platforms if we want to use it there as well exports.stat = function stat(pid, callback) { fs.readFile('/proc/' + pid + '/stat', 'ascii', function(err, data) { if (err) { return callback(err, null); } var stats_pid = data.split(' '); var ret = {}; ret.utime = parseInt(stats_pid[13]); ret.stime = parseInt(stats_pid[14]); ret.ptime = ret.utime + ret.stime; fs.readFile('/proc/stat', 'ascii', function(err, data) { if (err) return; ret.all = data.match('cpu +(.*)\n')[1].split(' '); ret.all = array_sum(ret.all); callback(null, ret); }) }); } function array_sum(a) { var k, s = 0; if (typeof a !== 'object') return null; for (k in a) { s += (a[k] * 1); } return s; }