'use strict'; var utils = require('../utils'); var defaultOnConfig = { console: true, http: true }; var defaultConfig = { console: false, http: false, pg: false }; function instrument(Raven, config) { if (config === false) { return; } else if (config === true) { config = defaultOnConfig; } else { config = utils.extend({}, defaultConfig, config); } Raven.instrumentedOriginals = []; Raven.instrumentedModules = []; var Module = require('module'); utils.fill( Module, '_load', function(origLoad) { return function(moduleId, parent, isMain) { var origModule = origLoad.apply(this, arguments); if (config[moduleId] && Raven.instrumentedModules.indexOf(moduleId) === -1) { Raven.instrumentedModules.push(moduleId); return require('./' + moduleId)(Raven, origModule, Raven.instrumentedOriginals); } return origModule; }; }, Raven.instrumentedOriginals ); // special case: since console is built-in and app-level code won't require() it, do that here if (config.console) { require('console'); } // observation: when the https module does its own require('http'), it *does not* hit our hooked require to instrument http on the fly // but if we've previously instrumented http, https *does* get our already-instrumented version // this is because raven's transports are required before this instrumentation takes place, which loads https (and http) // so module cache will have uninstrumented http; proactively loading it here ensures instrumented version is in module cache // alternatively we could refactor to load our transports later, but this is easier and doesn't have much drawback if (config.http) { require('http'); } } function deinstrument(Raven) { if (!Raven.instrumentedOriginals) return; var original; // eslint-disable-next-line no-cond-assign while ((original = Raven.instrumentedOriginals.shift())) { var obj = original[0]; var name = original[1]; var orig = original[2]; obj[name] = orig; } } module.exports = { instrument: instrument, deinstrument: deinstrument };