Merge commit 'c1ef713a863eaf3000048233b540ce35c44ac42b'

This commit is contained in:
alsotang 2015-05-27 22:15:25 +08:00
commit acd1626d9e
8 changed files with 146 additions and 10 deletions

18
app.js
View File

@ -17,6 +17,7 @@ var Loader = require('loader');
var express = require('express');
var session = require('express-session');
var passport = require('passport');
var mongooseLog = require('./middlewares/mongoose_log');
require('./models');
var GitHubStrategy = require('passport-github').Strategy;
var githubStrategyMiddleware = require('./middlewares/github_strategy');
@ -34,6 +35,9 @@ var busboy = require('connect-busboy');
var errorhandler = require('errorhandler');
var cors = require('cors');
var limitMiddleware = require('./middlewares/limit');
var requestLog = require('./middlewares/request_log');
var render = require('./middlewares/render');
var logger = require("./common/logger");
// 静态文件目录
@ -62,6 +66,13 @@ app.engine('html', require('ejs-mate'));
app.locals._layoutFile = 'layout.html';
app.enable('trust proxy');
// Request logger
app.use(requestLog);
if (config.debug) {
app.use(render.render);
}
// 静态资源
app.use(Loader.less(__dirname));
app.use('/public', express.static(staticDir));
@ -152,9 +163,10 @@ if (config.debug) {
}
app.listen(config.port, function () {
console.log("NodeClub listening on port %d", config.port);
console.log("God bless love....");
console.log("You can debug your app with http://" + config.hostname + ':' + config.port);
logger.log("NodeClub listening on port %d", config.port);
logger.log("God bless love....");
logger.log("You can debug your app with http://" + config.hostname + ':' + config.port);
logger.log("");
});

View File

@ -1,7 +1,10 @@
var redis = require('./redis');
var _ = require('lodash');
var redis = require('./redis');
var _ = require('lodash');
var logger = require('./logger');
var colors = require('colors');
var get = function (key, callback) {
var t = new Date();
redis.get(key, function (err, data) {
if (err) {
return callback(err);
@ -10,6 +13,8 @@ var get = function (key, callback) {
return callback();
}
data = JSON.parse(data);
var duration = (new Date() - t);
logger.info('Cache', 'get', key, (duration + 'ms').green);
callback(null, data);
});
};
@ -18,17 +23,22 @@ exports.get = get;
// time 参数可选,秒为单位
var set = function (key, value, time, callback) {
var t = new Date();
if (typeof time === 'function') {
callback = time;
time = null;
}
callback = callback || _.noop;
value = JSON.stringify(value);
if (!time) {
redis.set(key, value, callback);
} else {
redis.setex(key, time, value, callback);
}
var duration = (new Date() - t);
logger.info("Cache", "set", key, (duration + 'ms').green);
};
exports.set = set;

56
common/logger.js Normal file
View File

@ -0,0 +1,56 @@
var colors = require("colors");
var fs = require('fs');
var config = require('../config');
if (!fs.existsSync("./log")) {
fs.mkdirSync("./log");
}
exports.log = function() {
writeLog('', 'info', arguments);
}
exports.info = function() {
writeLog(' ', 'info', arguments);
}
exports.debug = function() {
writeLog(" ", 'debug', arguments);
}
exports.warn = function() {
writeLog(" ", 'warn', arguments);
}
exports.error = function() {
writeLog(" ", 'error', arguments);
}
var writeLog = function(prefix, logType, args) {
var infos = Array.prototype.slice.call(args);
var logStr = infos.join(" ");
switch (logType) {
case "debug":
logStr = logStr.gray;
break;
case 'warn':
logStr = logStr.yellow;
break;
case 'error':
logStr = logStr.red;
break;
}
var line = prefix + logStr;
var env = process.env.NODE_ENV || "development";
if (logStr !== 'debug') {
fs.appendFile('./log/'+ env +'.log', line + "\n");
}
if (env !== 'test' && config.debug) {
console.log(line);
}
}

View File

@ -69,12 +69,12 @@ exports.create = function (req, res, next) {
user.save(function (err) {
if (err) {
// 根据 err.err 的错误信息决定如何回应用户,这个地方写得很难看
if (err.err.indexOf('duplicate key error') !== -1) {
if (err.err.indexOf('users.$email') !== -1) {
if (err.message.indexOf('duplicate key error') !== -1) {
if (err.message.indexOf('users.$email') !== -1) {
return res.status(500)
.render('sign/no_github_email');
}
if (err.err.indexOf('users.$loginname') !== -1) {
if (err.message.indexOf('users.$loginname') !== -1) {
return res.status(500)
.send('您 GitHub 账号的用户名与之前在 CNodejs 注册的用户名重复了');
}

View File

@ -0,0 +1,17 @@
var mongoose = require('mongoose');
var colors = require('colors');
var logger = require('../common/logger');
var traceMQuery = function(method, info, query) {
return function (err, result, millis) {
var infos = [];
infos.push(query._collection.collection.name + "." + method.blue);
infos.push(JSON.stringify(info));
infos.push((millis + 'ms').green);
// var duration = (new Date()) - t;
logger.debug("MONGO".magenta, infos.join(' '));
};
}
mongoose.Mongoose.prototype.mquery.setGlobalTraceFunction(traceMQuery);

17
middlewares/render.js Normal file
View File

@ -0,0 +1,17 @@
var logger = require('../common/logger');
// Patch res.render method to output logger
exports.render = function (req, res, next) {
res._render = res.render;
res.render = function(view, options, fn) {
var t = new Date();
res._render(view, options, fn);
var duration = (new Date() - t);
logger.info("Render view", view, ("("+ duration +"ms)").green);
}
next();
};

View File

@ -0,0 +1,22 @@
var logger = require('../common/logger');
module.exports = function(req, res, next) {
// Assets do not out log.
if (exports.ignore.test(req.url)) {
next();
return;
}
var t = new Date();
logger.log('\n\nStarted', t.toISOString(), req.method, req.url, req.ip);
res.on('finish', function(){
var duration = ((new Date()) - t);
logger.log('Completed', res.statusCode, ('(' + duration + 'ms)').green);
});
next();
}
exports.ignore = /^\/(public|agent)/;

View File

@ -36,7 +36,8 @@
"memory-cache": "0.0.5",
"method-override": "1.0.2",
"moment": "2.9.0",
"mongoose": "3.8.23",
"mongoose": "4.0.3",
"mquery" : "1.5.1",
"multiline": "1.0.1",
"newrelic": "1.16.1",
"node-uuid": "1.4.1",
@ -52,7 +53,8 @@
"utility": "1.0.0",
"validator": "3.22.1",
"xmlbuilder": "2.5.0",
"xss": "0.1.15"
"xss": "0.1.15",
"colors" : "1.1.0"
},
"devDependencies": {
"coveralls": "2.11.2",