node-monkey
Advanced tools
Comparing version 0.1.2 to 0.2.0
@@ -0,4 +1,12 @@ | ||
Version 0.2.0 | ||
------------- | ||
- Added profiling functionality | ||
- Added ability to send commands to the Node.js server from the web browser | ||
Version 0.1.2 | ||
------------- | ||
- Fixed a bug causing NodeMonkey to crash the app it's included in | ||
Version 0.1.1 | ||
------------- | ||
- Changed default port to 50500 | ||
@@ -5,0 +13,0 @@ - Fixed logging issue causing messages to only be sent to the client on initial connection |
@@ -41,5 +41,5 @@ (function() { | ||
logMsg(' '); | ||
logMsg('---------------------'); | ||
logMsg('Welcome to node-mokey'); | ||
logMsg('---------------------'); | ||
logMsg(' /--------------------\\'); | ||
logMsg(' Welcome to NodeMokey'); | ||
logMsg(' \\--------------------/'); | ||
}); | ||
@@ -80,2 +80,41 @@ | ||
// | ||
// -- NodeMonkey API -- | ||
// | ||
window.nm = { | ||
_cmdCall: 0, | ||
_callbacks: {}, | ||
cmd: function(cmd, args, callback) { | ||
var cmdId = ++nm._cmdCall; | ||
connection.emit('cmd', {command: cmd, args: args, cmdId: cmdId}); | ||
if(callback) { | ||
nm._callbacks[cmdId] = callback; | ||
} | ||
}, | ||
_response: function(resp) { | ||
var cb = nm._callbacks[resp.cmdId]; | ||
if(cb) { | ||
cb(resp.result); | ||
} | ||
}, | ||
profiler: { | ||
pause: function() { | ||
nm.cmd('profiler.pause'); | ||
}, | ||
resume: function() { | ||
nm.cmd('profiler.resume'); | ||
} | ||
} | ||
}; | ||
connection.on('cmdResponse', nm._response); | ||
})(); |
50
index.js
@@ -6,2 +6,3 @@ var _ = require('underscore'); | ||
//var clientJS = fs.readFileSync('./client.js'); | ||
var profiler = require('./profiler.js'); | ||
@@ -11,5 +12,27 @@ function NodeMonkey() { | ||
this.msgbuffer = []; | ||
this.profiler = new profiler(); | ||
} | ||
_.extend(NodeMonkey.prototype, { | ||
profiler: null, | ||
setConfig: function(config) { | ||
this.config = _.extend({ | ||
host: '0.0.0.0', | ||
port: '50500', | ||
suppressOutput: true, | ||
saveOutput: true, | ||
silent: false | ||
}, config || {}); | ||
this.config.profiler = _.extend({ | ||
activeOnStart: true | ||
}, this.config.profiler || {}); | ||
this.profiler.setConfig(this.config.profiler); | ||
return this; | ||
}, | ||
consoleMsg: function(type, data) { | ||
@@ -62,2 +85,4 @@ // Send to open sockets if there is at least one, otherwise buffer | ||
}; | ||
return this; | ||
}, | ||
@@ -68,9 +93,3 @@ | ||
this.config = _.extend({ | ||
host: '0.0.0.0', | ||
port: '50500', | ||
suppressOutput: true, | ||
saveOutput: true, | ||
silent: false | ||
}, config || {}); | ||
this.setConfig(config); | ||
@@ -83,4 +102,6 @@ var socketIOSrc = 'http://' + this.config.host + ':' + this.config.port + '/socket.io/socket.io.js'; | ||
res.end(clientJS); | ||
} else if(req.url == '/underscore.js') { | ||
res.end(fs.readFileSync('./node_modules/underscore/underscore-min.js')); | ||
} else { | ||
res.end('<html><head><title>Node Monkey</title><script type="text/javascript" src="' + socketIOSrc + '"></script><script type="text/javascript" src="/client.js"></script><head><body>Open your console to see output</body></html>'); | ||
res.end('<html><head><title>Node Monkey</title><script type="text/javascript" src="' + socketIOSrc + '"></script><script type="text/javascript" src="/underscore.js"></script><script type="text/javascript" src="/client.js"></script><head><body>Open your console to see output</body></html>'); | ||
} | ||
@@ -96,2 +117,7 @@ }).listen(this.config.port, this.config.host); | ||
that.trySendBuffer(); | ||
socket.on('cmd', function(cmd) { | ||
var callObj = ['that'].concat(cmd.command.split('.').slice(0, -1)).join('.'); | ||
socket.emit('cmdResponse', { cmdId: cmd.cmdId, result: eval('that.' + cmd.command + '.apply(' + callObj + ', cmd.args);') }); | ||
}); | ||
}); | ||
@@ -102,8 +128,10 @@ | ||
if(!this.config.silent) { | ||
this.clog('-------------------'); | ||
this.clog('node-monkey started'); | ||
this.clog('------------------'); | ||
this.clog('NodeMonkey started'); | ||
this.clog('To inspect output, open a browser to: http://' + this.config.host + ':' + this.config.port); | ||
this.clog('-------------------'); | ||
this.clog('------------------'); | ||
this.clog(' '); | ||
} | ||
return this; | ||
} | ||
@@ -110,0 +138,0 @@ }); |
{ | ||
"author": "Justin Warkentin <justin.warkentin@gmail.com>", | ||
"name": "node-monkey", | ||
"version": "0.1.2", | ||
"description": "A Node.js module for inspecting and debugging Node applications through a web browser", | ||
"keywords": ["inspect objects", "object inspector", "inspect", "debug", "console.log", "object"], | ||
"version": "0.2.0", | ||
"description": "A Node.js module for inspecting, profiling and debugging Node.js applications through a web browser", | ||
"keywords": ["inspect", "debug", "console.log", "profile"], | ||
"homepage": "https://github.com/jwarkentin/node-monkey", | ||
@@ -18,2 +19,2 @@ "bugs": "https://github.com/jwarkentin/node-monkey/issues", | ||
} | ||
} | ||
} |
108
README.md
@@ -1,17 +0,19 @@ | ||
Node Monkey | ||
=========== | ||
NodeMonkey | ||
========== | ||
A Node.js module for inspecting and debugging Node applications through a web browser | ||
node-monkey runs a simple server and uses [Socket.IO](https://github.com/LearnBoost/socket.io) to create a websocket connection between the browser and server. | ||
A Node.js module for inspecting and debugging Node applications through a web browser | ||
NodeMonkey runs a simple server and uses [Socket.IO](https://github.com/LearnBoost/socket.io) to create a websocket connection between the browser and server. | ||
It captures anything that would normally be logged to the terminal, converts it to JSON and passes it to the browser | ||
where it can be logged in the console for inspection. | ||
The motivation for this project came from trying to debug a Node server I wrote that used websockets. | ||
Version 0.2.0 also introduces code profiling functionality and the ability to send commands to your Node.js application from your web browser. | ||
The motivation for this project came from trying to debug a Node.js server I wrote that used websockets. | ||
I found it problematic trying to inspect objects with the terminal. | ||
I tried using the built-in debugging that works with the [Chrome Developer Tools plugin](https://github.com/joyent/node/wiki/using-eclipse-as-node-applications-debugger) for Eclipse. | ||
Unfortunately, I ran into a problem where setting breakpoints to inspect objects would cause the server to stop responding to heartbeats and cause the client to disconnect. | ||
Unfortunately, I ran into a problem where setting breakpoints to inspect objects would cause the server to stop responding to heartbeats thus causing the client to disconnect. | ||
This would entirely mess up my debugging efforts. All I really needed to do was have a good way to inspect objects. | ||
I searched Google and found projects like [node-inspector](https://github.com/dannycoates/node-inspector), which doesn't work with the latest versions of Node, and [node-codein](http://thomashunter.name/blog/nodejs-console-object-debug-inspector/) which has many bugs. | ||
And neither works with Firefox. And node-monkey was born! | ||
And neither works with Firefox. And NodeMonkey was born! | ||
@@ -28,3 +30,3 @@ Installation | ||
Using node-monkey is extremely easy. | ||
Using NodeMonkey is extremely easy. | ||
All you have to do is include the following line in your Node.js application. | ||
@@ -35,3 +37,3 @@ Anything that is logged to the console after this will show up in the browser console once connected. | ||
```javascript | ||
require('node-monkey').start([options]); | ||
var nm = require('node-monkey').start([options]); | ||
``` | ||
@@ -47,2 +49,3 @@ | ||
<script type="text/javascript" src="http://0.0.0.0:50500/client.js"></script> | ||
<script type="text/javascript" src="http://0.0.0.0:50500/underscore.js"></script> | ||
``` | ||
@@ -60,6 +63,11 @@ | ||
* **silent**: If `true` then nothing will be logged to the console when started. Default is `false`. | ||
* **profiler**: This is a nested object of options for the profiler. It's options are listed below. | ||
Examples | ||
-------- | ||
### Profiler Options | ||
* **active**: If `true`, the profiler will be enabled when NodeMonkey is included. Defaults to `true`. | ||
Note that it doesn't matter what this is set to if you never call any profiler functions. | ||
Logging Examples | ||
---------------- | ||
**Example 1** | ||
@@ -82,2 +90,78 @@ ```javascript | ||
Profiling Examples | ||
------------------ | ||
**Example 1 - Setting profiler options** | ||
```javascript | ||
var nm = require('node-monkey').setConfig({ | ||
profiler: { | ||
active: false | ||
} | ||
}); | ||
``` | ||
OR | ||
```javascript | ||
var nm = require('node-monkey'); | ||
nm.profiler.setConfig({ | ||
active: false | ||
}); | ||
``` | ||
However, the above example is equivalent to the following: | ||
```javascript | ||
var nm = require('node-monkey'); | ||
nm.profiler.pause(); | ||
// NOTE: You can reverse this by calling `nm.profiler.resume()` | ||
``` | ||
**Example 2 - Using the profiler** | ||
After you have included and configured the profiler you have a couple simple options right now. You can manually start and stop | ||
the timer allowing complete control over what is timed and what data you see in the output. | ||
```javascript | ||
// NOTE: The second parameter for `startTime()` is optional and can simply be any data you want to see | ||
// with the call data that is dumped out for this call | ||
var timer = nm.profiler.startTime('identifier', {some: 'data'}); | ||
/* [code that does stuff here] */ | ||
nm.profiler.stopTimer(timer); | ||
``` | ||
However, if you just want to profile a specific function you can call `profile()` which will return a new profiled version of the function. | ||
If you use this, you have a third parameter which, if set to `true` will cause it to save the arguments the function is called with in the | ||
profile data for each function call. | ||
```javascript | ||
var myfunc = nm.profiler.profile('identifier', function() { | ||
/* [code that does stuff here] */ | ||
}); | ||
``` | ||
Just a final note about the identifiers/keys used when timing functions. They are mainly used as a grouping mechanism. You can use the same | ||
key as many times as you want. If you want to distinguish between different calls using the same key, put something unique in the `params` | ||
argument which follows the identifier. | ||
Inspecting profiler data | ||
------------------------ | ||
Inspecting the data from the profiler is really simple. From your developer console in Firefox/Chrome/whatever else, just type something like the following: | ||
```javascript | ||
nm.cmd('profiler.getData', null, function(resp) { console.log(resp); }); | ||
``` | ||
Here are some examples of the other supported commands you can use right now: | ||
```javascript | ||
nm.cmd('profiler.pause'); | ||
nm.cmd('profiler.resume'); | ||
nm.cmd('profiler.startTime', ['test'], function(resp) { window.timerId = resp; }); | ||
/* You can even time some of your own client side code here */ | ||
nm.cmd('profiler.stopTime', [window.timerId], function() { console.log('Timer stopped'); }); | ||
``` | ||
Contribute | ||
@@ -84,0 +168,0 @@ ---------- |
14
test.js
var clog = console.log; | ||
require('./index.js').start(); | ||
var nm = require('./index.js').start(); | ||
@@ -9,3 +9,13 @@ function logObject() { | ||
setInterval(logObject, 3000); | ||
//setInterval(logObject, 3000); | ||
logObject(); | ||
// | ||
// -- Test profiling -- | ||
// | ||
(nm.profiler.profile('test function', function() { | ||
console.log('testing profiler'); | ||
}))(); | ||
console.log(nm.profiler.getData()); |
- console.trace() functionality | ||
- Provide file and line numbers to client of where console.log() was called | ||
- Pass data through to client, even if there's a fatal exception | ||
- Provide a way to send commands back to the NodeJS app | ||
- Support cyclical objects by overriding JSON.stringify() and JSON.parse(). Have a look at 'cycle.js' here: https://github.com/douglascrockford/JSON-js | ||
- Send full object representation, including function()'s | ||
- Is it possible to rebuild full objects including inheritance? |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
19621
269
196
2