From 6f23459cf419cb841fbd29f86ec2d2e911818c96 Mon Sep 17 00:00:00 2001 From: Eran Hammer Date: Wed, 22 Aug 2012 00:08:57 -0700 Subject: [PATCH] debug interface, log interface --- lib/debug.js | 37 ++++++++++++++++++++++++++ lib/defaults.js | 15 ++++++++++- lib/request.js | 71 ++++++++++++++++++++++++++++++++++++++++++++----- lib/server.js | 22 ++++++++++++++- 4 files changed, 137 insertions(+), 8 deletions(-) create mode 100755 lib/debug.js diff --git a/lib/debug.js b/lib/debug.js new file mode 100755 index 000000000..dbdb0b4a5 --- /dev/null +++ b/lib/debug.js @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2012 Walmart. All rights reserved. Copyrights licensed under the New BSD License. +* See LICENSE file included with this code project for license terms. +*/ + +// Load modules + +var Err = require('./error'); + + +// Declare internals + +var internals = { + + events: {} // Map: debug session -> events array +}; + + +exports.report = function (session, event) { + + internals.events[session] = internals.events[session] || []; + internals.events[session].push(event); +}; + + +exports.session = function (request) { + + if (internals.events[request.params.id]) { + + request.reply(internals.events[request.params.id]); + } + else { + + request.reply(Err.notFound()); + } +}; + diff --git a/lib/defaults.js b/lib/defaults.js index 0ef54e29a..fef5ace2f 100755 --- a/lib/defaults.js +++ b/lib/defaults.js @@ -105,7 +105,11 @@ exports.server = { // Caching (see exports.cache for expected content) - cache: null + cache: null, + + // Debugging interface (see exports.debug for expected content) + + debug: null }; @@ -144,3 +148,12 @@ exports.cache = { } }; + +// Debug interface + +exports.debug = { + + debugEndpoint: '/debug/session', + queryKey: 'debug' +}; + diff --git a/lib/request.js b/lib/request.js index 5e2b00a2c..f16aa9a19 100755 --- a/lib/request.js +++ b/lib/request.js @@ -9,7 +9,7 @@ var NodeUtil = require('util'); var Events = require('events'); var Url = require('url'); var Utils = require('./utils'); -var Log = require('./log'); +var Debug = require('./debug'); // Declare internals @@ -54,17 +54,40 @@ exports = module.exports = Request = function (server, req, res) { res: res }; - this._response = {}; + this._log = []; + this._response = {}; // { result, error, options } this._analytics = { startTime: now }; - // Defined elsewhere: - // - // _response: { result, error, options } + // Extract session debugging information + + if (this.server.settings.debug) { + + if (this.query[this.server.settings.debug.queryKey]) { + + this._debug = this.query[this.server.settings.debug.queryKey]; + + delete this.url.search; + delete this.query[this.server.settings.debug.queryKey]; + + this._raw.req.url = Url.format(this.url); + this.setUrl(this._raw.req.url); + } + } + + // Log request + + var about = { + + method: this.method, + url: this.url.href, + agent: this._raw.req.headers['user-agent'] + }; + + this.log('http', 'received', '', about, now) - Log.info('Received', this); return this; }; @@ -84,3 +107,39 @@ Request.prototype.setMethod = function (method) { this.method = method.toLowerCase(); }; + +Request.prototype.log = function (category, event, message, data, timestamp) { + + // Prepare log item + + var now = (timestamp ? (timestamp instanceof Date ? timestamp.getTime() : timestamp) : Utils.getTimestamp()); + var item = { + + timestamp: now, + category: category, + event: event + }; + + if (message) { + + item.message = message; + } + + if (data) { + + item.data = data; + } + + // Add to array + + this._log.push(item); + + // Pass to debug + + if (this._debug) { + + Debug.report(this._debug, item); + } +}; + + diff --git a/lib/server.js b/lib/server.js index 9cfc243e5..d9a5bdf66 100755 --- a/lib/server.js +++ b/lib/server.js @@ -20,6 +20,7 @@ var Session = require('./session'); var Cache = require('./cache'); var Request = require('./request'); var Route = require('./route'); +var Debug = require('./debug'); // Declare internals @@ -129,7 +130,7 @@ exports.Server = Server = function (host, port, options, routes) { this.listener = Http.createServer(this.dispatch()); } - // Initialize Monitoring if set + // Initialize monitoring if set this.monitor = new Monitor(this, this.settings, Log); @@ -152,6 +153,24 @@ exports.Server = Server = function (host, port, options, routes) { }); } + // Setup debug endpoint + + if (this.settings.debug) { + + this.settings.debug = Utils.applyToDefaults(Defaults.debug, (typeof this.settings.debug === 'boolean' ? {} : this.settings.debug)); + + this.addRoute({ + + method: 'GET', + path: this.settings.debug.debugEndpoint + '/:id', + config: { + + handler: Debug.session, + authentication: 'none' + } + }); + } + // Add routes if (routes) { @@ -174,6 +193,7 @@ Server.prototype.dispatch = function () { // Create request object var request = new Request(self, req, res); + Log.info('Received', request); // Execute onRequest extensions (can change request method, url, etc.)