154 lines
3.6 KiB
JavaScript

/*
Copyright (c) 2013, Oracle and/or its affiliates. All rights
reserved.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 of
the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
02110-1301 USA
*/
"use strict";
var assert = require("assert"),
util = require("util"),
http = require("http");
var global_stats;
var running_servers = {};
var unified_debug = require("./unified_debug");
var udebug = unified_debug.getLogger("STATS");
var DETAIL = udebug.is_detail();
/* Because modules are cached, this initialization should happen only once.
If you try to do it twice the assert will fail.
*/
assert(typeof(global_stats) === 'undefined');
global_stats = {};
function getStatsDomain(root, keys, nparts) {
var i, key;
var stat = root;
for(i = 0 ; i < nparts; i++) {
key = keys[i];
if(typeof(stat[key]) === 'undefined') {
stat[key] = {};
}
stat = stat[key];
}
return stat;
}
function dot(argsList, length) {
var i, r = "";
for (i = 0 ; i < length ; i++) {
if(typeof argsList[i] !== 'undefined') {
if(i) r += ".";
r += argsList[i];
}
}
return r;
}
function dotted_name(base, keyPath) {
return base + "." + dot(keyPath, keyPath.length);
}
/* registerStats(statsObject, keyPart, ...)
*/
exports.register = function(userStatsContainer) {
var statParts, statsDomain, globalStatsNode, i;
statParts = [];
for(i = 1 ; i < arguments.length - 1; i++) {
statParts.push(arguments[i]);
}
statsDomain = arguments[i]; // the final part of the domain
assert(typeof userStatsContainer === 'object');
globalStatsNode = getStatsDomain(global_stats, statParts, statParts.length);
globalStatsNode[statsDomain] = userStatsContainer;
return this;
};
exports.query = function(path) {
return getStatsDomain(global_stats, path, path.length);
};
/* Translate a URL like "/a/b/" into an array ["a","b"]
*/
function parseStatsUrl(url) {
var parts = url.split("/");
if(parts[0].length == 0) {
parts.shift();
}
if(parts[parts.length-1].length == 0) {
parts.pop();
}
return parts;
}
exports.peek = function(query) {
var parts;
var tree = global_stats;
if(query) {
parts = parseStatsUrl(query);
tree = getStatsDomain(global_stats, parts, parts.length);
}
console.log(JSON.stringify(tree));
};
exports.startStatsServer = function(port, host, callback) {
var key = host + ":" + port;
var server;
function onStatsRequest(req, res) {
var parts, stats, response;
parts = parseStatsUrl(req.url);
stats = getStatsDomain(global_stats, parts, parts.length);
res.writeHead(200, {'Content-Type': 'text/plain'});
response = util.inspect(stats, true, null, false) + "\n";
res.end(response);
}
if(running_servers[key]) {
server = running_servers[key];
}
else {
server = http.createServer(onStatsRequest);
running_servers[key] = server;
server.listen(port, host, callback);
}
return server;
};
exports.stopStatsServers = function() {
var key;
for(key in running_servers) {
if(running_servers.hasOwnProperty(key)) {
running_servers[key].close();
}
}
};