UNPKG

ca-apm-probe

Version:

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

107 lines (96 loc) 3.84 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. */ // Copyright (c) 2014, StrongLoop Inc. // // This software is covered by the StrongLoop License. See StrongLoop-LICENSE // in the top-level directory or visit http://strongloop.com/license. var stream = require('stream'); var util = require('util'); exports.JsonDecoder = JsonDecoder; exports.JsonEncoder = JsonEncoder; // |maxlen| is the amount of unparsed JSON data that may be buffered. // |maxlen| < 1 means 'unlimited' // // When the |maxlen| threshold is exceeded, an 'error' event is emitted on // the decoder object and the decoder stops parsing. The decoder can then // be resumed by feeding it more data. function JsonDecoder(maxlen) { if (!(this instanceof JsonDecoder)) return new JsonDecoder(maxlen); this.constructor.call(this, {objectMode: true}); this.buffer_ = ''; this.index_ = 0; this.maxlen_ = (maxlen | 0) || -1; this.slice_ = null; } JsonDecoder.prototype = Object.create(stream.Transform.prototype); JsonDecoder.prototype._transform = function(chunk, encoding, done) { this.buffer_ += chunk.toString(); for (;;) { this.slice_ = null; var index = this.buffer_.indexOf('\n', this.index_); if (index === -1) { this.index_ = this.buffer_.length; // Do the check now rather than before entering the loop. If the new // chunk causes the threshold to be exceeded but contains the newline // that we're looking for, then we might as well parse the JSON. But // if there is still no newline, report a 'threshold exceeded' error. if (this.maxlen_ > 0 && this.buffer_.length > this.maxlen_) { var err = Error(util.format('Buffer size %d exceeds threshold.', this.buffer_.length)); this.emit('error', err); return done(); } break; } var length = index + 1; this.slice_ = this.buffer_.slice(0, length); this.buffer_ = this.buffer_.slice(length); this.index_ -= index; if (length === 1) { // A single newline is not a JSON object. continue; } try { var object = JSON.parse(this.slice_); this.slice_ = null; } catch (ex) { var err = ex; // Make the property non-enumerable so that printing the error object // won't also print possibly megabytes of JSON data. Object.defineProperty(err, 'data', {value: this.slice_}); } if (err) { this.emit('error', err); err = null; } else { this.push(object); } if (this.paused) { break; } } done(); }; function JsonEncoder() { if (!(this instanceof JsonEncoder)) return new JsonEncoder; this.constructor.call(this, {objectMode: true}); } JsonEncoder.prototype = Object.create(stream.Transform.prototype); JsonEncoder.prototype._transform = function(chunk, encoding, done) { this.push(JSON.stringify(chunk) + '\n', 'utf8'); done(); };