Skip to content

Commit

Permalink
Interim logging solution until streams are setup.
Browse files Browse the repository at this point in the history
  • Loading branch information
DanBUK committed Jul 26, 2011
1 parent 5f027c6 commit ce9cb13
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 93 deletions.
41 changes: 21 additions & 20 deletions lib/app.js
Expand Up @@ -14,29 +14,30 @@ module.exports = {
var appname = req.appname;
var user = req.user;
var app = req.app;
var app_error_log = path.join(config.opt.apps_home_dir, user._id, app.repo_id + '_rw', 'app', 'error.log');
fs.readFile(app_error_log, function(err, body) {
var code = 200,
resp;
if (err) {
code = 500;
resp = {
success: false,
error: "Failed to read error log."
};
} else {
var lines = body.toString().split("\n");
lines = lines.slice(-100);
resp = {
var app_error_log_sock = path.join(config.opt.apps_home_dir, user._id, app.repo_id + '_chroot', '.nodester', 'logs.sock');
var net = require('net');
var app_handler = net.createConnection(app_error_log_sock);
app_handler.once('connect', function () {
var buff = '';
app_handler.on('data', function (data) {
buff += data.toString();
});
app_handler.once('end', function () {
try {
var logs_strs = JSON.parse(buff);
} catch (e) {
var logs_strs = {stdout: 'no logs', stderr: ''};
}
var lines = ('stdout:\n' + logs_strs['stdout'] + '\nstderr:\n' + logs_strs['stderr']).toString().split('\n');
res.writeHead(200, {
'Content-Type': 'application/json'
});
res.write(JSON.stringify({
success: true,
lines: lines
};
}
res.writeHead(code, {
'Content-Type': 'application/json'
}) + '\n');
res.end();
});
res.write(JSON.stringify(resp) + '\n');
res.end();
});
},
gitreset: function(req, res, next) {
Expand Down
183 changes: 110 additions & 73 deletions scripts/chroot_runner.js
Expand Up @@ -3,10 +3,10 @@
require.paths.unshift('/usr/lib/node_modules');

var spawn = require('child_process').spawn;
var daemon = require('daemon');
var daemon = require('daemon.js');
var fs = require('fs');
var path = require('path');

var net = require('net');

var config = JSON.parse(fs.readFileSync(path.join('.nodester', 'config.json'), encoding='utf8'));

Expand All @@ -17,24 +17,55 @@ var run_count = 0;
var LOG_STDOUT = 1;
var LOG_STDERR = 2;

var error_log_fd = null;
// var error_log_fd = null;

var pre_shutdown = function () {
if (typeof error_log_fd != 'null') fs.closeSync(error_log_fd);
// if (typeof error_log_fd != 'null') fs.closeSync(error_log_fd);
};

var log_lines_stdout = new Array();
var log_lines_stderr = new Array();

var log_listen = function (p, cb) {
var srv = net.createServer(function (conn) {
var logs = JSON.stringify({
stdout: log_lines_stdout.join('\n'),
stderr: log_lines_stderr.join('\n')
});
conn.write(logs);
conn.end();
});
srv.listen(p, cb);
};

var log_line = function (line, stdout) {
if (typeof this == 'string') {
line = this + line;
switch (this) {
case 'chroot_runner':
log_lines_stderr.push(this + ': ' + line);
if (log_lines_stderr.length > 10) log_lines_stderr.shift();
break;
case 'stdout':
log_lines_stdout.push(line);
if (log_lines_stdout.length > 10) log_lines_stdout.shift();
break;
case 'stderr':
log_lines_stderr.push(line);
if (log_lines_stderr.length > 10) log_lines_stderr.shift();
break;
}
}
/*
if (typeof stdout != 'undefined') {
if (stdout == LOG_STDOUT) {
console.log(line);
} else if (stdout == LOG_STDERR) {
console.error(line);
}
}
if (error_log_fd !== null) fs.write(error_log_fd, line + '\n');
*/
// if (error_log_fd !== null) fs.write(error_log_fd, line + '\n');

};

var env = {
Expand All @@ -49,76 +80,82 @@ if (config.env) {
env.app_port = parseInt(config.port, 10);
env.app_host = config.ip;
var args = ['/app/' + config.start];

var chroot_res = daemon.chroot(config.appchroot);
if (chroot_res !== true) {
log_line('chroot_runner: ', 'Failed to chroot to ' + config.apphome, LOG_STDERR);
pre_shutdown();
process.exit(1);
}
var ch_uid = daemon.setreuid(config.userid);
if (ch_uid !== true) {
log_line.call('chroot_runner: ', 'Failed to change user to ' + config.userid, LOG_STDERR);
pre_shutdown();
process.exit(2);
}
var child = null;
var child_watcher_time = null;

var myPid = daemon.start();
log_line.call('chroot_runner: ', 'New PID: ' + myPid.toString());
if (path.existsSync('/.nodester/pids/runner.pid')) fs.unlinkSync('/.nodester/pids/runner.pid');
fs.writeFileSync('/.nodester/pids/runner.pid', myPid.toString());

process.on('SIGINT', function () {
log_line.call('chroot_runner: ', 'SIGINT recieved, sending SIGTERM to children.');
if (child !== null) {
log_line.call('chroot_runner: ', 'Child PID: ' + child.pid.toString());
process.kill(child.pid, 'SIGTERM');
process.exit();
} else {
process.exit();
var log_sock_path = path.join(config.appchroot, '.nodester', 'logs.sock');
log_listen(log_sock_path, function () {
try {
fs.chmodSync(log_sock_path, '0777');
} catch (e) {
log_line('chroot_runner', 'Failed to chmod logs.sock', LOG_STDERR);
}
});

process.on('SIGTERM', function () {
log_line.call('chroot_runner: ', 'SIGTERM recieved, sending SIGTERM to children.');
if (child !== null) {
log_line.call('chroot_runner: ', 'Child PID: ' + child.pid.toString());
process.kill(child.pid, 'SIGTERM');
process.exit();
} else {
process.exit();
log_line('chroot_runner', 'log_listen\'ing', LOG_STDERR);
var chroot_res = daemon.chroot(config.appchroot);
if (chroot_res !== true) {
log_line('chroot_runner', 'Failed to chroot to ' + config.apphome, LOG_STDERR);
pre_shutdown();
process.exit(1);
}
});
var ch_uid = daemon.setreuid(config.userid);
if (ch_uid !== true) {
log_line.call('chroot_runner', 'Failed to change user to ' + config.userid, LOG_STDERR);
pre_shutdown();
process.exit(2);
}
var child = null;
var child_watcher_time = null;

var myPid = daemon.start();
log_line.call('chroot_runner', 'New PID: ' + myPid.toString());
if (path.existsSync('/.nodester/pids/runner.pid')) fs.unlinkSync('/.nodester/pids/runner.pid');
fs.writeFileSync('/.nodester/pids/runner.pid', myPid.toString());

var start_child = function () {
child = spawn('/usr/bin/node', args, { env: env });
child.stdout.on('data', log_line.bind('stdout: '));
child.stderr.on('data', log_line.bind('stderr: '));
child.on('exit', function (code) {
if (code > 0 && run_count > run_max) {
log_line.call('Watcher: ', 'Error: Restarted too many times, bailing.', LOG_STDERR);
clearInterval(child_watcher_timer);
pre_shutdown();
process.exit(3);
} else if (code > 0) {
log_line.call('Watcher: ', 'Process died with exit code ' + code + '. Restarting...', LOG_STDERR);
child = null;
process.on('SIGINT', function () {
log_line.call('chroot_runner', 'SIGINT recieved, sending SIGTERM to children.');
if (child !== null) {
log_line.call('chroot_runner', 'Child PID: ' + child.pid.toString());
process.kill(child.pid, 'SIGTERM');
process.exit();
} else {
log_line.call('Watcher: ', 'Process exited cleanly. Dieing.', LOG_STDERR);
clearInterval(child_watcher_timer);
pre_shutdown();
process.exit(0);
process.exit();
}
});
};
var child_watcher = function () {
if (child === null) {
start_child();
run_count++;
}
};
if (path.existsSync('/app/error.log')) fs.unlinkSync('/app/error.log');
error_log_fd = fs.openSync('/app/error.log', 'w', '0777');
child_watcher_timer = setInterval(child_watcher, 750);

process.on('SIGTERM', function () {
log_line.call('chroot_runner', 'SIGTERM recieved, sending SIGTERM to children.');
if (child !== null) {
log_line.call('chroot_runner', 'Child PID: ' + child.pid.toString());
process.kill(child.pid, 'SIGTERM');
process.exit();
} else {
process.exit();
}
});

var start_child = function () {
child = spawn('/usr/bin/node', args, { env: env });
child.stdout.on('data', log_line.bind('stdout'));
child.stderr.on('data', log_line.bind('stderr'));
child.on('exit', function (code) {
if (code > 0 && run_count > run_max) {
log_line.call('Watcher', 'Error: Restarted too many times, bailing.', LOG_STDERR);
clearInterval(child_watcher_timer);
pre_shutdown();
process.exit(3);
} else if (code > 0) {
log_line.call('Watcher', 'Process died with exit code ' + code + '. Restarting...', LOG_STDERR);
child = null;
} else {
log_line.call('Watcher', 'Process exited cleanly. Dieing.', LOG_STDERR);
clearInterval(child_watcher_timer);
pre_shutdown();
process.exit(0);
}
});
};
var child_watcher = function () {
if (child === null) {
start_child();
run_count++;
}
};
child_watcher_timer = setInterval(child_watcher, 750);
});

0 comments on commit ce9cb13

Please sign in to comment.