Showing
4 changed files
with
287 additions
and
20 deletions
@@ -79,7 +79,7 @@ function handleCount(rows) { | @@ -79,7 +79,7 @@ function handleCount(rows) { | ||
79 | } | 79 | } |
80 | 80 | ||
81 | const profile_service = { | 81 | const profile_service = { |
82 | - async time(server, start, end, app, lastTime) { | 82 | + async mean(server, start, end, app, lastTime) { |
83 | const model = profile_sql.duration() | 83 | const model = profile_sql.duration() |
84 | .select('*') | 84 | .select('*') |
85 | .where(APP[app]); | 85 | .where(APP[app]); |
@@ -123,6 +123,26 @@ const profile_service = { | @@ -123,6 +123,26 @@ const profile_service = { | ||
123 | 123 | ||
124 | return {code: 200, data: rows} | 124 | return {code: 200, data: rows} |
125 | }, | 125 | }, |
126 | + async time(server, start, end, app, lastTime) { | ||
127 | + const model = profile_sql.duration() | ||
128 | + .select('*') | ||
129 | + .where(APP[app]); | ||
130 | + | ||
131 | + if (lastTime) { | ||
132 | + model.where('time', '>=', SqlBuilder.raw(`now() - ${lastTime}`)) | ||
133 | + } | ||
134 | + | ||
135 | + if (start && end) { | ||
136 | + model.where('time', '>=', start) | ||
137 | + .where('time', '<', end); | ||
138 | + } | ||
139 | + | ||
140 | + const rows = await exec(SERVER[server], model.toSql()) | ||
141 | + .then(result => _.get(result, 'results[0].series[0]', [])) | ||
142 | + .then(handleZip); | ||
143 | + | ||
144 | + return {cde: 200, data: rows}; | ||
145 | + }, | ||
126 | async error(server, start, end, app, lastTime) { | 146 | async error(server, start, end, app, lastTime) { |
127 | const model = profile_sql.error() | 147 | const model = profile_sql.error() |
128 | .select('*') | 148 | .select('*') |
@@ -146,10 +166,10 @@ const profile_service = { | @@ -146,10 +166,10 @@ const profile_service = { | ||
146 | }; | 166 | }; |
147 | 167 | ||
148 | const profile_controller = { | 168 | const profile_controller = { |
149 | - async time_report_index(ctx) { | ||
150 | - await ctx.render('action/profile_time'); | 169 | + async mean_report_index(ctx) { |
170 | + await ctx.render('action/profile_mean'); | ||
151 | }, | 171 | }, |
152 | - async time_report_json(ctx) { | 172 | + async mean_report_json(ctx) { |
153 | const start = ctx.query.start; | 173 | const start = ctx.query.start; |
154 | const end = ctx.query.end; | 174 | const end = ctx.query.end; |
155 | const app = ctx.query.app; | 175 | const app = ctx.query.app; |
@@ -172,6 +192,19 @@ const profile_controller = { | @@ -172,6 +192,19 @@ const profile_controller = { | ||
172 | const result = await profile_service.count(server, start, end, app, lastTime); | 192 | const result = await profile_service.count(server, start, end, app, lastTime); |
173 | ctx.body = result; | 193 | ctx.body = result; |
174 | }, | 194 | }, |
195 | + async time_report_index(ctx) { | ||
196 | + await ctx.render('action/profile_time'); | ||
197 | + }, | ||
198 | + async time_report_json(ctx) { | ||
199 | + const start = ctx.query.start; | ||
200 | + const end = ctx.query.end; | ||
201 | + const app = ctx.query.app; | ||
202 | + const server = ctx.query.server || 'aws'; | ||
203 | + const lastTime = ctx.query.lastTime; | ||
204 | + | ||
205 | + const result = await profile_service.time(server, start, end, app, lastTime); | ||
206 | + ctx.body = result; | ||
207 | + }, | ||
175 | async error_report_index(ctx) { | 208 | async error_report_index(ctx) { |
176 | await ctx.render('action/profile_error'); | 209 | await ctx.render('action/profile_error'); |
177 | }, | 210 | }, |
@@ -188,12 +221,15 @@ const profile_controller = { | @@ -188,12 +221,15 @@ const profile_controller = { | ||
188 | 221 | ||
189 | }; | 222 | }; |
190 | 223 | ||
191 | -r.get('/time', profile_controller.time_report_index); | ||
192 | -r.get('/time.json', profile_controller.time_report_json); | 224 | +r.get('/mean', profile_controller.mean_report_index); |
225 | +r.get('/mean.json', profile_controller.mean_report_json); | ||
193 | 226 | ||
194 | r.get('/count', profile_controller.count_report_index); | 227 | r.get('/count', profile_controller.count_report_index); |
195 | r.get('/count.json', profile_controller.count_report_json); | 228 | r.get('/count.json', profile_controller.count_report_json); |
196 | 229 | ||
230 | +r.get('/time', profile_controller.time_report_index); | ||
231 | +r.get('/time.json', profile_controller.time_report_json); | ||
232 | + | ||
197 | r.get('/error', profile_controller.error_report_index); | 233 | r.get('/error', profile_controller.error_report_index); |
198 | r.get('/error.json', profile_controller.error_report_json); | 234 | r.get('/error.json', profile_controller.error_report_json); |
199 | 235 |
apps/web/views/action/profile_mean.hbs
0 → 100644
1 | +<div class="pageheader"> | ||
2 | + <div class="media"> | ||
3 | + <div class="pageicon pull-left"> | ||
4 | + <i class="fa fa-th-list"></i> | ||
5 | + </div> | ||
6 | + <div class="media-body"> | ||
7 | + <ul class="breadcrumb"> | ||
8 | + <li><a href=""><i class="glyphicon glyphicon-home"></i></a></li> | ||
9 | + <li><a href="">性能监控</a></li> | ||
10 | + <li>调用时间统计</li> | ||
11 | + </ul> | ||
12 | + <h4>调用时间统计</h4> | ||
13 | + </div> | ||
14 | + </div> | ||
15 | + <!-- media --> | ||
16 | +</div> | ||
17 | +<!-- pageheader --> | ||
18 | + | ||
19 | +<div class="contentpanel page-servers"> | ||
20 | + <div class="panel panel-primary-head"> | ||
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 | + | ||
30 | + <div id="reportrange" class="pull-left" | ||
31 | + style="display: inline-block; background: #fff; cursor: pointer; padding: 9px 10px; border: 1px solid #ccc; width: 250px; color: black; margin-left: 20px;"> | ||
32 | + <i class="glyphicon glyphicon-calendar fa fa-calendar"></i> | ||
33 | + <span></span> <b class="caret"></b> | ||
34 | + </div> | ||
35 | + | ||
36 | + <div class="pull-left"> | ||
37 | + <select id="selectedApp" class="selectpicker show-menu-arrow form-control" style="margin-left: 10px;"> | ||
38 | + <option value="default">全部</option> | ||
39 | + <option value="pc">PC</option> | ||
40 | + <option value="h5">H5</option> | ||
41 | + </select> | ||
42 | + </div> | ||
43 | + | ||
44 | + <div class="pull-left"> | ||
45 | + <button id="search" class="btn btn-info" style="margin-left: 20px;">查询</button> | ||
46 | + </div> | ||
47 | + </div> | ||
48 | + <!-- panel-heading --> | ||
49 | + | ||
50 | + <table id="table-servers" class="table table-striped table-bordered"> | ||
51 | + <thead class=""> | ||
52 | + <tr> | ||
53 | + <td >接口名称</td> | ||
54 | + <td >耗时</td> | ||
55 | + </thead> | ||
56 | + | ||
57 | + <tbody> | ||
58 | + </tbody> | ||
59 | + </table> | ||
60 | + </div> | ||
61 | + <!-- panel --> | ||
62 | +</div> | ||
63 | + | ||
64 | + | ||
65 | +<script> | ||
66 | + var selectedServer, selectedStarTime, selectedEndTime, selectedApp, lastTime; | ||
67 | + var data_end_point = '/profile/mean.json'; | ||
68 | + var dataTable = null; | ||
69 | + | ||
70 | + function ajaxUrl() { | ||
71 | + let url = `${data_end_point}?app=${selectedApp}&server=${selectedServer}`; | ||
72 | + | ||
73 | + if (selectedEndTime && selectedEndTime) { | ||
74 | + url += `&start=${selectedStarTime}&end=${selectedEndTime}`; | ||
75 | + } | ||
76 | + | ||
77 | + if (lastTime) { | ||
78 | + url += `&lastTime=${lastTime}` | ||
79 | + } | ||
80 | + | ||
81 | + return url | ||
82 | + } | ||
83 | + | ||
84 | + $(function() { | ||
85 | + init(); | ||
86 | + initTable(); | ||
87 | + initDatePicker(); | ||
88 | + initSelect(); | ||
89 | + }); | ||
90 | + | ||
91 | + function init() { | ||
92 | + selectedServer = 'aws'; | ||
93 | + selectedApp = 'default'; | ||
94 | + } | ||
95 | + | ||
96 | + function initTable() { | ||
97 | + dataTable = $("#table-servers").DataTable({ | ||
98 | + pageLength: 20, | ||
99 | + retrieve: true, | ||
100 | + searching: true, | ||
101 | + dataSrc: 'data', | ||
102 | + pageLength: 25, | ||
103 | + columns: [ | ||
104 | + {data: 'route'}, | ||
105 | + {data: 'mean'} | ||
106 | + ], | ||
107 | + data: [{ | ||
108 | + route: '', | ||
109 | + mean: '' | ||
110 | + }], | ||
111 | + order: [[ 1, "desc" ]] | ||
112 | + }); | ||
113 | + } | ||
114 | + | ||
115 | + const TIME = { | ||
116 | + '最近1分钟': '1m', | ||
117 | + '最近30分钟': '30m', | ||
118 | + '最近1小时': '1h', | ||
119 | + '最近3小时': '3h', | ||
120 | + '最近6小时': '6h', | ||
121 | + '最近12小时': '12h' | ||
122 | + }; | ||
123 | + | ||
124 | + function initDatePicker() { | ||
125 | + var start = selectedStarTime; | ||
126 | + var end = selectedEndTime; | ||
127 | + var first = '最近1分钟'; | ||
128 | + | ||
129 | + $('#reportrange span').html(first); | ||
130 | + | ||
131 | + lastTime = TIME[first]; | ||
132 | + | ||
133 | + function cb(start, end, label) { | ||
134 | + if (label && label !== '自定义日期') { | ||
135 | + $('#reportrange span').html(label); | ||
136 | + lastTime = TIME[label]; | ||
137 | + } else if (label && label === '自定义日期'){ | ||
138 | + $('#reportrange span').html(start.format('YYYY-MM-DD') + ' 至 ' + end.format('YYYY-MM-DD')); | ||
139 | + selectedStarTime = start.format('YYYY-MM-DD'); | ||
140 | + selectedEndTime = end.format('YYYY-MM-DD'); | ||
141 | + lastTime = null | ||
142 | + } | ||
143 | + | ||
144 | + } | ||
145 | + | ||
146 | + $('#reportrange').daterangepicker({ | ||
147 | + startDate: start, | ||
148 | + endDate: end, | ||
149 | + timePicker: true, | ||
150 | + timePicker24Hour: true, | ||
151 | + dateLimit: { | ||
152 | + days: 7 | ||
153 | + }, | ||
154 | + ranges: { | ||
155 | + '最近1分钟': [moment().subtract(1, 'minutes'), moment()], | ||
156 | + '最近30分钟': [moment().subtract(30, 'minutes'), moment()], | ||
157 | + '最近1小时': [moment().subtract(1, 'hours'), moment()], | ||
158 | + '最近3小时': [moment().subtract(3, 'hours'), moment()], | ||
159 | + '最近6小时': [moment().subtract(6, 'hours'), moment()], | ||
160 | + '最近12小时': [moment().subtract(12, 'hours'), moment()] | ||
161 | + }, | ||
162 | + locale: { | ||
163 | + format: "YYYY-MM-DD", | ||
164 | + applyLabel: '确定', | ||
165 | + cancelLabel: '取消', | ||
166 | + weekLabel: 'W', | ||
167 | + customRangeLabel: '自定义日期', | ||
168 | + daysOfWeek: '一_二_三_四_五_六_日'.split('_'), | ||
169 | + monthNames: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), | ||
170 | + firstDay: 1 | ||
171 | + }, | ||
172 | + }, cb); | ||
173 | + | ||
174 | + cb(start, end); | ||
175 | + } | ||
176 | + | ||
177 | + function initSelect() { | ||
178 | + $('#selectedServer').change(function() { | ||
179 | + selectedServer = $('#selectedServer').val(); | ||
180 | + }); | ||
181 | + | ||
182 | + $('#selectedApp').change(function() { | ||
183 | + selectedApp = $('#selectedApp').val(); | ||
184 | + }); | ||
185 | + | ||
186 | + $('#search').on('click', () => { | ||
187 | + _handleChanged(); | ||
188 | + }) | ||
189 | + } | ||
190 | + | ||
191 | + function _handleChanged() { | ||
192 | + dataTable && dataTable.ajax.url(ajaxUrl()).load(); | ||
193 | + } | ||
194 | + | ||
195 | +</script> |
@@ -7,9 +7,9 @@ | @@ -7,9 +7,9 @@ | ||
7 | <ul class="breadcrumb"> | 7 | <ul class="breadcrumb"> |
8 | <li><a href=""><i class="glyphicon glyphicon-home"></i></a></li> | 8 | <li><a href=""><i class="glyphicon glyphicon-home"></i></a></li> |
9 | <li><a href="">性能监控</a></li> | 9 | <li><a href="">性能监控</a></li> |
10 | - <li>调用时间统计</li> | 10 | + <li>耗时分析</li> |
11 | </ul> | 11 | </ul> |
12 | - <h4>调用时间统计</h4> | 12 | + <h4>耗时分析</h4> |
13 | </div> | 13 | </div> |
14 | </div> | 14 | </div> |
15 | <!-- media --> | 15 | <!-- media --> |
@@ -21,7 +21,8 @@ | @@ -21,7 +21,8 @@ | ||
21 | <div class="panel-heading" style="overflow: hidden"> | 21 | <div class="panel-heading" style="overflow: hidden"> |
22 | 22 | ||
23 | <div class="pull-left"> | 23 | <div class="pull-left"> |
24 | - <select id="selectedServer" class="selectpicker show-menu-arrow form-control" style="margin-left: 10px;"> | 24 | + <select id="selectedServer" class="selectpicker show-menu-arrow form-control" |
25 | + style="margin-left: 10px;"> | ||
25 | <option value="aws" selected>aws</option> | 26 | <option value="aws" selected>aws</option> |
26 | <option value="qcloud">qcloud</option> | 27 | <option value="qcloud">qcloud</option> |
27 | </select> | 28 | </select> |
@@ -47,11 +48,19 @@ | @@ -47,11 +48,19 @@ | ||
47 | </div> | 48 | </div> |
48 | <!-- panel-heading --> | 49 | <!-- panel-heading --> |
49 | 50 | ||
50 | - <table id="table-servers" class="table table-striped table-bordered"> | 51 | + <table id="table-servers" class="table table-striped table-bordered responsive"> |
51 | <thead class=""> | 52 | <thead class=""> |
52 | <tr> | 53 | <tr> |
53 | - <td >接口名称</td> | ||
54 | - <td >耗时</td> | 54 | + <th>时间</th> |
55 | + <th>应用</th> | ||
56 | + <th>类型</th> | ||
57 | + <td>接口名称</td> | ||
58 | + <td>请求路由</td> | ||
59 | + <td>耗时</td> | ||
60 | + <th>请求ID</th> | ||
61 | + <td>用户ID</td> | ||
62 | + <td>访客ID</td> | ||
63 | + </tr> | ||
55 | </thead> | 64 | </thead> |
56 | 65 | ||
57 | <tbody> | 66 | <tbody> |
@@ -90,6 +99,8 @@ | @@ -90,6 +99,8 @@ | ||
90 | 99 | ||
91 | function init() { | 100 | function init() { |
92 | selectedServer = 'aws'; | 101 | selectedServer = 'aws'; |
102 | + selectedStarTime = moment(); | ||
103 | + selectedEndTime = moment().add(1, 'days'); | ||
93 | selectedApp = 'default'; | 104 | selectedApp = 'default'; |
94 | } | 105 | } |
95 | 106 | ||
@@ -97,24 +108,48 @@ | @@ -97,24 +108,48 @@ | ||
97 | dataTable = $("#table-servers").DataTable({ | 108 | dataTable = $("#table-servers").DataTable({ |
98 | pageLength: 20, | 109 | pageLength: 20, |
99 | retrieve: true, | 110 | retrieve: true, |
111 | + responsive: true, | ||
100 | searching: true, | 112 | searching: true, |
101 | dataSrc: 'data', | 113 | dataSrc: 'data', |
102 | pageLength: 25, | 114 | pageLength: 25, |
115 | + deferLoading: 0, | ||
103 | columns: [ | 116 | columns: [ |
104 | - {data: 'route'}, | ||
105 | - {data: 'mean'} | 117 | + {data: "time"}, |
118 | + {data: "app"}, | ||
119 | + {data: "type"}, | ||
120 | + {data: "api"}, | ||
121 | + {data: "route"}, | ||
122 | + {data: "duration"}, | ||
123 | + {data: "reqID"}, | ||
124 | + {data: "uid"}, | ||
125 | + {data: "udid"} | ||
106 | ], | 126 | ], |
107 | data: [{ | 127 | data: [{ |
108 | - route: '', | ||
109 | - mean: '' | 128 | + time: "", |
129 | + app: "", | ||
130 | + type: "", | ||
131 | + api: "", | ||
132 | + route: "", | ||
133 | + duration: "", | ||
134 | + reqID: "", | ||
135 | + uid: "", | ||
136 | + udid: "" | ||
110 | }], | 137 | }], |
111 | - order: [[ 1, "desc" ]] | 138 | + columnDefs: [ |
139 | + { | ||
140 | + render: function(data, type, row) { | ||
141 | + return moment(data).format('YYYY/MM/DD HH:MM:ss'); | ||
142 | + }, | ||
143 | + targets: 0 | ||
144 | + } | ||
145 | + ], | ||
146 | + order: [[0, "desc"]] | ||
112 | }); | 147 | }); |
113 | } | 148 | } |
114 | 149 | ||
115 | const TIME = { | 150 | const TIME = { |
116 | '最近1分钟': '1m', | 151 | '最近1分钟': '1m', |
117 | - '最近30分钟': '30m', | 152 | + '最近30分钟': '30m', |
118 | '最近1小时': '1h', | 153 | '最近1小时': '1h', |
119 | '最近3小时': '3h', | 154 | '最近3小时': '3h', |
120 | '最近6小时': '6h', | 155 | '最近6小时': '6h', |
@@ -134,7 +169,7 @@ | @@ -134,7 +169,7 @@ | ||
134 | if (label && label !== '自定义日期') { | 169 | if (label && label !== '自定义日期') { |
135 | $('#reportrange span').html(label); | 170 | $('#reportrange span').html(label); |
136 | lastTime = TIME[label]; | 171 | lastTime = TIME[label]; |
137 | - } else if (label && label === '自定义日期'){ | 172 | + } else if (label && label === '自定义日期') { |
138 | $('#reportrange span').html(start.format('YYYY-MM-DD') + ' 至 ' + end.format('YYYY-MM-DD')); | 173 | $('#reportrange span').html(start.format('YYYY-MM-DD') + ' 至 ' + end.format('YYYY-MM-DD')); |
139 | selectedStarTime = start.format('YYYY-MM-DD'); | 174 | selectedStarTime = start.format('YYYY-MM-DD'); |
140 | selectedEndTime = end.format('YYYY-MM-DD'); | 175 | selectedEndTime = end.format('YYYY-MM-DD'); |
@@ -77,8 +77,9 @@ | @@ -77,8 +77,9 @@ | ||
77 | 77 | ||
78 | <li class="parent"><a><i class="fa fa-list"></i> <span>性能统计</span></a> | 78 | <li class="parent"><a><i class="fa fa-list"></i> <span>性能统计</span></a> |
79 | <ul class="children"> | 79 | <ul class="children"> |
80 | - <li><a href="/profile/time"> <span>调用时间统计</span></a></li> | 80 | + <li><a href="/profile/mean"> <span>调用时间统计</span></a></li> |
81 | <li><a href="/profile/count"> <span>调用次数统计</span></a></li> | 81 | <li><a href="/profile/count"> <span>调用次数统计</span></a></li> |
82 | + <li><a href="/profile/time"> <span>调用时间统计</span></a></li> | ||
82 | <li><a href="/profile/error"> <span>错误信息统计</span></a></li> | 83 | <li><a href="/profile/error"> <span>错误信息统计</span></a></li> |
83 | </ul> | 84 | </ul> |
84 | </li> | 85 | </li> |
-
Please register or login to post a comment