ca-apm-probe
Version:
CA APM Node.js Agent monitors real-time health and performance of Node.js applications
97 lines (77 loc) • 2.87 kB
JavaScript
/**
* 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.
*/
// custom parser for arf messages sent by collector agent
'use strict';
var net = require('net');
var util = require('util');
var logger = require("./logger.js");
// raw data containing multiple json strings is separated by EOL character
var messageSeparator = '\n';
var Transform = require('stream').Transform;
util.inherits(ArfMessageParser, Transform);
function ArfMessageParser(options) {
if (!(this instanceof ArfMessageParser))
return new ArfMessageParser(options);
Transform.call(this, options);
this.maxAllowedBufferSize = 100;
this.rawDataBuffer = [];
}
ArfMessageParser.prototype._transform = function(chunk, encoding, done) {
try {
var data = chunk.toString();
logger.debug("raw data received from collector: %s", data);
this.processData(data);
done();
} catch (e) {
this.emit('error', new Error('invalid data chunk'));
return;
}
};
ArfMessageParser.prototype.processData = function(data) {
// check if the data has a \n
var split = -1;
for (var i = 0; i < data.length; i++) {
if (data[i] === messageSeparator) {
split = i;
break;
}
}
if (split === -1) {
// still waiting for the \n
// stash the chunk, and try again.
if (this.rawDataBuffer.length < this.maxAllowedBufferSize) {
this.rawDataBuffer.push(data);
}
} else {
var dataSegment = data.slice(0, split);
this.rawDataBuffer.push(dataSegment);
var message = this.rawDataBuffer.join('');
logger.debug("emitting 'arf-message' event for message: %s", message);
// and notify listeners that we are done parsing message
this.emit('arf-message', message);
// successfully sent event, clear buffer data now
this.rawDataBuffer = [];
var remainingData = data.slice(split + messageSeparator.length);
if (remainingData && remainingData.length > 0) {
this.processData(remainingData);
}
}
}
module.exports = {
ArfMessageParser: ArfMessageParser
};