Authored by 周奇琪

Merge branch 'feature/report' into 'master'

fix

增加选择服务器

See merge request !6
@@ -5,7 +5,8 @@ const SqlBuilder = require('../utils/sql-builder'); @@ -5,7 +5,8 @@ const SqlBuilder = require('../utils/sql-builder');
5 const request = require('superagent'); 5 const request = require('superagent');
6 const _ = require('lodash'); 6 const _ = require('lodash');
7 const config = require('../../../config/config'); 7 const config = require('../../../config/config');
8 -const ENDPOINT = `http://${config.influxdb.host}:${config.influxdb.port}`; 8 +
  9 +const endpoint = (server) => `http://${server.host}:${server.port}`;
9 10
10 const r = new Router; 11 const r = new Router;
11 12
@@ -30,9 +31,9 @@ const profile_sql = { @@ -30,9 +31,9 @@ const profile_sql = {
30 } 31 }
31 }; 32 };
32 33
33 -async function exec(sql) {  
34 - console.log('influx sql =>', sql);  
35 - return request.get(`${ENDPOINT}/query`) 34 +async function exec(server, sql) {
  35 + console.log('influx query from ', `[${server}] `, 'sql =>' ,sql);
  36 + return request.get(`${server}/query`)
36 .query({ 37 .query({
37 q: sql, 38 q: sql,
38 db: DB_NAME 39 db: DB_NAME
@@ -60,8 +61,13 @@ const DURATION = { @@ -60,8 +61,13 @@ const DURATION = {
60 3: {field: 'duration', op: '>', value: 200}, 61 3: {field: 'duration', op: '>', value: 200},
61 }; 62 };
62 63
  64 +const SERVER = {
  65 + aws: endpoint(config.influxdb.aws),
  66 + qcloud: endpoint(config.influxdb.qcloud)
  67 +};
  68 +
63 const profile_service = { 69 const profile_service = {
64 - async time(start, end, app, duration) { 70 + async time(server, start, end, app, duration) {
65 const model = profile_sql.duration() 71 const model = profile_sql.duration()
66 .select('*') 72 .select('*')
67 .where(DURATION[duration]) 73 .where(DURATION[duration])
@@ -69,18 +75,18 @@ const profile_service = { @@ -69,18 +75,18 @@ const profile_service = {
69 .where('time', '>=', start) 75 .where('time', '>=', start)
70 .where('time', '<', end); 76 .where('time', '<', end);
71 77
72 - const rows = await exec(model.toSql()); 78 + const rows = await exec(SERVER[server],model.toSql());
73 return {code: 200, data: rows} 79 return {code: 200, data: rows}
74 }, 80 },
75 81
76 - async error(start, end, app) { 82 + async error(server, start, end, app) {
77 const model = profile_sql.error() 83 const model = profile_sql.error()
78 .select('*') 84 .select('*')
79 .where(APP[app]) 85 .where(APP[app])
80 .where('time', '>=', start) 86 .where('time', '>=', start)
81 .where('time', '<', end); 87 .where('time', '<', end);
82 88
83 - const rows = await exec(model.toSql()); 89 + const rows = await exec(SERVER[server], model.toSql());
84 return {cde: 200, data: rows}; 90 return {cde: 200, data: rows};
85 } 91 }
86 }; 92 };
@@ -94,8 +100,9 @@ const profile_controller = { @@ -94,8 +100,9 @@ const profile_controller = {
94 const end = ctx.query.end; 100 const end = ctx.query.end;
95 const app = ctx.query.app; 101 const app = ctx.query.app;
96 const duration = ctx.query.duration; 102 const duration = ctx.query.duration;
  103 + const server = ctx.query.server || 'aws';
97 104
98 - const result = await profile_service.time(start, end, app, duration); 105 + const result = await profile_service.time(server, start, end, app, duration);
99 ctx.body = result; 106 ctx.body = result;
100 }, 107 },
101 async error_report_index(ctx) { 108 async error_report_index(ctx) {
@@ -105,8 +112,9 @@ const profile_controller = { @@ -105,8 +112,9 @@ const profile_controller = {
105 const start = ctx.query.start; 112 const start = ctx.query.start;
106 const end = ctx.query.end; 113 const end = ctx.query.end;
107 const app = ctx.query.app; 114 const app = ctx.query.app;
  115 + const server = ctx.query.server || 'aws';
108 116
109 - const result = await profile_service.error(start, end, app); 117 + const result = await profile_service.error(server, start, end, app);
110 ctx.body = result; 118 ctx.body = result;
111 } 119 }
112 120
@@ -82,7 +82,7 @@ class SqlBuilder { @@ -82,7 +82,7 @@ class SqlBuilder {
82 } else { 82 } else {
83 return value 83 return value
84 } 84 }
85 - }).filter(v => v.length).join(' AND '); 85 + }).filter(v => v && v.length).join(' AND ');
86 let orWhere = this._orWhere.map(({field, op, value}) => `${field}${op}${value}`).filter(v => v.length).join(' OR '); 86 let orWhere = this._orWhere.map(({field, op, value}) => `${field}${op}${value}`).filter(v => v.length).join(' OR ');
87 87
88 if (andWhere) { 88 if (andWhere) {
@@ -19,8 +19,16 @@ @@ -19,8 +19,16 @@
19 <div class="contentpanel page-servers"> 19 <div class="contentpanel page-servers">
20 <div class="panel panel-primary-head"> 20 <div class="panel panel-primary-head">
21 <div class="panel-heading" style="overflow: hidden"> 21 <div class="panel-heading" style="overflow: hidden">
  22 +
  23 + <div class="pull-left">
  24 + <select id="selectedServer" class="selectpicker show-menu-arrow form-control" style="margin-left: 10px;">
  25 + <option value="aws" selected>aws</option>
  26 + <option value="qcloud">qcloud</option>
  27 + </select>
  28 + </div>
  29 +
22 <div id="reportrange" class="pull-left" 30 <div id="reportrange" class="pull-left"
23 - style="display: inline-block; background: #fff; cursor: pointer; padding: 9px 10px; border: 1px solid #ccc; width: 250px; color: black"> 31 + style="display: inline-block; background: #fff; cursor: pointer; padding: 9px 10px; border: 1px solid #ccc; width: 250px; color: black; margin-left: 20px;">
24 <i class="glyphicon glyphicon-calendar fa fa-calendar"></i>&nbsp; 32 <i class="glyphicon glyphicon-calendar fa fa-calendar"></i>&nbsp;
25 <span></span> <b class="caret"></b> 33 <span></span> <b class="caret"></b>
26 </div> 34 </div>
@@ -41,7 +49,6 @@ @@ -41,7 +49,6 @@
41 <th>时间</th> 49 <th>时间</th>
42 <th>应用</th> 50 <th>应用</th>
43 <th>类型</th> 51 <th>类型</th>
44 - <th>父请求ID</th>  
45 <th>请求ID</th> 52 <th>请求ID</th>
46 <td>用户ID</td> 53 <td>用户ID</td>
47 <td>访客ID</td> 54 <td>访客ID</td>
@@ -63,13 +70,13 @@ @@ -63,13 +70,13 @@
63 70
64 71
65 <script> 72 <script>
66 - var selectedStarTime, selectedEndTime, selectedApp; 73 + var selectedServer, selectedStarTime, selectedEndTime, selectedApp;
67 var data_end_point = '/profile/error.json'; 74 var data_end_point = '/profile/error.json';
68 var dataTable = null; 75 var dataTable = null;
69 var handleChanged = skipOnce(_handleChanged); 76 var handleChanged = skipOnce(_handleChanged);
70 77
71 function ajaxUrl() { 78 function ajaxUrl() {
72 - return `${data_end_point}?start=${selectedStarTime.format('YYYY-MM-DD')}&end=${selectedEndTime.format('YYYY-MM-DD')}&app=${selectedApp}` 79 + return `${data_end_point}?start=${selectedStarTime.format('YYYY-MM-DD')}&end=${selectedEndTime.format('YYYY-MM-DD')}&app=${selectedApp}&server=${selectedServer}`
73 } 80 }
74 81
75 function skipOnce(fn) { 82 function skipOnce(fn) {
@@ -89,6 +96,7 @@ @@ -89,6 +96,7 @@
89 }); 96 });
90 97
91 function init() { 98 function init() {
  99 + selectedServer = 'aws';
92 selectedStarTime = moment(); 100 selectedStarTime = moment();
93 selectedEndTime = moment().add(1, 'days'); 101 selectedEndTime = moment().add(1, 'days');
94 selectedApp = 'default'; 102 selectedApp = 'default';
@@ -108,7 +116,6 @@ @@ -108,7 +116,6 @@
108 { data: 'time' }, 116 { data: 'time' },
109 { data: 'app' }, 117 { data: 'app' },
110 { data: 'type' }, 118 { data: 'type' },
111 - { data: 'preqID' },  
112 { data: 'reqID' }, 119 { data: 'reqID' },
113 { data: 'uid' }, 120 { data: 'uid' },
114 { data: 'udid' }, 121 { data: 'udid' },
@@ -178,6 +185,11 @@ @@ -178,6 +185,11 @@
178 } 185 }
179 186
180 function initSelect() { 187 function initSelect() {
  188 + $('#selectedServer').change(function() {
  189 + selectedApp = $('#selectedServer').val();
  190 + handleChanged();
  191 + });
  192 +
181 $('#selectedApp').change(function() { 193 $('#selectedApp').change(function() {
182 selectedApp = $('#selectedApp').val(); 194 selectedApp = $('#selectedApp').val();
183 handleChanged(); 195 handleChanged();
@@ -19,8 +19,16 @@ @@ -19,8 +19,16 @@
19 <div class="contentpanel page-servers"> 19 <div class="contentpanel page-servers">
20 <div class="panel panel-primary-head"> 20 <div class="panel panel-primary-head">
21 <div class="panel-heading" style="overflow: hidden"> 21 <div class="panel-heading" style="overflow: hidden">
  22 +
  23 + <div class="pull-left">
  24 + <select id="selectedServer" class="selectpicker show-menu-arrow form-control" style="margin-left: 10px;">
  25 + <option value="aws" selected>aws</option>
  26 + <option value="qcloud">qcloud</option>
  27 + </select>
  28 + </div>
  29 +
22 <div id="reportrange" class="pull-left" 30 <div id="reportrange" class="pull-left"
23 - style="display: inline-block; background: #fff; cursor: pointer; padding: 9px 10px; border: 1px solid #ccc; width: 250px; color: black"> 31 + style="display: inline-block; background: #fff; cursor: pointer; padding: 9px 10px; border: 1px solid #ccc; width: 250px; color: black; margin-left: 20px;">
24 <i class="glyphicon glyphicon-calendar fa fa-calendar"></i>&nbsp; 32 <i class="glyphicon glyphicon-calendar fa fa-calendar"></i>&nbsp;
25 <span></span> <b class="caret"></b> 33 <span></span> <b class="caret"></b>
26 </div> 34 </div>
@@ -53,7 +61,6 @@ @@ -53,7 +61,6 @@
53 <td>接口名称</td> 61 <td>接口名称</td>
54 <td>请求路由</td> 62 <td>请求路由</td>
55 <td>耗时</td> 63 <td>耗时</td>
56 - <th>父请求ID</th>  
57 <th>请求ID</th> 64 <th>请求ID</th>
58 <td>用户ID</td> 65 <td>用户ID</td>
59 <td>访客ID</td></tr> 66 <td>访客ID</td></tr>
@@ -68,13 +75,13 @@ @@ -68,13 +75,13 @@
68 75
69 76
70 <script> 77 <script>
71 - var selectedStarTime, selectedEndTime, selectedApp, selectedDuration; 78 + var selectedServer, selectedStarTime, selectedEndTime, selectedApp, selectedDuration;
72 var data_end_point = '/profile/time.json'; 79 var data_end_point = '/profile/time.json';
73 var dataTable = null; 80 var dataTable = null;
74 var handleChanged = skipOnce(_handleChanged); 81 var handleChanged = skipOnce(_handleChanged);
75 82
76 function ajaxUrl() { 83 function ajaxUrl() {
77 - return `${data_end_point}?start=${selectedStarTime.format('YYYY-MM-DD')}&end=${selectedEndTime.format('YYYY-MM-DD')}&app=${selectedApp}&duration=${selectedDuration}` 84 + return `${data_end_point}?start=${selectedStarTime.format('YYYY-MM-DD')}&end=${selectedEndTime.format('YYYY-MM-DD')}&app=${selectedApp}&duration=${selectedDuration}&server=${selectedServer}`
78 } 85 }
79 86
80 function skipOnce(fn) { 87 function skipOnce(fn) {
@@ -95,6 +102,7 @@ @@ -95,6 +102,7 @@
95 }); 102 });
96 103
97 function init() { 104 function init() {
  105 + selectedServer = 'aws';
98 selectedStarTime = moment(); 106 selectedStarTime = moment();
99 selectedEndTime = moment().add(1, 'days'); 107 selectedEndTime = moment().add(1, 'days');
100 selectedApp = 'default'; 108 selectedApp = 'default';
@@ -118,7 +126,6 @@ @@ -118,7 +126,6 @@
118 {data: "api"}, 126 {data: "api"},
119 {data: "route"}, 127 {data: "route"},
120 {data: "duration"}, 128 {data: "duration"},
121 - {data: "preqID"},  
122 {data: "reqID"}, 129 {data: "reqID"},
123 {data: "uid"}, 130 {data: "uid"},
124 {data: "udid"} 131 {data: "udid"}
@@ -182,6 +189,11 @@ @@ -182,6 +189,11 @@
182 } 189 }
183 190
184 function initSelect() { 191 function initSelect() {
  192 + $('#selectedServer').change(function() {
  193 + selectedServer = $('#selectedServer').val();
  194 + handleChanged();
  195 + });
  196 +
185 $('#selectedApp').change(function() { 197 $('#selectedApp').change(function() {
186 selectedApp = $('#selectedApp').val(); 198 selectedApp = $('#selectedApp').val();
187 handleChanged(); 199 handleChanged();
@@ -5,16 +5,23 @@ const path = require('path'); @@ -5,16 +5,23 @@ const path = require('path');
5 const env = process.env.NODE_ENV || 'development'; 5 const env = process.env.NODE_ENV || 'development';
6 6
7 const defaults = { 7 const defaults = {
8 - port: 9000,  
9 - buildDir: path.normalize(__dirname + '/../packages/'),  
10 - dbDir: path.normalize(__dirname + '/../db'),  
11 - influxdb: {  
12 - host: 'influxd.yoho.cn',  
13 - port: 80  
14 - },  
15 - redis: {  
16 - connect: {  
17 - host: '127.0.0.1', 8 + port: 9000,
  9 + buildDir: path.normalize(__dirname + '/../packages/'),
  10 + dbDir: path.normalize(__dirname + '/../db'),
  11 + influxdb: {
  12 + aws: {
  13 + host: 'influxd.yoho.cn',
  14 + port: 80
  15 + },
  16 + qcloud: {
  17 + host: 'influxd.yoho.cn',
  18 + port: 80
  19 + }
  20 +
  21 + },
  22 + redis: {
  23 + connect: {
  24 + host: '127.0.0.1',
18 port: '6379', 25 port: '6379',
19 retry_strategy: options => { 26 retry_strategy: options => {
20 if (options.error && options.error.code === 'ECONNREFUSED') { 27 if (options.error && options.error.code === 'ECONNREFUSED') {
@@ -29,65 +36,71 @@ const defaults = { @@ -29,65 +36,71 @@ const defaults = {
29 } 36 }
30 return Math.min(options.attempt * 100, 1000); 37 return Math.min(options.attempt * 100, 1000);
31 } 38 }
32 - }  
33 - },  
34 - mysql: {  
35 - host: '192.168.102.219',  
36 - user: 'yh_test',  
37 - password: 'yh_test',  
38 - port: '3306',  
39 - database: 'yoho_seo'  
40 - },  
41 - domains: {  
42 - // test3  
43 - singleApi: 'http://api-test3.yohops.com:9999/',  
44 - api: 'http://api-test3.yohops.com:9999/',  
45 - service: 'http://service-test3.yohops.com:9999/',  
46 - serviceNotify: 'http://service-test3.yohops.com:9999/',  
47 - global: 'http://global-test-soa.yohops.com:9999/',  
48 - platformApi: 'http://192.168.102.48:8088/',  
49 - search: 'http://192.168.102.216:8080/yohosearch/', 39 + }
  40 + },
  41 + mysql: {
  42 + host: '192.168.102.219',
  43 + user: 'yh_test',
  44 + password: 'yh_test',
  45 + port: '3306',
  46 + database: 'yoho_seo'
  47 + },
  48 + domains: {
  49 + // test3
  50 + singleApi: 'http://api-test3.yohops.com:9999/',
  51 + api: 'http://api-test3.yohops.com:9999/',
  52 + service: 'http://service-test3.yohops.com:9999/',
  53 + serviceNotify: 'http://service-test3.yohops.com:9999/',
  54 + global: 'http://global-test-soa.yohops.com:9999/',
  55 + platformApi: 'http://192.168.102.48:8088/',
  56 + search: 'http://192.168.102.216:8080/yohosearch/',
50 57
51 - imSocket: 'ws://socket.yohobuy.com:10240',  
52 - imCs: 'http://im.yohobuy.com/api',  
53 - unionApi: 'http://172.16.6.90:8080/', 58 + imSocket: 'ws://socket.yohobuy.com:10240',
  59 + imCs: 'http://im.yohobuy.com/api',
  60 + unionApi: 'http://172.16.6.90:8080/',
54 61
55 - }, 62 + },
56 baiduToken: '0lSAO4ZxEKsYopMG', 63 baiduToken: '0lSAO4ZxEKsYopMG',
57 64
58 - // redis key prefix  
59 - singleBrandKeyPre: 'golobal:yoho:single_brand:', // key: 品牌id, val: 名牌名  
60 - singleSortKeyPre: 'golobal:yoho:single_sort:' // key: 品类id, val: 品类名 65 + // redis key prefix
  66 + singleBrandKeyPre: 'golobal:yoho:single_brand:', // key: 品牌id, val: 名牌名
  67 + singleSortKeyPre: 'golobal:yoho:single_sort:' // key: 品类id, val: 品类名
61 }; 68 };
62 69
63 const specific = { 70 const specific = {
64 - development: {},  
65 - test: {},  
66 - production: { 71 + development: {},
  72 + test: {},
  73 + production: {
67 influxdb: { 74 influxdb: {
68 - host: 'influxdblog.web.yohoops.org',  
69 - port: 4444 75 + aws: {
  76 + host: '172.31.26.70',
  77 + port: 8086
  78 + },
  79 + qcloud: {
  80 + host: '10.66.0.139',
  81 + port: 8086
  82 + }
70 }, 83 },
71 redis: { 84 redis: {
72 connect: { 85 connect: {
73 host: 'web.redis.yohoops.org', 86 host: 'web.redis.yohoops.org',
74 port: '6379', 87 port: '6379',
75 retry_strategy: options => { 88 retry_strategy: options => {
76 - if (options.error && options.error.code === 'ECONNREFUSED') {  
77 - console.log('redis连接不成功');  
78 - }  
79 - if (options.total_retry_time > 1000 * 60 * 60 * 6) {  
80 - console.log('redis连接超时');  
81 - return;  
82 - }  
83 - if (options.attempt > 10) {  
84 - return 1000 * 60 * 60 * 0.5;  
85 - }  
86 - return Math.min(options.attempt * 100, 1000); 89 + if (options.error && options.error.code === 'ECONNREFUSED') {
  90 + console.log('redis连接不成功');
  91 + }
  92 + if (options.total_retry_time > 1000 * 60 * 60 * 6) {
  93 + console.log('redis连接超时');
  94 + return;
  95 + }
  96 + if (options.attempt > 10) {
  97 + return 1000 * 60 * 60 * 0.5;
  98 + }
  99 + return Math.min(options.attempt * 100, 1000);
87 } 100 }
88 } 101 }
89 }, 102 },
90 - mysql: { 103 + mysql: {
91 host: '172.31.200.242', 104 host: '172.31.200.242',
92 user: 'yoho_seo_user', 105 user: 'yoho_seo_user',
93 password: 'eRUWnPm6nqWT', 106 password: 'eRUWnPm6nqWT',
@@ -95,15 +108,15 @@ const specific = { @@ -95,15 +108,15 @@ const specific = {
95 database: 'yoho_seo', 108 database: 'yoho_seo',
96 }, 109 },
97 domains: { 110 domains: {
98 - singleApi: 'http://single.yoho.cn/',  
99 - api: 'http://api.yoho.cn/',  
100 - service: 'http://service.yoho.cn/',  
101 - serviceNotify: 'http://service.yoho.cn/',  
102 - global: 'http://api-global.yohobuy.com/',  
103 - platformApi: 'http://172.16.6.210:8088/',  
104 - search: 'http://search.yohoops.org/yohosearch/' 111 + singleApi: 'http://single.yoho.cn/',
  112 + api: 'http://api.yoho.cn/',
  113 + service: 'http://service.yoho.cn/',
  114 + serviceNotify: 'http://service.yoho.cn/',
  115 + global: 'http://api-global.yohobuy.com/',
  116 + platformApi: 'http://172.16.6.210:8088/',
  117 + search: 'http://search.yohoops.org/yohosearch/'
105 } 118 }
106 - }, 119 + },
107 }; 120 };
108 121
109 module.exports = Object.assign(defaults, specific[env]); 122 module.exports = Object.assign(defaults, specific[env]);