diff --git a/lib/helpers/hydrater.js b/lib/helpers/hydrater.js index 9e12329..c2756f8 100644 --- a/lib/helpers/hydrater.js +++ b/lib/helpers/hydrater.js @@ -14,8 +14,8 @@ var rarity = require('rarity'); var util = require('util'); var lib = require('../index.js'); - var HydrationError = lib.HydrationError; +var logError = require('../utils').logError; @@ -52,6 +52,12 @@ module.exports = function(hydraterFunction, childs, logger, errLogger) { if(!cleaner.called) { cleaner.called = true; if(err) { + var extra = JSON.parse(JSON.stringify(task)); + extra.changes = changes; + extra.stdout = stdout; + extra.stderr = stderr; + + logError(err, extra); child.reset(); } else { @@ -170,7 +176,7 @@ module.exports = function(hydraterFunction, childs, logger, errLogger) { cb(null, changes); }, function patchDocument(changes, cb) { - // Returning null means we won't complete the hdyration, and are waiting for something else. + // Returning null means we won't complete the hydration, and are waiting for something else. if(changes === null) { logger("Skipped task: " + ((task.file_path) ? task.file_path : task.document.id)); return cb(); @@ -187,8 +193,11 @@ module.exports = function(hydraterFunction, childs, logger, errLogger) { } ], function handleErrors(err, changes, res) { async.waterfall([ - function logError(cb) { + function logErrors(cb) { if(err) { + var extra = JSON.parse(JSON.stringify(task)); + extra.changes = changes; + logError(err, extra); errLogger("ERR hydrating " + ((task.file_path) ? task.file_path : task.document.id), err.toString()); } @@ -214,7 +223,11 @@ module.exports = function(hydraterFunction, childs, logger, errLogger) { } } ], function(internalErr) { + /* istanbul ignore next */ if(internalErr) { + var extra = JSON.parse(JSON.stringify(task)); + extra.changes = changes; + logError(internalErr, extra); errLogger("INTERNAL ERR", internalErr); } done(err || internalErr, changes); diff --git a/lib/index.js b/lib/index.js index fd5245a..da26caf 100644 --- a/lib/index.js +++ b/lib/index.js @@ -5,6 +5,7 @@ var restify = require('restify'); var yaqs = require('yaqs'); var Childs = require('./helpers/Childs'); +var utils = require('./utils.js'); /** * Create a new hydration server. * This server will use `config.hydrater_function` as its main function, to turn a file into metadata. @@ -23,6 +24,14 @@ module.exports.createServer = function(config) { config.logger = config.logger || console.log; config.errLogger = config.errLogger || console.error; + utils.logError.config = config; + + /* istanbul ignore next */ + if(config.opbeat && config.opbeat.secretToken) { + var opbeat = require('opbeat'); + utils.logError.opbeat = opbeat(config.opbeat); + } + var concurrency = config.concurrency || 1; var tasksPerProcess = config.tasksPerProcess || 100; diff --git a/lib/utils.js b/lib/utils.js new file mode 100644 index 0000000..94094b6 --- /dev/null +++ b/lib/utils.js @@ -0,0 +1,70 @@ +"use strict"; + +/* istanbul ignore next */ +module.exports.logError = function logError(err, req, extra) { + // No logging on test or if err is undefined + if(process.env.NODE_ENV === "test" || !err) { + return; + } + + if(!extra) { + extra = req; + req = null; + } + + delete err.domain; + delete err.domainThrown; + + if(err.__alreadyLogged) { + console.warn("Skipping an error already sent to Opbeat: ", err.toString()); + return; + } + + if(!extra) { + extra = {}; + } + + if(module.exports.logError.config) { + extra.hydrater = module.exports.logError.config.hydraterUrl; + } + + if(module.exports.logError.opbeat) { + var meta = { + extra: extra + }; + + if(req) { + meta.request = req; + + if(req.token) { + meta.user = { + is_authenticated: true, + id: req.token.anyfetchToken, + username: req.token.accountName, + email: req.token.accountName + }; + } + } + + module.exports.logError.opbeat.captureError(err, meta); + } + else { + var all = { + details: err.toString(), + err: err, + extra: extra + }; + + try { + all = JSON.stringify(all); + } + catch(e) { + // Converting circular structure to JSON. + // We can't do anything, let's log the raw object. + } + + console.warn("LOG-ERROR-DETAILS", all); + } + + err.__alreadyLogged = true; +}; diff --git a/package.json b/package.json index ad22af0..486c837 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ ], "dependencies": { "async": "^0.9.0", + "opbeat": "^1.0.5", "rarity": "^2.1.1", "redis": "^0.12.1", "restify": "^2.8.3",