Permalink
Browse files

Initial commit for process monitoring

  • Loading branch information...
0 parents commit e5853fda50bc1a733937eb63263fb0296a50ce63 @rohiniwork rohiniwork committed Sep 23, 2013
Showing with 1,403 additions and 0 deletions.
  1. +31 −0 LICENSE
  2. +74 −0 README.md
  3. +9 −0 binding.gyp
  4. +43 −0 examples/README.md
  5. +54 −0 examples/i_am_monitoring.js
  6. +32 −0 examples/monitor_me.js
  7. +18 −0 examples/package.json
  8. +169 −0 lib/monitor.js
  9. +42 −0 package.json
  10. +594 −0 src/monitor.cc
  11. +160 −0 src/monitor.h
  12. +177 −0 tests/test-monitor.js
31 LICENSE
@@ -0,0 +1,31 @@
+Copyright (c) 2013, Yahoo! Inc. All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+* Neither the name of Yahoo! Inc. nor the names of its
+ contributors may be used to endorse or promote products
+ derived from this software without specific prior
+ written permission of Yahoo! Inc.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,74 @@
+# monitor
+
+Nodejs process monitoring tool. This module currently works only on LINUX.
+This module spawns a thread and begins monitoring the process.
+
+It looks up /proc/* files on the system to report CPU Usage.
+It looks up /proc/pid/* files on the system to report its own stats.
+It calls the process.monitor.* methods to report total requests, open connections and total data transferred.
+
+process.monitor.* methods are set by lib/monitor.js.
+
+Here is the list of data the module reports periodically:
+```
+ { status:
+ { pid: <pid of the node process>,
+ ts: <current time stamp>,
+ cluster: <process group id>,
+ reqstotal: <total requests processed by this node process server>,
+ utcstart: <when the process was started>,
+ events: <number of new reports being processed since last stats reporting>,,
+ cpu: <cpu usage>,
+ mem: <memory usage>,
+ cpuperreq: <cpu usage per request>,
+ oreqs: <current open requests count>,
+ sys_cpu: <system cpu load>,
+ oconns: <current open connections count>,
+ user_cpu: <user cpu load>,
+ rps: <requests per second>,
+ kbs_out: <kbs of data transferred since last stats reporting>,
+ elapsed: <time elapsed since last event>,
+ kb_trans: <total kbs of data transferred>,
+ jiffyperreq: <cpu usage in terms of ticks per request>
+ }
+ }
+```
+
+
+# install
+
+With [npm](http://npmjs.org) do:
+
+```
+npm install monitor
+```
+
+# methods
+```js
+var monitor = require('monitor');
+```
+
+## start()
+
+```js
+monitor.start();
+```
+Spawns a thread and monitors the process. Writes process stats every second to the socket path.
+
+## stop()
+```js
+monitor.stop();
+```
+Terminates the thread and closes the socket.
+
+## setIpcMonitorPath(socketPath)
+```js
+monitor.setIpcMonitorPath('/tmp/my-process-stats.mon');
+```
+Sets the handle to write the stats to. If not specified, defaults to /tmp/nodejs.mon
+
+# example
+
+Please refer to the examples/README.md for details
+
+
@@ -0,0 +1,9 @@
+{
+ "targets": [
+ {
+ "target_name": "monitor",
+ "sources": [ "src/monitor.cc" ],
+ "cflags_cc" : ["-fexceptions"]
+ }
+ ]
+}
@@ -0,0 +1,43 @@
+# application
+In one console start the main application
+```
+node monitor_me
+```
+
+# listener
+In another console, build the listener and start it
+```
+ynpm install
+node i_am_monitoring
+```
+Now you can see the listener starts receiving messages from the application.
+
+# Invoke
+Can also invoke server a couple of times to view updated stats
+```
+curl 'http://localhost:2000'
+```
+
+# Output
+```
+ Process stats: { status:
+ { pid: 9560,
+ ts: 947819135.59,
+ cluster: 9560,
+ reqstotal: 102,
+ utcstart: 1379372564,
+ debug: 0,
+ events: 2,
+ cpu: 0,
+ mem: 0.36,
+ cpuperreq: 0,
+ oreqs: 0,
+ sys_cpu: 0,
+ oconns: 0,
+ user_cpu: 0,
+ rps: 0,
+ kbs_out: 0,
+ elapsed: 1.16,
+ kb_trans: 16.54,
+ jiffyperreq: 0 } }
+```
@@ -0,0 +1,54 @@
+var dgram = require('unix-dgram'),
+ fs = require('fs'),
+ util = require('util');
+
+/*
+ * This is the default path
+ * If you plan to edit the path, do so in both monitor_me.js and this file
+ * So that they read from the same socket
+ */
+var monPath = "/tmp/nodejs.mon";
+monitorSocket = dgram.createSocket('unix_dgram');
+monitorSocket.on('message', function (msg, rinfo) {
+ stats = JSON.parse(msg.toString());
+ console.error('Process stats: ' + util.inspect(stats, true, null));
+});
+
+fs.unlink(monPath, function () {
+ var um = process.umask(0);
+ // Bind to the socket and start listening the stats
+ monitorSocket.bind(monPath);
+ setTimeout(function () {
+ try {
+ fs.chmodSync(monPath, 511); //0777
+ } catch (e) {
+ console.log("ERROR: Could not change mod for Socket" + e.stack);
+ }
+ }, 500);
+ process.umask(um);
+});
+
+/*
+ * Sample output on the console
+ *
+ * Process stats: { status:
+ * { pid: 9560,
+ * ts: 947819135.59,
+ * cluster: 9560,
+ * reqstotal: 102,
+ * utcstart: 1379372564,
+ * debug: 0,
+ * events: 2,
+ * cpu: 0,
+ * mem: 0.36,
+ * cpuperreq: 0,
+ * oreqs: 0,
+ * sys_cpu: 0,
+ * oconns: 0,
+ * user_cpu: 0,
+ * rps: 0,
+ * kbs_out: 0,
+ * elapsed: 1.16,
+ * kb_trans: 16.54,
+ * jiffyperreq: 0 } }
+ */
@@ -0,0 +1,32 @@
+var http = require('http'),
+ monitor = require('..');
+
+/*
+ * This is the main application that will be monitored
+ * This is a simple HTTP Server
+ * monitor.start will create a thread
+ * and sends stats of the process to the socket
+ * If there is a listener on the messages on the socket
+ * The listener can get this process stats
+ */
+monitor.start();
+
+/*
+ * Start a simple http server
+ */
+http.createServer(function (req, res) {
+ res.writeHead(200, {'Content-Type': 'text/plain'});
+ res.end('I am being monitored\n');
+}).listen(2000);
+
+/*
+ * stop monitoring
+ */
+process.on('exit', function () {
+ monitor.stop();
+});
+
+// Graceful shutdown
+process.on('SIGINT', function () {
+ process.exit();
+});
@@ -0,0 +1,18 @@
+{
+ "name": "i-am-monitoring",
+ "version": "0.0.1",
+ "main": "i-am-monitoring.js",
+ "description": "Node process monitoring the main application",
+ "os": [ "linux" ],
+ "cpu": [ "x64", "ia32" ],
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/yahoo/node-monitor.git"
+ },
+ "license": "",
+ "engines": { "node": ">=0.6" },
+ "dependencies": {
+ "unix-dgram": ">=0.0.3"
+ }
+}
+
Oops, something went wrong.

0 comments on commit e5853fd

Please sign in to comment.