todosapp: dom logging mechanism
Change-Id: I748a2be01a81dc15a20eeff5d53191c8cb6ea399
diff --git a/browser/benchmark.js b/browser/benchmark.js
index f1be681..9e264a0 100644
--- a/browser/benchmark.js
+++ b/browser/benchmark.js
@@ -3,30 +3,23 @@
'use strict';
var async = require('async');
-var moment = require('moment');
var syncbase = require('syncbase');
var nosql = syncbase.nosql;
+var util = require('./util');
+
exports.logLatency = logLatency;
exports.runBenchmark = runBenchmark;
var LOG_EVERYTHING = false;
-// Returns a string timestamp, useful for logging.
-function timestamp(t) {
- t = t || Date.now();
- return moment(t).format('HH:mm:ss.SSS');
-}
-
function logStart(name) {
- var t = Date.now();
- console.log(timestamp(t) + ' ' + name + ' start');
- return t;
+ util.log(name + ' start');
+ return Date.now();
}
function logStop(name, start) {
- var t = Date.now();
- console.log(timestamp(t) + ' ' + name + ' took ' + (t - start) + 'ms');
+ util.log(name + ' took ' + (Date.now() - start) + 'ms');
}
function logLatency(name, cb) {
@@ -47,15 +40,15 @@
// which should create the VC.)
function doPuts(ctx, tb, n, cb) {
cb = logLatency('doPuts', cb);
- var prefix = timestamp() + '.';
+ var prefix = util.timestamp() + '.';
async.times(100, function(n, cb) {
// TODO(sadovsky): Remove this once we loosen Syncbase's naming rules.
prefix = prefix.replace(/:/g, '.');
var key = prefix + n;
var value = '';
- if (LOG_EVERYTHING) console.log('put: ' + key);
+ if (LOG_EVERYTHING) util.log('put: ' + key);
tb.put(ctx, key, value, function(err) {
- if (LOG_EVERYTHING) console.log('put done: ' + key);
+ if (LOG_EVERYTHING) util.log('put done: ' + key);
cb(err);
});
}, function(err) {
@@ -70,11 +63,11 @@
tb.scan(ctx, nosql.rowrange.prefix(prefix), function(err) {
err = err || streamErr;
if (err) return cb(err);
- console.log('scanned ' + bytes + ' bytes');
+ util.log('scanned ' + bytes + ' bytes');
cb();
}).on('data', function(row) {
bytes += row.key.length + row.value.length;
- if (LOG_EVERYTHING) console.log('scan: ' + JSON.stringify(row));
+ if (LOG_EVERYTHING) util.log('scan: ' + JSON.stringify(row));
}).on('error', function(err) {
streamErr = streamErr || err.error;
});
diff --git a/browser/defaults.js b/browser/defaults.js
index e9dfea4..bae85e3 100644
--- a/browser/defaults.js
+++ b/browser/defaults.js
@@ -7,6 +7,7 @@
var CollectionDispatcher = require('./collection_dispatcher');
var MemCollection = require('./mem_collection');
var SyncbaseDispatcher = require('./syncbase_dispatcher');
+var util = require('./util');
// Copied from meteor/todos/server/bootstrap.js.
var data = [
@@ -90,10 +91,10 @@
if (benchmark) {
return bm.runBenchmark(ctx, db, cb);
}
- console.log('app exists; assuming everything has been initialized');
+ util.log('app exists; assuming everything has been initialized');
return cb(null, disp);
}
- console.log('app does not exist; initializing everything');
+ util.log('app does not exist; initializing everything');
app.create(wt(ctx), {}, function(err) {
if (err) return cb(err);
db.create(wt(ctx), {}, function(err) {
@@ -103,7 +104,7 @@
if (benchmark) {
return bm.runBenchmark(ctx, db, cb);
}
- console.log('hierarchy created; writing rows');
+ util.log('hierarchy created; writing rows');
initData(disp, function(err) {
if (err) return cb(err);
cb(null, disp);
diff --git a/browser/index.js b/browser/index.js
index 17eb9a1..00e3eff 100644
--- a/browser/index.js
+++ b/browser/index.js
@@ -12,7 +12,8 @@
var vanadium = require('vanadium');
var defaults = require('./defaults');
-var h = require('./util').h;
+var util = require('./util');
+var h = util.h;
////////////////////////////////////////
// Constants
@@ -422,8 +423,8 @@
},
componentWillUpdate: function(nextProps, nextState) {
if (false) {
- console.log(this.props, nextProps);
- console.log(this.state, nextState);
+ util.log(this.props, nextProps);
+ util.log(this.state, nextState);
}
},
componentDidUpdate: function() {
@@ -487,12 +488,21 @@
////////////////////////////////////////
// Initialization
+var logEl = document.querySelector('#log');
+util.addLogger(function() {
+ var msgEl = document.createElement('div');
+ msgEl.className = 'msg';
+ msgEl.innerText = Array.prototype.slice.call(arguments).join(' ');
+ logEl.appendChild(msgEl);
+});
+util.log('starting app');
+
var u = url.parse(window.location.href, true);
var rc; // React component
function render(props) {
console.assert(!rc);
- rc = React.render(Page(props), document.getElementById('page'));
+ rc = React.render(Page(props), document.querySelector('#page'));
}
function initDispatcher(dispType, syncbaseName, benchmark, cb) {
diff --git a/browser/syncbase_dispatcher.js b/browser/syncbase_dispatcher.js
index e7cc62c..1c64ccc 100644
--- a/browser/syncbase_dispatcher.js
+++ b/browser/syncbase_dispatcher.js
@@ -31,6 +31,7 @@
var bm = require('./benchmark');
var Dispatcher = require('./dispatcher');
+var util = require('./util');
inherits(SyncbaseDispatcher, Dispatcher);
module.exports = SyncbaseDispatcher;
@@ -248,7 +249,7 @@
};
SyncbaseDispatcher.prototype.logTraceRecords = function() {
- console.log(vtrace.formatTraces(this.getTraceRecords()));
+ util.log(vtrace.formatTraces(this.getTraceRecords()));
};
// TODO(sadovsky): Watch for changes on Syncbase itself so that we can detect
diff --git a/browser/util.js b/browser/util.js
index 290e6b6..999ca99 100644
--- a/browser/util.js
+++ b/browser/util.js
@@ -1,6 +1,7 @@
'use strict';
var _ = require('lodash');
+var moment = require('moment');
var React = require('react');
exports.h = function(selector, props, children) {
@@ -11,12 +12,31 @@
props = {};
}
var parts = selector.split('.');
- var x = parts[0].split('#'), type = x[0], id = x[1];
+ var x = parts[0].split('#'), tagName = x[0], id = x[1];
var className = parts.slice(1).join(' ');
- console.assert(type);
+ console.assert(tagName);
props = _.assign({}, props, {
id: id || undefined,
className: className || undefined
});
- return React.createElement(type, props, children);
+ return React.createElement(tagName, props, children);
+};
+
+// Returns a string timestamp, useful for logging.
+var timestamp = exports.timestamp = function(t) {
+ t = t || Date.now();
+ return moment(t).format('HH:mm:ss.SSS');
+};
+
+var LOGGERS = [console.log.bind(console)];
+
+exports.addLogger = function(logger) {
+ LOGGERS.push(logger);
+};
+
+exports.log = function() {
+ var args = [timestamp()].concat(Array.prototype.slice.call(arguments));
+ _.forEach(LOGGERS, function(logger) {
+ logger.apply(null, args);
+ });
};
diff --git a/public/extras.css b/public/extras.css
index ac5a4f1..2edb974 100644
--- a/public/extras.css
+++ b/public/extras.css
@@ -1,3 +1,9 @@
+*,
+:before,
+:after {
+ box-sizing: border-box;
+}
+
.disp-type {
position: fixed;
top: 0;
@@ -16,3 +22,33 @@
.disp-type.syncbase {
background-color: #673ab7;
}
+
+#log {
+ position: fixed;
+ right: 0;
+ bottom: 0;
+ width: 20px;
+ height: 20px;
+ background-color: #e91e63;
+ font: 400 14px/1.4 monospace;
+ overflow-x: hidden;
+ overflow-y: scroll;
+ white-space: pre-wrap;
+ word-wrap: break-word;
+}
+
+#log .msg {
+ display: none;
+}
+
+#log:hover {
+ width: 100%;
+ height: 300px;
+ padding: 16px;
+ background-color: #fff;
+ border-top: 1px solid #000;
+}
+
+#log:hover .msg {
+ display: block;
+}
diff --git a/public/index.html b/public/index.html
index 599dcfa..9cf329c 100644
--- a/public/index.html
+++ b/public/index.html
@@ -10,6 +10,7 @@
</head>
<body>
<div id="page"></div>
+ <div id="log"></div>
<script src="/third_party/async.min.js"></script>
<script src="/third_party/lodash.min.js"></script>
<script src="/third_party/moment.min.js"></script>