Using nodemonkey on production
Hey,
First of all, thanks for developing nodemonkey. I just stumbled onto this, and I am really excited to use this in our apps.
I want to use this in some of our production apps, and for that I think we will need the changes listed below. I am just about to fork this project and work on it myself. I just wanted your input on these. Do these changes make sense to you? Will you be interested in merging them back if I send PR?
Changes
Use socketio-auth for security
https://www.npmjs.com/package/socketio-auth
User can maybe provide some options like this:
{
"users": [
{
"user": "userid",
"password": "password"
}
]
}
Then the page that hosts debugger (client.html or custom page), will need to provide user and password to use (window.nomoUser, window.nomoPassword). client.js will use this user and password to authenticate socket.io.
Allow for light weight start() and stop() functions
User will want to enable debugger dynamically in production. No point in running debugger when you are not using it.
I, for example, would want to create some endpoint like this in my server:
POST /debugger
headers:
enable: 0/1
token: "some predetermined token"
this will call nomo.start or stop
For above reasons, lightweight version of start will be needed.
Current start():
- uses fs.readFileSync variants to read files for serving them
- generates template for client.js from provided options
Need to divide that into two functions.
init():
- sets config
- reads client.js. uses template and options to dynamically generate client.out.js
start():
- uses fs.readFile variants to serve needed files
- uses client.out.js instead of client.js
- adds proper cache headers for all js files, except client.out.js
- starts server and io. and do the rest
Allow for limits on msgbuffer array in server side
Currently it will keep growing if no active sockets are there. We can provide option "serverMaxBuffer" and use it to maintain msgbuffer size.
An optional enhancement in client.js
It will be helpful if we can filter messages to be logged in browser's console. For example, in our apps we have dedicated debugger functions for different modules. They emebed moduleId along with current date to all the logged messages.
If we can provide a filter function to client.js, each developer will be able to see just the messages that they are interested in.
client.js can check if window.nomoFilterMessages function exists, and use it to filter messages.
Along with "users" option, we can provide "authorize" option.
{
"authorize": function(user, password, callback) {}
}
Sorry I didn't get to this sooner. I'm normally pretty responsive but work has been busy. I never finished the work I was doing on the v0.3.0 branch but that already supports a full user and auth system. Unfortunately the docs on that branch haven't been rewritten yet. I really need to take a few days and tackle the rewrite. I don't know if anything on that branch would run anymore, especially with the latest version of node, but it's worth a shot.
Starting and stopping debugger
As for enabling and disabling the debugger in production it already supports that if you do something like this:
nomo.registerCommand({
command: 'startDebug',
callback: function() { nomo.start.apply(nomo, Array.prototype.slice.call(arguments)); }
});
nomo.registerCommand({
command: 'stopDebug',
callback: function() { nomo.stop(); }
});
And then in the browser you can do this:
nomo.cmd('startDebug', function(response, error) {
console.log(response, error);
});
If you want to pass options to the nomo.start() call you would then just pass an array with an options object as the second argument to nomo.cmd().
msgbuffer limit
This is already support by passing the clientMaxBuffer option like so:
nomo.start({
clientMaxBuffer: 50
});
It already defaults to 50 though.
The new release supports authentication for production environments and provides both a browser and SSH interface for access. I want to flesh out the filtering concept more and then drop that in this weekend. Is your goal to send different messages to different web clients based on which user is authenticated?
Hey,
I ended up not trying this till now. About the filtering, I just wanted some kind of channels I guess. A large app will have a lot of module working together, and developers might be interested in the log messages just for their own module. So channels will make sense in cases like this. On web client side, dev might just filter the logs he is interested in (based on channels).
Ok, I've given this some thought and here's my proposal. Let me know what you think.
The server builds an object that it sends to the client with all the information the client needs to display the messages how it wants. So, I can let you set a function that gets called for all messages before they go to the server and it can set filters on that object like so:
let monkey = require('node-monkey')({
events: {
beforeSend: (message) => {
let matches = message.args[0].match(/\[(\w+?) module\]/)
if (matches) {
message.filter = {
module: matches[1]
}
}
}
}
})
console.log('[test module] Some text')
console.log('[auth module] Different text')
And then on the client to just see the 'auth' module messages you could do:
monkey.filter({ module: 'auth' })
Of course, this gives you the flexibility to filter however you want. For example, you could instead look for a second argument that's an object instead and filter by that:
let monkey = require('node-monkey')({
events: {
beforeSend: (message) => {
message.filter = message.args[1]
message.args[1] = undefined
}
}
})
console.log('Some text', { module: 'test' })
console.log('Different text', { module: 'auth' })