diff --git a/browserid/app.js b/browserid/app.js index 8adc439ed3ca48f9e5f28e3a62d6a63eb28d795d..e31733579e0c44a46d02f9eb75f51e68a44ad8cd 100644 --- a/browserid/app.js +++ b/browserid/app.js @@ -81,7 +81,7 @@ function router(app) { // this should probably be an internal redirect // as soon as relative paths are figured out. app.get('/sign_in', function(req, res, next ) { - metrics.userEntry('browserid', req); + metrics.userEntry(req); res.render('dialog.ejs', { title: 'A Better Way to Sign In', layout: false, diff --git a/browserid/lib/db_mysql.js b/browserid/lib/db_mysql.js index 964281d49462877d7396d83a70f0c79d4ed72113..d81395526ffebd02af0c334dc50e1f2cf26b9f24 100644 --- a/browserid/lib/db_mysql.js +++ b/browserid/lib/db_mysql.js @@ -83,7 +83,7 @@ function logUnexpectedError(detail) { var where; try { dne; } catch (e) { where = e.stack.split('\n')[2].trim(); }; // now log it! - metrics.report('db', { type: "unexpected", message: "unexpected database failure", detail: detail, where: where }); + metrics.report('unexpected', { message: "unexpected database failure", detail: detail, where: where }); } // open & create the mysql database @@ -426,7 +426,7 @@ exports.pubkeysForEmail = function(email, cb) { exports.removeEmail = function(authenticated_email, email, cb) { exports.emailsBelongToSameAccount(authenticated_email, email, function(ok) { if (!ok) { - metrics.report('security', { type: 'security', msg: authenticated_email + ' attempted to delete an email that doesn\'t belong to her: ' + email }); + metrics.report('security', { msg: authenticated_email + ' attempted to delete an email that doesn\'t belong to her: ' + email }); cb("authenticated user doesn't have permission to remove specified email " + email); return; } diff --git a/libs/metrics.js b/libs/metrics.js index f05328226ee3652088b7454f5d94a19bef6a6f50..ae0aaf35434519bc129282a088ab0263038e5a9e 100644 --- a/libs/metrics.js +++ b/libs/metrics.js @@ -88,15 +88,18 @@ function setupLogger() { } // entry is an object that will get JSON'ified -exports.report = function(category, entry) { - // entry must have at least a type - if (!entry.type) - throw new Error("every log entry needs a type"); - +exports.report = function(type, entry) { // setup the logger if need be setupLogger(); + // allow convenient reporting of atoms by converting + // atoms into objects + if (entry === null || typeof entry !== 'object') entry = { msg: entry }; + if (entry.type) throw "reported metrics may not have a `type` property, that's reserved"; + entry.type = type; + // timestamp + if (entry.at) throw "reported metrics may not have an `at` property, that's reserved"; entry.at = new Date().toUTCString(); // if no logger, go to console (FIXME: do we really want to log to console?) @@ -104,9 +107,8 @@ exports.report = function(category, entry) { }; // utility function to log a bunch of stuff at user entry point -exports.userEntry = function(category, req) { - exports.report(category, { - type: 'signin', +exports.userEntry = function(req) { + exports.report('signin', { browser: req.headers['user-agent'], rp: req.headers['referer'], // IP address (this probably needs to be replaced with the X-forwarded-for value diff --git a/verifier/app.js b/verifier/app.js index 1116b881ffdce383851c9925926fd8f21d62077b..e2afb4fb2c7da528f182cae8eab00790c357c8e3 100644 --- a/verifier/app.js +++ b/verifier/app.js @@ -72,11 +72,10 @@ function doVerify(req, resp, next) { audience, function(payload) { // log it! - metrics.report('verifier', { - type: 'verify', - result: 'success', - rp: payload.audience - }); + metrics.report('verify', { + result: 'success', + rp: payload.audience + }); result = { status : "okay", @@ -88,21 +87,19 @@ function doVerify(req, resp, next) { resp.json(result); }, function(errorObj) { - metrics.report('verifier', { - type: 'verify', - result: 'failure', - rp: audience - }); + metrics.report('verify', { + result: 'failure', + rp: audience + }); resp.json({ status: "failure", reason: errorObj }); } ); } catch (e) { console.log(e.stack); - metrics.report('verifier', { - type: 'verify', - result: 'failure', - rp: audience - }); + metrics.report('verify', { + result: 'failure', + rp: audience + }); resp.json({ status: "failure", reason: e.toString() }); } }