Authored by htoooth

fix

... ... @@ -12,7 +12,7 @@ const endpoint = (server) => `http://${server.host}:${server.port}`;
const r = new Router;
const TABLE = {
DURATION: 'web-client-duration',
CLIENT: 'web-client-duration',
REPORT: 'error-report',
SERVER: 'web-server-duration'
};
... ... @@ -24,6 +24,11 @@ const APP_NAME = {
h5: 'yohobuywap-node'
};
const APP_NAME2 = {
pc: 'www.yohobuy.com',
h5: 'm.yohobuy.com'
};
const TYPE = {
DOMContentLoaded: 0,
load: 0,
... ... @@ -31,8 +36,8 @@ const TYPE = {
};
const profile_sql = {
duration() {
return SqlBuilder.of(TABLE.DURATION);
client() {
return SqlBuilder.of(TABLE.CLIENT);
},
error() {
return SqlBuilder.of(TABLE.REPORT);
... ... @@ -62,6 +67,12 @@ const APP = {
h5: {field: 'app', op: '=', value: APP_NAME.h5}
};
const APP2 = {
default: {field: '', op: '', value: ''},
pc: {field: 'app', op: '=', value: APP_NAME2.pc},
h5: {field: 'app', op: '=', value: APP_NAME2.h5}
};
const SERVER = {
aws: endpoint(config.apm.aws),
qcloud: endpoint(config.apm.qcloud)
... ... @@ -77,6 +88,14 @@ function handleZip(items) {
});
}
function handleZip2(item) {
const col = _.get(item, 'columns', []);
const values = _.get(item, "values[0]", []);
const tags = _.get(item, "tags", []);
return Object.assign({}, _.zipObject(col, values), tags)
}
function handleRows(rows) {
let stats = rows.reduce((acc, cur) => {
_.updateWith(acc, [cur.route, cur.type, 'duration'], function(n) {
... ... @@ -126,9 +145,21 @@ function handleRows(rows) {
return result;
}
function handleApi(totalRows, apiRows) {
let totalObj = totalRows.map(handleZip2);
let apiObj = apiRows.map(handleZip2);
totalObj.forEach(i => {
i.detail = jp.query(apiObj, `$..[?(@.route=="${i.route}")]`);
i.length = i.detail.length;
});
return totalObj;
}
const profile_service = {
async mean(server, start, end, app, lastTime) {
const model = profile_sql.duration()
async client_time(server, start, end, app, lastTime) {
const model = profile_sql.client()
.select('*')
.where(APP[app]);
... ... @@ -149,10 +180,12 @@ const profile_service = {
return {code: 200, data: rows}
},
async time(server, start, end, app, lastTime) {
const model = profile_sql.duration()
.select('*')
.where(APP[app]);
async server_time(server, start, end, app, lastTime) {
const model = profile_sql.server()
.select('count("duration"), mean("duration")')
.where(APP2[app])
.where('type', '=', 'route')
.groupBy(['route']);
if (lastTime) {
model.where('time', '>=', SqlBuilder.raw(`now() - ${lastTime}`))
... ... @@ -163,9 +196,28 @@ const profile_service = {
.where('time', '<', end);
}
const rows = await exec(SERVER[server], model.toSql())
.then(result => _.get(result, 'results[0].series[0]', []))
.then(handleZip);
const total = await exec(SERVER[server], model.toSql())
.then(result => _.get(result, 'results[0].series', []));
const apiModel = profile_sql.server()
.select('count("duration"), mean("duration")')
.where(APP2[app])
.where('type', '=', 'api')
.groupBy(['route', 'api']);
if (lastTime) {
apiModel.where('time', '>=', SqlBuilder.raw(`now() - ${lastTime}`))
}
if (start && end) {
apiModel.where('time', '>=', start)
.where('time', '<', end);
}
const api = await exec(SERVER[server], apiModel.toSql())
.then(result => _.get(result, 'results[0].series', []));
const rows = handleApi(total, api);
return {cde: 200, data: rows};
},
... ... @@ -192,30 +244,30 @@ const profile_service = {
};
const profile_controller = {
async mean_report_index(ctx) {
await ctx.render('action/profile_mean');
async client_mean_report_index(ctx) {
await ctx.render('action/profile_client');
},
async mean_report_json(ctx) {
async client_mean_report_json(ctx) {
const start = ctx.query.start;
const end = ctx.query.end;
const app = ctx.query.app;
const server = ctx.query.server || 'aws';
const lastTime = ctx.query.lastTime;
const result = await profile_service.mean(server, start, end, app, lastTime);
const result = await profile_service.client_time(server, start, end, app, lastTime);
ctx.body = result;
},
async time_report_index(ctx) {
await ctx.render('action/profile_time');
async server_mean_report_index(ctx) {
await ctx.render('action/profile_server');
},
async time_report_json(ctx) {
async server_mean_report_json(ctx) {
const start = ctx.query.start;
const end = ctx.query.end;
const app = ctx.query.app;
const server = ctx.query.server || 'aws';
const lastTime = ctx.query.lastTime;
const result = await profile_service.time(server, start, end, app, lastTime);
const result = await profile_service.server_time(server, start, end, app, lastTime);
ctx.body = result;
},
async error_report_index(ctx) {
... ... @@ -234,11 +286,11 @@ const profile_controller = {
};
r.get('/mean', profile_controller.mean_report_index);
r.get('/mean.json', profile_controller.mean_report_json);
r.get('/client', profile_controller.client_mean_report_index);
r.get('/client.json', profile_controller.client_mean_report_json);
r.get('/time', profile_controller.time_report_index);
r.get('/time.json', profile_controller.time_report_json);
r.get('/server', profile_controller.server_mean_report_index);
r.get('/server.json', profile_controller.server_mean_report_json);
r.get('/error', profile_controller.error_report_index);
r.get('/error.json', profile_controller.error_report_json);
... ...
... ... @@ -7,9 +7,9 @@
<ul class="breadcrumb">
<li><a href=""><i class="glyphicon glyphicon-home"></i></a></li>
<li><a href="">性能监控</a></li>
<li>调用时间统计</li>
<li>客户端调用时间统计</li>
</ul>
<h4>调用时间统计</h4>
<h4>客户端调用时间统计</h4>
</div>
</div>
<!-- media -->
... ... @@ -103,7 +103,7 @@
<script>
var selectedServer, selectedStarTime, selectedEndTime, selectedApp, lastTime;
var data_end_point = '/profile/mean.json';
var data_end_point = '/profile/client.json';
var dataTable = null, detailTable = null;
function ajaxUrl() {
... ... @@ -170,7 +170,7 @@
$('#table-servers tbody').on( 'click', 'button', function (e) {
var data = dataTable.row($(this).parents('tr')).data();
var modal = $('#myModal'), modalBody = $('#myModal .modal-body');
var modal = $('#myModal');
modal.on('show.bs.modal', function () {
detailTable.clear().rows.add(data.detail).draw();
... ...
... ... @@ -7,9 +7,9 @@
<ul class="breadcrumb">
<li><a href=""><i class="glyphicon glyphicon-home"></i></a></li>
<li><a href="">性能监控</a></li>
<li>耗时分析</li>
<li>服务器调用时间统计</li>
</ul>
<h4>耗时分析</h4>
<h4>服务器调用时间统计</h4>
</div>
</div>
<!-- media -->
... ... @@ -21,8 +21,7 @@
<div class="panel-heading" style="overflow: hidden">
<div class="pull-left">
<select id="selectedServer" class="selectpicker show-menu-arrow form-control"
style="margin-left: 10px;">
<select id="selectedServer" class="selectpicker show-menu-arrow form-control" style="margin-left: 10px;">
<option value="aws" selected>aws</option>
<option value="qcloud">qcloud</option>
</select>
... ... @@ -48,33 +47,57 @@
</div>
<!-- panel-heading -->
<table id="table-servers" class="table table-striped table-bordered responsive">
<table id="table-servers" class="table table-striped table-bordered">
<thead class="">
<tr>
<th>时间</th>
<th>应用</th>
<th>类型</th>
<td>接口名称</td>
<td>请求路由</td>
<td>耗时</td>
<th>请求ID</th>
<td>用户ID</td>
<td>访客ID</td>
</tr>
<td >接口名称</td>
<td >调用次数</td>
<td >耗时</td>
<td >调用接口数</td>
<td >详细情况</td>
</thead>
<tbody>
</tbody>
</table>
</div>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog modal-lg" role="document" style="display:table;">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="myModalLabel">详细信息</h4>
</div>
<div class="modal-body">
<table id="table-detail" class="table table-striped table-bordered">
<thead class="">
<tr>
<td >time</td>
<td >api</td>
<td >count</td>
<td >mean</td>
</thead>
<tbody>
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
</div>
</div>
</div>
</div>
<!-- panel -->
</div>
<script>
var selectedServer, selectedStarTime, selectedEndTime, selectedApp, lastTime;
var data_end_point = '/profile/time.json';
var dataTable = null;
var data_end_point = '/profile/server.json';
var dataTable = null, detailTable = null;
function ajaxUrl() {
let url = `${data_end_point}?app=${selectedApp}&server=${selectedServer}`;
... ... @@ -99,8 +122,6 @@
function init() {
selectedServer = 'aws';
selectedStarTime = moment();
selectedEndTime = moment().add(1, 'days');
selectedApp = 'default';
}
... ... @@ -108,33 +129,64 @@
dataTable = $("#table-servers").DataTable({
pageLength: 20,
retrieve: true,
responsive: true,
searching: true,
dataSrc: 'data',
pageLength: 25,
deferLoading: 0,
columns: [
{data: "time"},
{data: "app"},
{data: "type"},
{data: "api"},
{data: "route"},
{data: "duration"},
{data: "reqID"},
{data: "uid"},
{data: "udid"}
{data: 'route'},
{data: 'count'},
{data: 'mean'},
{data: 'length'},
{data: 'detail'}
],
data: [{
route: '',
count: 0,
mean: 0,
length: 0,
detail: ''
}],
order: [[ 2, "desc" ]],
columnDefs: [ {
targets: -1,
data: null,
render: function ( data, type, row ) {
return '<button data-toggle="modal" data-target="#myModal">查看</button>';
},
}]
});
$('#table-servers tbody').on( 'click', 'button', function (e) {
var data = dataTable.row($(this).parents('tr')).data();
var modal = $('#myModal');
modal.on('show.bs.modal', function () {
detailTable.clear().rows.add(data.detail).draw();
});
e.preventDefault();
});
detailTable = $("#table-detail").DataTable({
pageLength: 20,
retrieve: true,
searching: true,
dataSrc: 'data',
pageLength: 25,
columns: [
{data: 'time'},
{data: 'api'},
{data: 'count'},
{data: 'mean'}
],
data: [{
time: "",
app: "",
type: "",
api: "",
route: "",
duration: "",
reqID: "",
uid: "",
udid: ""
time: '',
api: '',
count: '',
mean: ''
}],
order: [[ 0, "desc" ]],
columnDefs: [
{
render: function(data, type, row) {
... ... @@ -143,13 +195,12 @@
targets: 0
}
],
order: [[0, "desc"]]
});
}
const TIME = {
'最近1分钟': '1m',
'最近30分钟': '30m',
'最近30分钟': '30m',
'最近1小时': '1h',
'最近3小时': '3h',
'最近6小时': '6h',
... ... @@ -169,7 +220,7 @@
if (label && label !== '自定义日期') {
$('#reportrange span').html(label);
lastTime = TIME[label];
} else if (label && label === '自定义日期') {
} else if (label && label === '自定义日期'){
$('#reportrange span').html(start.format('YYYY-MM-DD') + ' 至 ' + end.format('YYYY-MM-DD'));
selectedStarTime = start.format('YYYY-MM-DD');
selectedEndTime = end.format('YYYY-MM-DD');
... ...
... ... @@ -77,8 +77,8 @@
<li class="parent"><a><i class="fa fa-list"></i> <span>性能统计</span></a>
<ul class="children">
<li><a href="/profile/mean"> <span>客户端调用时间统计</span></a></li>
<li><a href="/profile/time"> <span>调用时间统计</span></a></li>
<li><a href="/profile/client"> <span>客户端调用时间统计</span></a></li>
<li><a href="/profile/server"> <span>服务器调用时间统计</span></a></li>
<li><a href="/profile/error"> <span>错误信息统计</span></a></li>
</ul>
</li>
... ...