Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

ENYO-2090:add log-to file & smart loging to the ide server #246

Merged
merged 5 commits into from

2 participants

@asnowfix
Owner
  • server-siode code only: no test needed in the browser
  • developed & tested on OSX

  • ENYO-2047: remove non-existing temp files from .gitignore (HEAD, enyojs/ENYO-2090, ENYO-2090)

  • ENYO-2090: replace console.log by npmlog & allow log to file
  • ENYO-2090: Add a dependency on npmlog

Enyo-DCO-1.1-Signed-off-by: Francois-Xavier KOWALSKI francois-xavier.kowalski@hp.com

asnowfix added some commits
@asnowfix asnowfix ENYO-2090: Add a dependency on npmlog
- add to package.json
- re-run `npm shrinkwrap`

Enyo-DCO-1.1-Signed-off-by: Francois-Xavier KOWALSKI <francois-xavier.kowalski@hp.com>
8493e63
@asnowfix asnowfix ENYO-2090: replace console.log by npmlog & allow log to file
- replace '-v' option by `--level XXX` to use npmlog
- add `-L` option to active logging to a file `ide.log`
- update usage instructions accordingly, add bug reporting instructions

Enyo-DCO-1.1-Signed-off-by: Francois-Xavier KOWALSKI <francois-xavier.kowalski@hp.com>
84f9f18
@asnowfix asnowfix ENYO-2047: remove non-existing temp files from `.gitignore`
- This is no longer needed, so we prefer that Git has a real view on the
  workspace.

