Authored by 周奇琪

Merge branch 'feature/influxdb-log' into develop

Conflicts:
	library/api.js
@@ -3,14 +3,18 @@ @@ -3,14 +3,18 @@
3 * @author: xuqi<qi.xu@yoho.cn> 3 * @author: xuqi<qi.xu@yoho.cn>
4 * @date: 2016/4/25 4 * @date: 2016/4/25
5 */ 5 */
  6 +'use strict';
6 7
7 -var express = require('express'), 8 +let express = require('express'),
8 path = require('path'), 9 path = require('path'),
9 bodyParser = require('body-parser'), 10 bodyParser = require('body-parser'),
10 - favicon = require('serve-favicon'),  
11 - cookieParser = require('cookie-parser'); 11 + cookieParser = require('cookie-parser'),
  12 + favicon = require('serve-favicon');
12 13
13 -var app = express(); 14 +require('express-handlebars');
  15 +
  16 +
  17 +let app = express();
14 18
15 app.set('view engine', '.hbs'); 19 app.set('view engine', '.hbs');
16 20
  1 +/**
  2 + * sub app guang
  3 + * @author: hbomb<qiqi.zhou@yoho.cn>
  4 + * @date: 2016/05/06
  5 + */
  6 +
  7 +var express = require('express'),
  8 + path = require('path'),
  9 + hbs = require('express-handlebars');
  10 +
  11 +var app = express();
  12 +
  13 +// set view engin
  14 +var doraemon = path.join(__dirname, '../../doraemon/views'); // parent view root
  15 +
  16 +app.set('views', path.join(__dirname, 'views/action'));
  17 +app.engine('.hbs', hbs({
  18 + extname: '.hbs',
  19 + defaultLayout: 'layout',
  20 + layoutsDir: doraemon,
  21 + partialsDir: ['./views/partial', `${doraemon}/partial`],
  22 + helpers: 'helpers'
  23 +}));
  24 +
  25 +// router
  26 +app.use(require('./router'));
  27 +
  28 +module.exports = app;
  1 +/**
  2 + * router of sub app guang
  3 + * @author: hbomb<qiqi.zhou@yoho.cn>
  4 + * @date: 2016/05/06
  5 + */
  6 +
  7 +'use strict';
  8 +
  9 +const router = require('express').Router();
  10 +const cRoot = './controllers';
  11 +let API = require('../../library/api');
  12 +// Your controller here
  13 +router.get('/', function(req, res) {
  14 + let api = new API();
  15 + let name = '/productColor/queryProductColors';
  16 + api.get(name, {}).then(function(body) {
  17 + res.send(body);
  18 + }).catch(function(error) {
  19 + res.send('some thing wrong');
  20 + });
  21 +});
  22 +
  23 +
  24 +module.exports = router;
  1 +/**
  2 + * 系统配置
  3 + *
  4 + * @author hbomb qiqi.zhou@yoho.cn
  5 + * @date 2016/05/06
  6 + */
  7 +
  8 +module.exports = {
  9 + domains: {
  10 + api:'http://192.168.102.202:8088/platform'
  11 + },
  12 + loggers: {
  13 + file:{
  14 + level:'info',
  15 + maxsize:100 * 1024 * 1024,
  16 + handleExceptions:true,
  17 + zippedArchive:true,
  18 + timestamp:true,
  19 + filename:'info.log'
  20 + },
  21 + udp: { // send by udp
  22 + level:'debug', // logger level
  23 + host:'192.168.102.162', // influxdb host
  24 + port:'4444'// influxdb port
  25 + },
  26 + 'console':{
  27 + level:'debug',
  28 + colorize: 'all',
  29 + prettyPrint:true
  30 + }
  31 + }
  32 +};
@@ -8,8 +8,12 @@ @@ -8,8 +8,12 @@
8 8
9 const rp = require('request-promise'); 9 const rp = require('request-promise');
10 const _ = require('lodash'); 10 const _ = require('lodash');
  11 +const log = require('./logger');
  12 +const api = require('../config/common').domains.api;
  13 +const Timer = require('./timer');
