From 5a6de74105867c7b1b834af5629ad83c73e50473 Mon Sep 17 00:00:00 2001 From: Matt Godbolt Date: Thu, 27 Oct 2016 20:13:30 -0500 Subject: [PATCH] Use winston for logging --- app.js | 52 +++++++++++++++++++++++------------------------ lib/asm-cl.js | 3 ++- lib/compile.js | 21 ++++++++++--------- lib/diff.js | 15 ++++++-------- lib/logger.js | 39 +++++++++++++++++++++++++++++++++++ lib/properties.js | 13 ++++++------ package.json | 3 ++- 7 files changed, 92 insertions(+), 54 deletions(-) create mode 100644 lib/logger.js diff --git a/app.js b/app.js index 592fd4e6..b0c548dd 100755 --- a/app.js +++ b/app.js @@ -39,7 +39,8 @@ var nopt = require('nopt'), url = require('url'), Promise = require('promise'), aws = require('./lib/aws'), - _ = require('underscore-node'); + _ = require('underscore-node'), + logger = require('./lib/logger').logger; // Parse arguments from command line 'node ./app.js args...' var opts = nopt({ @@ -71,7 +72,7 @@ var propHierarchy = _.flatten([ process.platform, os.hostname(), 'local']); -console.log("properties hierarchy: " + propHierarchy.join(', ')); +logger.info("properties hierarchy: " + propHierarchy.join(', ')); // Propagate debug mode if need be if (opts.propDebug) props.setDebug(true); @@ -217,10 +218,10 @@ function retryPromise(promiseFunc, name, maxFails, retryMs) { }, function (e) { fails++; if (fails < maxFails) { - console.log("Failed " + name + " : " + e + ", retrying"); + logger.warn("Failed " + name + " : " + e + ", retrying"); setTimeout(doit, retryMs); } else { - console.log("Too many retries for " + name + " : " + e); + logger.error("Too many retries for " + name + " : " + e); reject(e); } }); @@ -255,7 +256,7 @@ function configuredCompilers() { } function fetchRemote(host, port, props) { - console.log("Fetching compilers from remote source " + host + ":" + port); + logger.info("Fetching compilers from remote source " + host + ":" + port); return retryPromise(function () { return new Promise(function (resolve, reject) { var request = http.get({ @@ -287,16 +288,16 @@ function configuredCompilers() { props('proxyRetries', 5), props('proxyRetryMs', 500)) .catch(function () { - console.log("Unable to contact " + host + ":" + port + "; skipping"); + logger.warn("Unable to contact " + host + ":" + port + "; skipping"); return []; }); } function fetchAws() { - console.log("Fetching instances from AWS"); + logger.info("Fetching instances from AWS"); return awsInstances().then(function (instances) { return Promise.all(instances.map(function (instance) { - console.log("Checking instance " + instance.InstanceId); + logger.info("Checking instance " + instance.InstanceId); var address = instance.PrivateDnsName; if (awsProps("externalTestMode", false)) { address = instance.PublicDnsName; @@ -353,7 +354,7 @@ function getCompilerInfo(compilerInfo) { // assuming the compiler returns its version on 1 line child_process.exec('"' + compiler + '" ' + versionFlag, function (err, output) { if (err) { - console.log("Unable to run compiler '" + compiler + "' : " + err); + logger.error("Unable to run compiler '" + compiler + "' : " + err); return resolve(null); } compilerInfo.version = output.split('\n')[0]; @@ -377,7 +378,7 @@ function getCompilerInfo(compilerInfo) { } // debug (seems to be displayed multiple times): - if (opts.propDebug) console.log("compiler options: " + JSON.stringify(options, null, 4)); + logger.debug("compiler options: ", options); resolve(compilerInfo); }); @@ -435,7 +436,7 @@ function shortUrlHandler(req, res, next) { }); response.on('end', function () { if (response.statusCode != 200) { - console.log("Failed to resolve short URL " + bits[1] + " - got response " + + logger.error("Failed to resolve short URL " + bits[1] + " - got response " + response.statusCode + " : " + responseText); return next(); } @@ -444,7 +445,7 @@ function shortUrlHandler(req, res, next) { var parsed = url.parse(resultObj.longUrl); var allowedRe = new RegExp(gccProps('allowedShortUrlHostRe')); if (parsed.host.match(allowedRe) === null) { - console.log("Denied access to short URL " + bits[1] + " - linked to " + resultObj.longUrl); + logger.warn("Denied access to short URL " + bits[1] + " - linked to " + resultObj.longUrl); return next(); } res.writeHead(301, { @@ -478,12 +479,9 @@ findCompilers().then(function (compilers) { if (JSON.stringify(prevCompilers) == JSON.stringify(compilers)) { return; } - console.log("Compilers:"); - compilers.forEach(function (c) { - console.log(c.id + " : " + c.name + " : " + (c.exe || c.remote)); - }); - if (compilers.length == 0) { - console.log("#### No compilers found: no compilation will be done!"); + logger.info("Compilers:", compilers); + if (compilers.length === 0) { + logger.error("#### No compilers found: no compilation will be done!"); } prevCompilers = compilers; clientOptionsHandler.setCompilers(compilers); @@ -495,7 +493,7 @@ findCompilers().then(function (compilers) { var rescanCompilerSecs = gccProps('rescanCompilerSecs', 0); if (rescanCompilerSecs) { - console.log("Rescanning compilers every " + rescanCompilerSecs + "secs"); + logger.info("Rescanning compilers every " + rescanCompilerSecs + "secs"); setInterval(function () { findCompilers().then(onCompilerChange); }, rescanCompilerSecs * 1000); @@ -505,13 +503,13 @@ findCompilers().then(function (compilers) { sFavicon = require('serve-favicon'), sStatic = require('serve-static'), bodyParser = require('body-parser'), - logger = require('morgan'), + morgan = require('morgan'), compression = require('compression'), restreamer = require('./lib/restreamer'), diffHandler = buildDiffHandler(wdiffConfig); webServer - .use(logger('combined')) + .use(morgan('combined', {stream: logger.stream})) .use(compression()) .use(sFavicon(staticDir + '/favicon.ico')) .use(sStatic(staticDir, {maxAge: staticMaxAgeSecs * 1000})) @@ -526,13 +524,13 @@ findCompilers().then(function (compilers) { .post('/diff', diffHandler); // used inside static/compiler.js // GO! - console.log("======================================="); - console.log("Listening on http://" + hostname + ":" + port + "/"); - console.log(" serving static files from '" + staticDir + "'"); - console.log(" git release " + gitReleaseName); - console.log("======================================="); + logger.info("======================================="); + logger.info("Listening on http://" + hostname + ":" + port + "/"); + logger.info(" serving static files from '" + staticDir + "'"); + logger.info(" git release " + gitReleaseName); + logger.info("======================================="); webServer.listen(port, hostname); }).catch(function (err) { - console.log("Error: " + err); + logger.error("Error: " + err); process.exit(1); }); diff --git a/lib/asm-cl.js b/lib/asm-cl.js index b6c9010c..0302b8a1 100644 --- a/lib/asm-cl.js +++ b/lib/asm-cl.js @@ -23,6 +23,7 @@ // POSSIBILITY OF SUCH DAMAGE. var _ = require('underscore-node'); +var logger = require('./logger').logger; var expandTabs = require('./utils').expandTabs; var sourceTag = /^;\s*([0-9]+)\s*:/; @@ -46,7 +47,7 @@ var commentedLine = /([^;]+);\s*(.*)/; var numberRe = /^\s+(([0-9a-f]+\b\s*)([0-9a-f][0-9a-f]\b\s*)*)(.*)/; function debug() { - // console.log.apply(console, arguments); + logger.debug.apply(logger, arguments); } function demangle(line) { diff --git a/lib/compile.js b/lib/compile.js index 4efe83e6..23303458 100644 --- a/lib/compile.js +++ b/lib/compile.js @@ -32,15 +32,16 @@ var child_process = require('child_process'), Queue = require('promise-queue'), asm = require('./asm'), utils = require('./utils'), - quote = require('shell-quote'); + quote = require('shell-quote'), + logger = require('./logger').logger; Queue.configure(Promise); temp.track(); function periodicCleanup() { temp.cleanup(function (err, stats) { - if (err) console.log("Error cleaning directories: ", err); - // if (stats) console.log("Directory cleanup stats:", stats); + if (err) logger.error("Error cleaning directories: ", err); + if (stats) logger.debug("Directory cleanup stats:", stats); }); } var gccProps = null; @@ -56,7 +57,7 @@ function initialise(gccProps_, compilerProps_) { gccProps = gccProps_; compilerProps = compilerProps_; var tempDirCleanupSecs = gccProps("tempDirCleanupSecs", 600); - console.log("Cleaning temp dirs every " + tempDirCleanupSecs + " secs"); + logger.info("Cleaning temp dirs every " + tempDirCleanupSecs + " secs"); setInterval(periodicCleanup, tempDirCleanupSecs * 1000); asm.initialise(compilerProps); stubRe = compilerProps("stubRe"); @@ -198,13 +199,13 @@ Compile.prototype.getMultiarch = function () { try { var multi = child_process.execSync("gcc -print-multiarch").toString().trim(); if (multi) { - console.log("Multiarch: " + multi); + logger.info("Multiarch: " + multi); this.multiarch = multi; } else { - console.log("No multiarch"); + logger.info("No multiarch"); } } catch (err) { - console.log("Unable to get multiarch: " + err); + logger.warn("Unable to get multiarch: " + err); } }; @@ -385,7 +386,7 @@ Compile.prototype.checkSource = function (source) { Compile.prototype.cacheStats = function () { var pc = (100 * this.cacheHits) / (this.cacheMisses + this.cacheHits); - console.log("Cache stats: " + this.cacheHits + " hits, " + this.cacheMisses + " misses (" + pc.toFixed(2) + + logger.info("Cache stats: " + this.cacheHits + " hits, " + this.cacheMisses + " misses (" + pc.toFixed(2) + "%), LRU has " + this.cache.itemCount + " item(s) totalling " + this.cache.length + " bytes"); }; @@ -403,7 +404,7 @@ function CompileHandler() { var remote = compileObj.getRemote(compiler); if (remote) { proxy.web(req, res, {target: remote}, function (e) { - console.log("Proxy error: ", e); + logger.error("Proxy error: ", e); next(e); }); return; @@ -421,7 +422,7 @@ function CompileHandler() { res.end(JSON.stringify(result)); }, function (error) { - console.log("Error: " + error.stack); + logger.error("Error: " + error.stack); if (typeof(error) !== "string") { error = "Internal GCC explorer error: " + error.toString(); } diff --git a/lib/diff.js b/lib/diff.js index f78e3234..c456b1e1 100644 --- a/lib/diff.js +++ b/lib/diff.js @@ -2,6 +2,7 @@ var fs = require('fs'), child_process = require('child_process'), temp = require('temp'), path = require('path'), + logger = require('./logger').logger, Promise = require('promise') // jshint ignore:line ; @@ -106,15 +107,11 @@ function cleanAndGetIndexes(text) { memorizeText(); } - function log_error(string) { - console.log(string); - } - while (posInText < text.length) { var tag = tagLookup(rules, text, posInText); if (tag.seen && tag.type == TagTypeEnum.OPENING) { if (state != StateEnum.OUTSIDE_TAG) { - log_error("Opening tag while not outside tag (tags cannot be nested)"); + log.error("Opening tag while not outside tag (tags cannot be nested)"); return null; } currentTag = tag.rule; @@ -122,11 +119,11 @@ function cleanAndGetIndexes(text) { state = StateEnum.INSIDE_TAG; } else if (tag.seen && tag.type == TagTypeEnum.CLOSING) { if (state != StateEnum.INSIDE_TAG) { - log_error("Closing tag while not inside tag."); + log.error("Closing tag while not inside tag."); return null; } if (currentTag != tag.rule) { - log_error("Closing tag, but not of the same type as previously opened."); + log.error("Closing tag, but not of the same type as previously opened."); return null; } seenClosingTag(); @@ -161,12 +158,12 @@ function buildDiffHandler(config) { var error; if (before === undefined) { error = 'Warning : Bad request : wrong "before"'; - console.log(error); + logger.error(error); return next(new Error(error)); } if (after === undefined) { error = 'Warning : Bad request : wrong "after"'; - console.log(error); + logger.error(error); return next(new Error(error)); } diff --git a/lib/logger.js b/lib/logger.js new file mode 100644 index 00000000..9605594e --- /dev/null +++ b/lib/logger.js @@ -0,0 +1,39 @@ +// Copyright (c) 2012-2016, Matt Godbolt +// All rights reserved. +// +// Redistribution and use 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. +// +// 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 HOLDER 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. + +var winston = require('winston'); + +var logger = new (winston.Logger)({ + transports: [ + new (winston.transports.Console)({colorize: true}) + ] +}); + +logger.stream = { + write: function (message, encoding) { + logger.info(message.trim()); + } +}; + +exports.logger = logger; \ No newline at end of file diff --git a/lib/properties.js b/lib/properties.js index f18a84da..ab279f7b 100644 --- a/lib/properties.js +++ b/lib/properties.js @@ -22,7 +22,8 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -var fs = require('fs'); +var fs = require('fs'), + logger = require('./logger').logger; var properties = {}; @@ -36,11 +37,11 @@ function findProps(base, elem) { } function debug(string) { - if (propDebug) console.log("prop: " + string); + if (propDebug) logger.info("prop: " + string); } function debug_show_properties() { - console.log("props.properties =" + JSON.stringify(properties,null,4)); + } function get(base, property, defaultValue) { @@ -73,7 +74,7 @@ function parseProperties(blob, name) { if (!line) return; var split = line.match(/([^=]+)=(.*)/); if (!split) { - console.log("Bad line: " + line + " in " + name + ":" + (index + 1)); + logger.error("Bad line: " + line + " in " + name + ":" + (index + 1)); return; } props[split[1].trim()] = toProperty(split[2].trim()); @@ -84,7 +85,7 @@ function parseProperties(blob, name) { function initialize(directory, hier) { if (hier === null) throw new Error('Must supply a hierarchy array'); - console.log("Reading properties from " + directory + " with hierarchy " + hier); + logger.info("Reading properties from " + directory + " with hierarchy " + hier); hierarchy = hier; var endsWith = /\.properties$/; var propertyFiles = fs.readdirSync(directory).filter(function (filename) { @@ -97,7 +98,7 @@ function initialize(directory, hier) { debug('Reading config from ' + file); properties[baseName] = parseProperties(fs.readFileSync(file, 'utf-8'), file); }); - if (propDebug) debug_show_properties(); + logger.debug("props.properties = ", properties); } function propsFor(base) { diff --git a/package.json b/package.json index 5a2b132e..98e03159 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,8 @@ "serve-static": "1.10.x", "temp": "0.8.x", "underscore-node": "*", - "shell-quote": "1.6.x" + "shell-quote": "1.6.x", + "winston": "2.2.x" }, "devDependencies": { "supervisor": "*",