Enyo-DCO-1.1-Signed-off-by: Francois-Xavier KOWALSKI <francois-xavier.kowalski@hp.com>
497ce07
ide.js
@@ -64,23 +74,26 @@ if (argv.help) {
process.exit(0);
}
-function log() {
- if (argv.verbose) {
- var arg, msg = arguments.callee.caller.name + '(): ';
- for (var argi = 0; argi < arguments.length; argi++) {
- arg = arguments[argi];
- if (typeof arg === 'object') {
- msg += util.inspect(arg);
- } else {
- msg += arg;
- }
- msg += ' ';
+log.level = argv.level || 'http';
+if (argv.out) {
@yves-del-medico Owner

It should be argv.log instead of argv.out.

So "node ide.js --log" or "node ide.js -L" does not generate an ide.log

@asnowfix Owner

good catch. it use to be out on my dev branch...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
ide.js
((26 lines not shown))
return function(data){
- console.log("> Service['"+service.id+"']: "+data);
+ log.warn(service.id, data);
@yves-del-medico Owner

Data is shown as a byte array which is not useful.

ares WARN home

@asnowfix Owner

_ ares WARN home_ ?

@asnowfix Owner

Trampoline are now log.xxx(yyy, data.toString())

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
ide.js
((14 lines not shown))
}
};
}
-function serviceEcho(service) {
+function serviceOut(service) {
+ return function(data){
+ log.info(service.id, data);
@yves-del-medico Owner

Default level (http )is not enough to log message coming from sub-processes.

Data is displayed as a byte array.

@asnowfix Owner

Will use http as the log-level for messages coming from the sub-processes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
ide.js
((6 lines not shown))
}
// Exit path
-console.info("Press CTRL + C to shutdown");
+log.info('main', "Press CTRL + C to shutdown");
process.on('uncaughtException', function (err) {
console.error(err.stack);
@yves-del-medico Owner

Should also go thru npmlog

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@asnowfix asnowfix ENYO-2090: Fix review comments
Enyo-DCO-1.1-Signed-off-by: Francois-Xavier KOWALSKI <francois-xavier.kowalski@hp.com>
e65b900
@asnowfix
Owner
  1. review comments fixed
  2. tested on win7/x64

ready to merge

@yves-del-medico yves-del-medico merged commit 597ffca into master
@yves-del-medico

Merged

@yves-del-medico

I forgot one comment; color should be disabled when -L or --log is specified.
This is true for ide.js and sub-processes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 29, 2013
  1. @asnowfix

    ENYO-2090: Add a dependency on npmlog

    asnowfix authored
    - add to package.json
    - re-run `npm shrinkwrap`
    
    Enyo-DCO-1.1-Signed-off-by: Francois-Xavier KOWALSKI <francois-xavier.kowalski@hp.com>
  2. @asnowfix

    ENYO-2090: replace console.log by npmlog & allow log to file

    asnowfix authored
    - replace '-v' option by `--level XXX` to use npmlog
    - add `-L` option to active logging to a file `ide.log`
    - update usage instructions accordingly, add bug reporting instructions
    
    Enyo-DCO-1.1-Signed-off-by: Francois-Xavier KOWALSKI <francois-xavier.kowalski@hp.com>
  3. @asnowfix

    ENYO-2047: remove non-existing temp files from `.gitignore`

    asnowfix authored
    - This is no longer needed, so we prefer that Git has a real view on the
      workspace.
    
    Enyo-DCO-1.1-Signed-off-by: Francois-Xavier KOWALSKI <francois-xavier.kowalski@hp.com>
  4. @asnowfix
Commits on Mar 30, 2013
  1. @asnowfix

    ENYO-2090: Fix review comments

    asnowfix authored
    Enyo-DCO-1.1-Signed-off-by: Francois-Xavier KOWALSKI <francois-xavier.kowalski@hp.com>
This page is out of date. Refresh to see the latest.
View
1  .gitignore
@@ -27,4 +27,3 @@ $*
/node_modules/temp
/node_modules/tunnel
/node_modules/zipstream
-/test/root
View
22 README.md
@@ -108,11 +108,15 @@ Get more information about the options using `-h` or `--help`:
Usage: "node ./ide.js" [OPTIONS]
Options:
- -h, --help help message [boolean]
- -T, --runtest Run the non-regression test suite [boolean]
- -b, --browser Open the default browser on the Ares URL [boolean]
- -p, --port port (o) local IP port of the express server (default: 9009, 0: dynamic) [default: "9009"]
- -H, --host host to bind the express server onto (default: 127.0.0.1) [default: "127.0.0.1"]
+ -h, --help help message [boolean]
+ -T, --runtest Run the non-regression test suite [boolean]
+ -b, --browser Open the default browser on the Ares URL [boolean]
+ -p, --port port (o) local IP port of the express server (default: 9009, 0: dynamic) [default: "9009"]
+ -H, --host host to bind the express server onto [default: "127.0.0.1"]
+ -a, --listen_all When set, listen to all adresses. By default, listen to the address specified with -H [boolean]
+ -c, --config IDE configuration file [default: "/Users/kowalskif/Desktop/GIT/enyojs/ares-project/ide.json"]
+ -l, --level IDE debug level ('silly', 'verbose', 'info', 'http', 'warn', 'error') [default: "http"]
+ -L, --log Log IDE debug to ./ide.log [boolean]
Optionally, configure the `root` of your local file-system access in `ide.json`. By default, the local filesystem service serves the files from your _Home_ or _My Documents_ directory, depending on your operating system. You might want to change this to point to the location of your project files, to make navigation faster & easier.
@@ -125,6 +129,14 @@ For instance, you can change `@HOME@` to `@HOME@/Documents` or to `D:\\Users\\Us
],
[...]
+#### Reporting Issues
+
+Be sure to run Ares with `--log` (or `-L`) to capture the Ares server output in the file name `ide.log`. Attach this log-file to you bug report on the [ARES JIRA](https://enyojs.atlassian.net/browse/ENYO/component/10302).
+
+You may also want to increase the log verbosity, in order to better understand what is going wrong by yourself. The default verbosity level is `http`. You may want o increase to `info` or even `verbose`. Lowest layer `silly` is usually for Ares core developers.
+
+ $ node ide.js --level=info
+
### Build
In order to produce Ares on a build server:
View
143 ide.js
@@ -8,6 +8,7 @@ require('./hermes/lib/checkNodeVersion'); // Check nodejs version
var fs = require("fs"),
path = require("path"),
express = require("express"),
+ npmlog = require('npmlog'),
optimist = require("optimist"),
util = require('util'),
spawn = require('child_process').spawn,
@@ -16,6 +17,10 @@ var fs = require("fs"),
var myDir = typeof(__dirname) !== 'undefined' ? __dirname : path.resolve('') ;
var HttpError = require(path.resolve(myDir, "hermes/lib/httpError"));
+var log = npmlog;
+log.heading = 'ares';
+log.level = 'warn';
+
var argv = optimist.usage('\nAres IDE, a front-end designer/editor web applications.\nUsage: "$0" [OPTIONS]\n')
.options('h', {
alias : 'help',
@@ -52,9 +57,14 @@ var argv = optimist.usage('\nAres IDE, a front-end designer/editor web applicati
description: 'IDE configuration file',
default: path.resolve(myDir, "ide.json")
})
- .options('v', {
- alias : 'verbose',
- description: 'Increase IDE verbosity in the console',
+ .options('l', {
+ alias : 'level',
+ description: "IDE debug level ('silly', 'verbose', 'info', 'http', 'warn', 'error')",
+ default: 'http'
+ })
+ .options('L', {
+ alias : 'log',
+ description: "Log IDE debug to ./ide.log",
boolean: true
})
.argv;
@@ -64,23 +74,35 @@ if (argv.help) {
process.exit(0);
}
-function log() {
- if (argv.verbose) {
- var arg, msg = arguments.callee.caller.name + '(): ';
- for (var argi = 0; argi < arguments.length; argi++) {
- arg = arguments[argi];
- if (typeof arg === 'object') {
- msg += util.inspect(arg);
- } else {
- msg += arg;
- }
- msg += ' ';
+log.level = argv.level || 'http';
+if (argv.log) {
+ log.stream = fs.createWriteStream('ide.log');
+}
+
+function m() {
+ var arg, msg = '';
+ for (var argi = 0; argi < arguments.length; argi++) {
+ arg = arguments[argi];
+ if (typeof arg === 'object') {
+ msg += util.inspect(arg);
+ } else {
+ msg += arg;
}
- console.log(msg);
- };
+ msg += ' ';
+ }
+ return msg;
}
-log("Arguments:", argv);
+log.info('main', m("Arguments:", argv));
+
+// Exit path
+
+process.on('uncaughtException', function (err) {
+ log.error('main', err.stack);
+ process.exit(1);
+});
+process.on('exit', onExit);
+process.on('SIGINT', onExit);
// Load IDE configuration & start per-project file servers
@@ -125,7 +147,7 @@ function loadMainConfig(configFile) {
throw "Did not find: '"+configFile+"': ";
}
- log("Loading ARES configuration from '"+configFile+"'...");
+ log.verbose('loadMainConfig()', "Loading ARES configuration from '"+configFile+"'...");
configStats = fs.lstatSync(configFile);
if (!configStats.isFile()) {
throw "Not a file: '"+configFile+"': ";
@@ -148,7 +170,7 @@ function getObjectType(object) {
}
function mergePluginConfig(service, newdata, configFile) {
- log("Merging service '" + (service.name || service.id) + "' to ARES configuration");
+ log.verbose('mergePluginConfig()', "Merging service '" + (service.name || service.id) + "' to ARES configuration");
try {
for(var key in newdata) {
var srcType = getObjectType(service[key]);
@@ -164,7 +186,7 @@ function mergePluginConfig(service, newdata, configFile) {
}
} else if (srcType === 'object') {
for(var subkey in newdata[key]) {
- console.log("Adding or replacing " + subkey + " in " + key);
+ log.verbose('mergePluginConfig()', "Adding or replacing " + subkey + " in " + key);
service[key][subkey] = newdata[key][subkey];
}
} else {
@@ -172,15 +194,15 @@ function mergePluginConfig(service, newdata, configFile) {
}
}
- log("Merged service: " + JSON.stringify(service, null, 2));
+ log.info('mergePluginConfig()', "Merged service: " + JSON.stringify(service, null, 2));
} catch(err) {
- console.log(err);
+ log.error('mergePluginConfig()', err);
throw "Unable to merge " + configFile;
}
}
function appendPluginConfig(configFile) {
- log("Loading ARES plugin configuration from '"+configFile+"'...");
+ log.verbose('appendPluginConfig()', "Loading ARES plugin configuration from '"+configFile+"'...");
var pluginData;
var configContent = fs.readFileSync(configFile, 'utf8');
try {
@@ -193,7 +215,7 @@ function appendPluginConfig(configFile) {
if (serviceMap[pluginData.id]) {
mergePluginConfig(serviceMap[pluginData.id], pluginData, configFile);
} else {
- log("Adding new service '" + pluginData.name + "' to ARES configuration");
+ log.verbose('appendPluginConfig()', "Adding new service '" + pluginData.name + "' to ARES configuration");
ide.res.services.push(pluginData);
serviceMap[pluginData.id] = pluginData;
}
@@ -224,18 +246,18 @@ loadPluginConfigFiles();
// configuration age/date is the UTC configuration file last modification date
ide.res.timestamp = configStats.atime.getTime();
-log(ide.res);
+log.verbose('main', ide.res);
function handleMessage(service) {
return function(msg) {
if (msg.protocol && msg.host && msg.port && msg.origin && msg.pathname) {
service.dest = msg;
- log("will proxy to service.dest:", service.dest);
+ log.info(service.id , m("will proxy to service.dest:", service.dest));
service.origin = 'http://' + argv.host + ':' + argv.port;
service.pathname = '/res/services/' + service.id;
if (service.origin.match(/^https:/)) {
- console.info("Service['"+service.id+"']: connect to <"+service.origin+"> to accept SSL certificate");
+ log.http(service.id, "connect to <"+service.origin+"> to accept SSL certificate");
}
var options = {
@@ -248,35 +270,41 @@ function handleMessage(service) {
}
};
var creq = http.request(options, function(cres) {
- console.info("Service['"+service.id+"']: POST /config response.status=" + cres.statusCode);
+ log.http(service.id, "POST /config response.status=" + cres.statusCode);
}).on('error', function(e) {
throw e;
});
creq.write(JSON.stringify({config: service}, null, 2));
creq.end();
} else {
- console.error("Error updating URL for service "+service.id);
+ log.error(service.id, "Error updating service URL");
}
};
}
-function serviceEcho(service) {
+function serviceOut(service) {
+ return function(data){
+ log.http(service.id, data.toString());
+ };
+}
+
+function serviceErr(service) {
return function(data){
- console.log("> Service['"+service.id+"']: "+data);
+ log.warn(service.id, data.toString());
};
}
function handleServiceExit(service) {
return function(code, signal) {
if (signal) {
- console.log("> Service['"+service.id+"']: killed (signal="+signal+")");
+ log.warn(service.id, "killed (signal="+signal+")");
} else {
- console.error("*** Service['"+service.id+"']: abnormal exit (code="+code+")");
+ log.warn(service.id, "abnormal exit (code="+code+")");
if (service.respawn) {
- console.error("*** Service['"+service.id+"']: respawning...");
+ log.warn(service.id, "respawning...");
startService(service);
} else {
- console.error("*** Exiting...");
+ log.error('handleServiceExit()', "*** Exiting...");
process.exit(code);
}
}
@@ -295,17 +323,17 @@ function startService(service) {
if (service.verbose) {
params.push('-v');
}
- console.log("> Service['"+service.id+"']: executing '"+command+" "+params.join(" ")+"'");
+ log.info(service.id, "executing '"+command+" "+params.join(" ")+"'");
var subProcess = spawn(command, params, options);
- subProcess.stderr.on('data', serviceEcho(service));
- subProcess.stdout.on('data', serviceEcho(service));
+ subProcess.stderr.on('data', serviceErr(service));
+ subProcess.stdout.on('data', serviceOut(service));
subProcess.on('exit', handleServiceExit(service));
subProcess.on('message', handleMessage(service));
subProcesses.push(subProcess);
}
function proxyServices(req, res, next) {
- log("req.params:", req.params, ", req.query:", req.query);
+ log.verbose('proxyServices()', m("req.params:", req.params, ", req.query:", req.query));
var query = {},
id = req.params.serviceId,
service = ide.res.services.filter(function(service) {
@@ -334,11 +362,11 @@ function proxyServices(req, res, next) {
// headers to send
headers: req.headers
};
- log("options:", options);
+ log.verbose('proxyServices()', m("options:", options));
var creq = http.request(options, function(cres) {
// transmit every header verbatim, but cookies
- log("cres.headers:", cres.headers);
+ log.verbose('proxyServices()', m("cres.headers:", cres.headers));
for (var key in cres.headers) {
var val = cres.headers[key];
if (key.toLowerCase() === 'set-cookie') {
@@ -361,8 +389,8 @@ function translateCookie(service, res, cookie) {
cookie.options.domain = ide.res.domain || '127.0.0.1';
var oldPath = cookie.options.path;
cookie.options.path = service.pathname + (oldPath ? oldPath : '');
- log("cookie.path:", oldPath, "->", cookie.options.path);
- log("set-cookie:", cookie);
+ log.silly('translateCookie()', m("cookie.path:", oldPath, "->", cookie.options.path));
+ log.silly('translateCookie()', m("set-cookie:", cookie));
res.cookie(cookie.name, cookie.value, cookie.options);
}
@@ -374,7 +402,7 @@ function parseSetCookie(cookies) {
cookies.forEach(function(cookie) {
var outCookie = {};
var tokens = cookie.split(/; */);
- log("parseSetCookie(): tokens:", tokens);
+ log.silly("parseSetCookie()", m("tokens:", tokens));
var namevalStr = tokens.splice(0, 1)[0];
if (typeof namevalStr === 'string') {
var nameval = namevalStr.split('=');
@@ -388,24 +416,24 @@ function parseSetCookie(cookies) {
if (typeof outCookie.options.expires === 'string') {
outCookie.options.expires = new Date(outCookie.options.expires);
}
- log("parseSetCookie(): outCookie:", outCookie);
+ log.silly("parseSetCookie()", m("outCookie:", outCookie));
outCookies.push(outCookie);
} else {
- log("parseSetCookie(): Invalid Set-Cookie header:", namevalStr);
+ log.silly("parseSetCookie()", m("Invalid Set-Cookie header:", namevalStr));
}
});
- log("outCookies:", outCookies);
+ log.silly("parseSetCookie()", m("outCookies:", outCookies));
return outCookies;
}
function onExit() {
if (subProcesses.length > 0) {
- console.log('Terminating sub-processes...');
+ log.info('onExit()', 'Terminating sub-processes...');
subProcesses.forEach(function(subproc) {
process.kill(subproc.pid, 'SIGINT');
});
subProcesses = [];
- console.log('Exiting...');
+ log.info('onExit()', 'Exiting...');
}
}
@@ -435,14 +463,14 @@ app.configure(function(){
app.use(express.logger('dev'));
app.get('/', function(req, res, next) {
- log("GET /");
+ log.http('main', "GET /");
res.redirect('/ide/ares/');
});
app.get('/res/timestamp', function(req, res, next) {
res.status(200).json({timestamp: ide.res.timestamp});
});
app.get('/res/services', function(req, res, next) {
- log("GET /res/services:", ide.res.services);
+ log.http('main', m("GET /res/services:", ide.res.services));
res.status(200).json({services: ide.res.services});
});
app.all('/res/services/:serviceId/*', proxyServices);
@@ -471,16 +499,7 @@ if (argv.browser) {
var info = platformOpen[process.platform] ;
spawn(info[0], info.slice(1).concat([url]));
} else {
- console.log("Ares now running at <" + url + ">");
+ log.http('main', "Ares now running at <" + url + ">");
}
-// Exit path
-
-console.info("Press CTRL + C to shutdown");
-
-process.on('uncaughtException', function (err) {
- console.error(err.stack);
- process.exit(1);
-});
-process.on('exit', onExit);
-process.on('SIGINT', onExit);
+log.info('main', "Press CTRL + C to shutdown");
View
11 npm-shrinkwrap.json
@@ -33,7 +33,6 @@
"express": {
"version": "3.1.0",
"from": "express@3.1.0",
- "resolved": "https://registry.npmjs.org/express/-/express-3.1.0.tgz",
"dependencies": {
"connect": {
"version": "2.7.2",
@@ -117,6 +116,16 @@
"version": "0.3.4",
"from": "mkdirp@0.3.4"
},
+ "npmlog": {
+ "version": "0.0.2",
+ "from": "npmlog@",
+ "dependencies": {
+ "ansi": {
+ "version": "0.1.2",
+ "from": "ansi@~0.1.2"
+ }
+ }
+ },
"optimist": {
"version": "0.3.5",
"from": "optimist@0.3.5",
View
2  package.json
@@ -26,6 +26,7 @@
"form-data": "0.0.x",
"mime": "1.2.x",
"mkdirp": "0.3.x",
+ "npmlog": "0.0.x",
"optimist": "0.3.x",
"phonegapbuildapi": "1.0.2",
"request": "2.12.x",
@@ -44,6 +45,7 @@
"form-data",
"mime",
"mkdirp",
+ "npmlog",
"optimist",
"phonegapbuildapi",
"request",
Something went wrong with that request. Please try again.