UNPKG

@risingstack/trace

Version:
115 lines (95 loc) 2.76 kB
var Module = require('module') var path = require('path') var fs = require('fs') var remove = require('lodash.remove') var debug = require('debug')('risingstack/trace:instrumentations') var shimmer = require('../utils/shimmer') var INSTRUMENTED_LIBS = [ // from npm 'mongoose', 'mongodb', 'bluebird', 'redis', 'ioredis', 'mysql', 'when', 'q', 'koa', 'express', // knex and bookshelf does some black magic, so we have to do this :( 'bluebird.main', 'pg' ] var CORE_LIBS = [ 'http', 'https' ] function instrument (shortName, fileName, nodule, agent) { var newNodule if (!fs.existsSync(fileName)) { return debug('not found %s', fileName) } var pkg try { pkg = require(path.join(shortName, 'package.json')) } catch (err) { debug('cannot load package.json for %s: %s', shortName, err.message) } newNodule = require(fileName)(nodule, agent, pkg) return newNodule } function postLoadHook (nodule, name, agent) { var instrumentation var base = path.basename(name) // knex and bookshelf does some black magic, so we have to do this :( if (name === 'bluebird/js/main/promise') { instrumentation = 'bluebird.main' } else { instrumentation = base } if (INSTRUMENTED_LIBS.indexOf(instrumentation) !== -1) { debug('Instrumenting %s.', base) var fileName = path.join(__dirname, instrumentation + '.js') try { nodule = instrument(base, fileName, nodule, agent) nodule._instrumentedByTrace = true } catch (ex) { debug('failed to instrument %s using %s', name, fileName) } } return nodule } // patching most commonly used node modules module.exports.create = function (options) { var agent = options.agent var config = options.config || { } shimmer.wrap(process, 'process', '_fatalException', function (original) { return function (stackTrace) { agent.onCrash({ stackTrace: stackTrace }) return original.apply(this, arguments) } }) var disableInstrumentations = config.disableInstrumentations || [] disableInstrumentations.forEach(function (instrumentation) { remove(INSTRUMENTED_LIBS, function (lib) { return instrumentation === lib }) remove(CORE_LIBS, function (lib) { return instrumentation === lib }) }) CORE_LIBS.forEach(function (core) { var fileName = core + '.js' var filePath = path.join(__dirname, 'core', fileName) instrument(fileName, filePath, require(core), agent) }) shimmer.wrap(Module, 'Module', '_load', function (load) { return function (file) { return postLoadHook(load.apply(this, arguments), file, agent) } }) } module.exports.INSTRUMENTED_LIBS = INSTRUMENTED_LIBS module.exports.CORE_LIBS = CORE_LIBS