Open sanchezih opened 10 years ago
Hello Ignacio,
If you've used Java, you can think of node-monitor as JMX beans. You install node-monitor on the system you want to monitor, and the remote system can view and interact with node-monitor.
It's best to start simple - with node-monitor (less the dashboard). Have you gone through the README and seen the process stats (freemem, cpu stats) using node-monitor only?
-Loren
Thanks for your response Loren. Yes, I've already read the example, that works very good, but now I need to know how can count the http requests that my node app receives, but I don't know how do this. I've tried with StatProbe and InspectProbe, but I don't understand how it works. There is a possibility that you show some example?
Thanks for your time. Ignacio.
For http requests, the question is - how do you want your data aggregated. The stats probe is good for viewing all stats as they're fired, but it doesn't yet do aggregation.
The quickest (and dirtiest) way to get this done is to create a handful of variables off the global namespace to contain the aggregations you care about (5 minute, 1 hour, by http method, by endpoint, etc.). Add to these variables in your http request pipeline, and clear them on a timer if they're periodic aggregations.
Then use the InspectProbe to inspect these variables.
Let me know if that makes any sense :) -Loren
Great. I have the following:
var inspectOptions = { hostName: 'localhost', probeClass: 'Inspect', initParams: { key:global.http_requests, pollInterval: 10000 } } var inspectMonitor = new Monitor(inspectOptions); inspectMonitor.on('change', function() { var xxx =inspectMonitor.get('value'); console.log(xxx); }); inspectMonitor.connect(function(error) { if (error) { console.error('Error connecting with the process probe: ', error); process.exit(1); } });
I want to get the value of http_requests variable, defined in my app, but I can't. Can you help me?
So your app (running in a different process, maybe a different server) has a global variable called global.http_requests, and it also has node-monitor linked in and started.
From the other app (running on the same machine or on another machine), you have to connect to the correct node process. Everything looks good except your key variable is global.http_requests, which, if evaluated locally is likely to return undefined
. Place quotes around the key:'global.http_requests' and see if that works better.
You're right Loren, when I put the quotes around the key, I get undefined. Is that because the hostName is localhost?
It's because both processes are on localhost, and it connected with the closest inspector probe, which happened to be running in your client. To verify, set global.http_requests
in the client to something like "hello world", and run again.
If that's the case, you have to differentiate the two processes - either by running them on different machines, or by naming the processes.
To configure your app with a name, add the following to your config/default.json
configuration file in your server app:
{
Monitor: {
appName: 'YourAppServerName'
}
}
Then when you connect from your client, do this:
var inspectOptions = {
hostName: 'localhost',
appName: 'YourAppServerName',
probeClass: 'Inspect',
...
Now I'm trying to run your Monitoring example from another machine into the LAN, but Isn't work. I added node-config to my app and my script.
var options = { hostName: '192.168.0.1:9000', appName: 'YourAppServerName', probeClass: 'Process', initParams: { pollInterval: 10000 } }
The :9000
shouldn't be specified, as node-monitor uses other ports by default (in the 42,000 range).
The other thing about connecting one machine to another is security. By default, node-monitor only accepts incoming connections on localhost. In order to allow it to connect from another machine, you have to configure this in your config/default.json file:
{
Monitor: {
appName: 'YourAppServerName',
allowExternalConnections: true
}
}
The reason it's disabled by default is to have you think about your network security before allowing external connections. Generally your network isn't exposing ports in the 42,000 range to the outside world, but it's good to think about security before opening up your servers for external monitoring & control.
Great! I have seen the freemem from another machine using your example. But now I wish I could see a global variable in my app.
--config/default.json { "Monitor": { "appName": "YourAppServerName", "allowExternalConnections": "true" } }
--monitorScript.js
var Monitor = require('monitor'); var options = { hostName: '192.168.0.1', appName: 'YourAppServerName', probeClass: 'Inspect', initParams: { key:'global.http_requests', pollInterval: 10000 } }
var inspectMonitor = new Monitor(inspectOptions);
// Attach the change listener inspectMonitor.on('change', function() { console.log(inspectMonitor.get('value')); });
// Now connect the monitor inspectMonitor.connect(function(error) { if (error) { console.error('Error connecting with the Inspect probe: ', error); process.exit(1); } });
Thank you very much Loren.
Everything looks right. You're monitoring the variable every 10 seconds, and triggering console.log
when the value changes. Is that value changing in your server?
Yes, the value changes. When I evaluate if isModel I get false
console.log(inspectMonitor.get('isModel'));
Should I get true?
Unless global.http_requests
is a backbone data model, you should be getting false
returned from inspectMonitor.get('isModel').
What do you see when you do console.log(inspectMonitor.toJSON())
?
{ hostName: '10.10.10.212', appName: 'YourAppServerName', probeClass: 'Inspect', initParams: { key: undefined, pollInterval: 10000 }, id: '', name: '', probeName: '', appInstance: '', probeId: '3cef7531-1d1b-8137-ad1c-edcba1a7fa5d', writableAttributes: [ 'value' ], pollInterval: 10000, cronPattern: '* * * * * *', value: { ArrayBuffer: '[Function]', Int8Array: { constructor: '[Function]', BYTES_PER_ELEMENT: 1 }, Uint8Array: { constructor: '[Function]', BYTES_PER_ELEMENT: 1 }, Uint8ClampedArray: { constructor: '[Function]', BYTES_PER_ELEMENT: 1 }, Int16Array: { constructor: '[Function]', BYTES_PER_ELEMENT: 2 }, Uint16Array: { constructor: '[Function]', BYTES_PER_ELEMENT: 2 }, Int32Array: { constructor: '[Function]', BYTES_PER_ELEMENT: 4 }, Uint32Array: { constructor: '[Function]', BYTES_PER_ELEMENT: 4 }, Float32Array: { constructor: '[Function]', BYTES_PER_ELEMENT: 4 }, Float64Array: { constructor: '[Function]', BYTES_PER_ELEMENT: 8 }, DataView: '[Function]', global: { ArrayBuffer: '[Function]', Int8Array: '[Function]', Uint8Array: '[Function]', Uint8ClampedArray: '[Function]', Int16Array: '[Function]', Uint16Array: '[Function]', Int32Array: '[Function]', Uint32Array: '[Function]', Float32Array: '[Function]', Float64Array: '[Function]', DataView: '[Function]', global: '[Object]', process: '[Object]', GLOBAL: '[Object]', root: '[Object]', Buffer: '[Function]', setTimeout: '[Function]', setInterval: '[Function]', clearTimeout: '[Function]', clearInterval: '[Function]', setImmediate: '[Function]', clearImmediate: '[Function]', console: '[Object]', NODE_CONFIG: '[Object]', Monitor: '[Function]', empresa: '[Object]', local: '[Object]' }, process: { title: 'node', version: 'v0.10.25', moduleLoadList: '[Array]', versions: '[Object]', arch: 'x64', platform: 'linux', argv: '[Array]', execArgv: '[Array]', env: '[Object]', pid: 5951, features: '[Object]', _needImmediateCallback: false, execPath: '/usr/bin/nodejs', debugPort: 5858, _getActiveRequests: '[Function]', _getActiveHandles: '[Function]', _needTickCallback: '[Function]', reallyExit: '[Function]', abort: '[Function]', chdir: '[Function]', cwd: '[Function]', umask: '[Function]', getuid: '[Function]', setuid: '[Function]', setgid: '[Function]', getgid: '[Function]', getgroups: '[Function]', setgroups: '[Function]', initgroups: '[Function]', _kill: '[Function]', _debugProcess: '[Function]', _debugPause: '[Function]', _debugEnd: '[Function]', hrtime: '[Function]', dlopen: '[Function]', uptime: '[Function]', memoryUsage: '[Function]', binding: '[Function]', _usingDomains: '[Function]', _tickInfoBox: '[Object]', _events: '[Object]', domain: '[Object]', _maxListeners: 10, EventEmitter: '[Function]', _fatalException: '[Function]', _exiting: false, assert: '[Function]', config: '[Object]', nextTick: '[Function]', _nextDomainTick: '[Function]', _tickCallback: '[Function]', _tickDomainCallback: '[Function]', _tickFromSpinner: '[Function]', maxTickDepth: 1000, stdout: '[Object]', stderr: '[Object]', stdin: '[Object]', openStdin: '[Function]', exit: '[Function]', kill: '[Function]', addListener: '[Function]', on: '[Function]', removeListener: '[Function]', mainModule: '[Object]', _errno: 'EOF' }, GLOBAL: { ArrayBuffer: '[Function]', Int8Array: '[Function]', Uint8Array: '[Function]', Uint8ClampedArray: '[Function]', Int16Array: '[Function]', Uint16Array: '[Function]', Int32Array: '[Function]', Uint32Array: '[Function]', Float32Array: '[Function]', Float64Array: '[Function]', DataView: '[Function]', global: '[Object]', process: '[Object]', GLOBAL: '[Object]', root: '[Object]', Buffer: '[Function]', setTimeout: '[Function]', setInterval: '[Function]', clearTimeout: '[Function]', clearInterval: '[Function]', setImmediate: '[Function]', clearImmediate: '[Function]', console: '[Object]', NODE_CONFIG: '[Object]', Monitor: '[Function]', empresa: '[Object]', local: '[Object]' }, root: { ArrayBuffer: '[Function]', Int8Array: '[Function]', Uint8Array: '[Function]', Uint8ClampedArray: '[Function]', Int16Array: '[Function]', Uint16Array: '[Function]', Int32Array: '[Function]', Uint32Array: '[Function]', Float32Array: '[Function]', Float64Array: '[Function]', DataView: '[Function]', global: '[Object]', process: '[Object]', GLOBAL: '[Object]', root: '[Object]', Buffer: '[Function]', setTimeout: '[Function]', setInterval: '[Function]', clearTimeout: '[Function]', clearInterval: '[Function]', setImmediate: '[Function]', clearImmediate: '[Function]', console: '[Object]', NODE_CONFIG: '[Object]', Monitor: '[Function]', empresa: '[Object]', local: '[Object]' }, Buffer: { constructor: '[Function]', isEncoding: '[Function]', poolSize: 8192, isBuffer: '[Function]', byteLength: '[Function]', concat: '[Function]', _charsWritten: 261 }, setTimeout: '[Function]', setInterval: '[Function]', clearTimeout: '[Function]', clearInterval: '[Function]', setImmediate: '[Function]', clearImmediate: '[Function]', console: { log: '[Function]', info: '[Function]', warn: '[Function]', error: '[Function]', dir: '[Function]', time: '[Function]', timeEnd: '[Function]', trace: '[Function]', assert: '[Function]', Console: '[Function]' }, NODE_CONFIG: { Monitor: '[Object]', watch: '[Function]', setModuleDefaults: '[Function]', makeHidden: '[Function]', makeImmutable: '[Function]', watchForConfigFileChanges: '[Function]', safeWriteFile: '[Function]', getConfigSources: '[Function]', _persistConfigsOnChange: '[Function]', _loadFileConfigs: '[Function]', _loadOldStyleEnv: '[Function]', _parseFile: '[Function]', _attachProtoDeep: '[Function]', _cloneDeep: '[Function]', _equalsDeep: '[Function]', _diffDeep: '[Function]', _extendDeep: '[Function]', _stripYamlComments: '[Function]', _stripComments: '[Function]', _isObject: '[Function]', getOriginalConfig: '[Function]', resetRuntime: '[Function]', _initParam: '[Function]', getCmdLineArg: '[Function]' }, Monitor: { constructor: '[Function]', extend: '[Function]', super: '[Object]', generateUniqueId: '[Function]', generateUniqueCollectionId: '[Function]', getRouter: '[Function]', start: '[Function]', stop: '[Function]', toServerString: '[Function]', deepCopy: '[Function]', stringify: '[Function]', setStatLoggerClass: '[Function]', setLoggerClass: '[Function]', List: '[Function]', Config: '[Object]', : '[Function]', Backbone: '[Object]', Cron: '[Object]', commonJS: true, Stat: '[Function]', getStatLogger: '[Function]', Log: '[Function]', getLogger: '[Function]', Probe: '[Function]', Connection: '[Function]', Server: '[Function]', Router: '[Function]', Sync: '[Function]', DataModelProbe: '[Function]', RecipeProbe: '[Function]', PollingProbe: '[Function]', StreamProbe: '[Function]', InspectProbe: '[Function]', StatProbe: '[Function]', LogProbe: '[Function]', FileProbe: '[Function]', ReplProbe: '[Function]', ProcessProbe: '[Function]', SyncProbe: '[Function]', defaultServer: '[Object]', defaultRouter: '[Object]' }, empresa: { INCIADA: 0, INCOMPLETA: 1, ERROR: 2, COMPLETA: 3, CERRADA: 4 }, local: { ABIERTO: 0, COMPLETO: 1, CERRADO: 2, MODIFICADO: 3, VALIDADO: 4 } }, isModel: false }
The fact that key: undefined
is in your initParams tells me that you've forgotten to put quotes around global.http_requests
. The value
you're seeing is your entire global namespace (!).
If you are putting quotes around global.http_requests
in your init params, it could be that global.http_requests really is undefined in your server.
Can you show me a little example how I should define my variable to see its value using Inspect?
Thank you in advance :)
Yes:
var inspectOptions = {
hostName: '10.10.10.212',
appName: 'YourAppServerName',
probeClass: 'Inspect',
initParams: {
key: 'global.http_requests',
pollInterval: 10000
}
}
var inspectMonitor = new Monitor(inspectOptions);
Notice the quotes around 'global.http_requests'
. That's to make sure the variable is evaluated on the server, and not on the client when inspectOptions is declared.
Hi Loren,
I have the following code:
var inspectMonitor = new Monitor({ hostName:'192.168.20.122', probeClass: 'Inspect', initParams: { key: 'global.http_requests', pollInterval: 10000 } });
inspectMonitor.on('change', function () {
var xxx = inspectMonitor.get('value');
console.log(inspectMonitor.toJSON());
});
inspectMonitor.connect(function (error) {
console.log('Inspect probe connected.');
if (error) {
console.error('Error connecting with the inspect probe: ', error);
process.exit(1);
}
});
..and output:
Inspect probe connected. { hostName: '192.168.20.122', probeClass: 'Inspect', initParams: { key: 'global.http_requests', pollInterval: 10000 }, id: '', name: '', probeName: '', appName: '', appInstance: '', probeId: '4092dcdb-d9dd-47b8-5d00-09bb69f027cd', writableAttributes: [ 'value' ], key: 'global.http_requests', pollInterval: 10000, cronPattern: '* * * * * *', value: undefined, isModel: false }
It seems that "value" is undefined as shown, can you please advise?
Hi Loren, I'd like to know if you can help me with node-monitor and monitor-dashboard. I need to monitoring a node app, specifically http requests and the node server cluster status (freemem, cpu status) and be able to see this information in monitor-dashboard. I tried to do this by reading your code, but I can't.
Hope you help me. Thanks! Ignacio.