11 14
12 -const ApiUrl = 'http://testapi.yoho.cn:28078/'; 15 +
  16 +const ApiUrl = api;
13 17
14 class API { 18 class API {
15 19
@@ -19,10 +23,26 @@ class API { @@ -19,10 +23,26 @@ class API {
19 * @param data Obejct 23 * @param data Obejct
20 */ 24 */
21 get(url, data) { 25 get(url, data) {
22 - return rp({ 26 +
  27 + let options = {
23 url: `${ApiUrl}${url}`, 28 url: `${ApiUrl}${url}`,
24 qs: data 29 qs: data
  30 + };
  31 +
  32 + let timer = new Timer();
  33 + timer.put('getApi');// 统计时间开始
  34 +
  35 + let ret = rp(options);
  36 +
  37 + ret.then((body)=>{
  38 + let duration = timer.put('getApi');// 接口返回
  39 + log.info('API GET: %s, parms: %j , durationMs: %d ms , body: %s', options.url, options.qs, duration, body);
  40 + }).catch((error)=>{
  41 + let duration = timer.put('getApi');// 接口返回
  42 + log.error('API GET: %s, parms: %j , durationMs: %d ms error: %s , statusCode: %d', options.url, options.qs, duration, error.message, error.statusCode);
25 }); 43 });
  44 +
  45 + return ret;
26 } 46 }
27 47
28 /** 48 /**
  1 +
  2 +/**
  3 + * 日志工具类
  4 + * @author: hbomb<qiqi.zhou@yoho.cn>
  5 + * @date: 2016/05/06
  6 + */
  7 + 'use strict';
  8 +
  9 + let winston = require('winston'),
  10 + config = require('../config/common');
  11 +
  12 + require('influxdb-winston');
  13 +
  14 + let logger = new (winston.Logger)({
  15 + transports: [
  16 + new (winston.transports.File)(config.loggers.file),
  17 + new (winston.transports.UdpTransport)(config.loggers.udp),
  18 + new (winston.transports.Console)(config.loggers.console)
  19 + ]
  20 + });
  21 +
  22 + module.exports = logger;
  1 +'use strict';
  2 +
  3 +/**
  4 + * 计时类
  5 + * @example
  6 + * let timer = new Timer();
  7 + * timer.put('profile');
  8 + * timer.put('proflie'); // console output: 12.14
  9 + *
  10 + * @author: hbomb<qiqi.zhou@yoho.cn>
  11 + * @date: 2016/05/07
  12 + */
  13 +
  14 +class Timer {
  15 + constructor() {
  16 + this.timers = {};
  17 + }
  18 +
  19 + /**
  20 + * 打点计时
  21 + */
  22 + put(label) {
  23 + let labelTime = this.timers[label];
  24 +
  25 + if (labelTime) {
  26 + let duration = process.hrtime(labelTime);
  27 + return this._round(duration[1]);
  28 + } else {
  29 + this.timers[label] = process.hrtime();
  30 + }
  31 + }
  32 +
  33 + /**
  34 + * 格式化成毫秒
  35 + * @param {Number} value 纳秒
  36 + */
  37 + _round(value) {
  38 + return Math.round(value / 10000) / 100;
  39 + }
  40 +
  41 +}
  42 +
  43 +module.exports = Timer;
@@ -12,8 +12,8 @@ @@ -12,8 +12,8 @@
12 "dev": "node_modules/.bin/nodemon -e js,hbs -i public/ app.js", 12 "dev": "node_modules/.bin/nodemon -e js,hbs -i public/ app.js",
13 "online": "NODE_ENV=\"production\" node app.js", 13 "online": "NODE_ENV=\"production\" node app.js",
14 "debug": "DEBUG=\"express:*\" node app.js", 14 "debug": "DEBUG=\"express:*\" node app.js",
15 - "lint-js": "node_modules/.bin/eslint -c .eslintrc --cache --fix `git diff --cached --name-only --diff-filter=ACM | grep .js$` app.js",  
16 - "lint-css": "node_modules/.bin/stylelint --config .stylelintrc `git diff --cached --name-only --diff-filter=ACM | grep .css$`", 15 + "lint-js": "file=`git diff --cached --name-only --diff-filter=ACM | grep .js$`;node_modules/.bin/eslint -c .eslintrc --cache --fix $file app.js",
  16 + "lint-css": "file=`git diff --cached --name-only --diff-filter=ACM | grep .css$`;node_modules/.bin/stylelint --config .stylelintrc $file",
17 "precommit": "npm run lint-js && npm run lint-css" 17 "precommit": "npm run lint-js && npm run lint-css"
18 }, 18 },
19 "license": "MIT", 19 "license": "MIT",
@@ -22,11 +22,13 @@ @@ -22,11 +22,13 @@
22 "cookie-parser": "^1.4.1", 22 "cookie-parser": "^1.4.1",
23 "express": "^4.13.1", 23 "express": "^4.13.1",
24 "express-handlebars": "^3.0.0", 24 "express-handlebars": "^3.0.0",
  25 + "influxdb-winston": "^1.0.1",
25 "lodash": "^4.8.2", 26 "lodash": "^4.8.2",
26 "md5": "^2.1.0", 27 "md5": "^2.1.0",
27 "morgan": "^1.7.0", 28 "morgan": "^1.7.0",
28 "request-promise": "^2.0.1", 29 "request-promise": "^2.0.1",
29 - "serve-favicon": "^2.3.0" 30 + "serve-favicon": "^2.3.0",
  31 + "winston": "^2.2.0"
30 }, 32 },
31 "devDependencies": { 33 "devDependencies": {
32 "autoprefixer": "^6.3.6", 34 "autoprefixer": "^6.3.6",
@@ -39,6 +41,8 @@ @@ -39,6 +41,8 @@
39 "gulp-sourcemaps": "^2.0.0-alpha", 41 "gulp-sourcemaps": "^2.0.0-alpha",
40 "gulp-util": "^3.0.7", 42 "gulp-util": "^3.0.7",
41 "husky": "^0.11.4", 43 "husky": "^0.11.4",
  44 + "mocha": "^2.4.5",
  45 + "nodemon": "1.9.2",
42 "postcss-assets": "^4.0.1", 46 "postcss-assets": "^4.0.1",
43 "postcss-cachebuster": "^0.1.2", 47 "postcss-cachebuster": "^0.1.2",
44 "postcss-calc": "^5.2.1", 48 "postcss-calc": "^5.2.1",
@@ -51,11 +55,12 @@ @@ -51,11 +55,12 @@
51 "postcss-sprites": "^3.1.2", 55 "postcss-sprites": "^3.1.2",
52 "postcss-use": "^2.0.2", 56 "postcss-use": "^2.0.2",
53 "precss": "^1.4.0", 57 "precss": "^1.4.0",
  58 + "rewire": "^2.5.1",
  59 + "shelljs": "^0.7.0",
54 "stylelint": "^6.2.2", 60 "stylelint": "^6.2.2",
55 "stylelint-config-yoho": "^1.2.0", 61 "stylelint-config-yoho": "^1.2.0",
56 "webpack": "^1.13.0", 62 "webpack": "^1.13.0",
57 "webpack-dev-server": "^1.14.1", 63 "webpack-dev-server": "^1.14.1",
58 - "webpack-stream": "^3.1.0",  
59 - "shelljs": "^0.7.0" 64 + "webpack-stream": "^3.1.0"
60 } 65 }
61 } 66 }
  1 +let expect = require('expect.js');
  2 +let Timer = require('../../library/timer');
  3 +
  4 +
  5 +describe('/library/timer', function() {
  6 + it('延迟100ms,期望大于或等于100ms', function(done) {
  7 + let t = new Timer();
  8 + t.put('aa');
  9 + setTimeout(function() {
  10 + let time = t.put('aa');
  11 + expect(Math.round(time) >= 100).to.be.ok();
  12 + done();
  13 + }, 100);
  14 + });
  15 +});
  1 +require('./library/timer.test');