guest_detail.html 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. {% extends "layout.html" %}
  2. {% block title %} Guest {% endblock %}
  3. {% block head %}
  4. {{ super() }}
  5. <style type="text/css">
  6. @media (min-width: 768px) {
  7. .form-horizontal .control-label {
  8. text-align: left;
  9. }
  10. }
  11. label>span {
  12. color: deepskyblue;
  13. }
  14. .btn,
  15. .form-group>div>div,
  16. .form-control {
  17. border-radius: 0;
  18. }
  19. .table {
  20. font-size: 12px;
  21. border-width: 1px;
  22. line-height: 22px;
  23. }
  24. .table > tbody > tr > td {
  25. color: #424547;
  26. }
  27. .table-bordered > tbody > tr {
  28. padding-top: 10px;
  29. padding-bottom: 10px;
  30. }
  31. .table-bordered > thead > tr > th,
  32. .table-bordered > tbody > tr > th,
  33. .table-bordered > tfoot > tr > th,
  34. .table-bordered > thead > tr > td,
  35. .table-bordered > tbody > tr > td,
  36. .table-bordered > tfoot > tr > td {
  37. border-style: solid;
  38. border-width: 1px 0 0 0;
  39. }
  40. .guest-label {
  41. color: #999999;
  42. }
  43. .guest-desc {
  44. color: #333333;
  45. }
  46. </style>
  47. {% endblock head %}
  48. {% block body %}
  49. <script>
  50. var resource_path = window.location.pathname;
  51. var resource_path_array = resource_path.split('/');
  52. var uuid = resource_path_array[resource_path_array.length - 1];
  53. var cpu_chart = null;
  54. var traffic_chart = null;
  55. var datetime_format_type = 'time';
  56. function format_time(timestamp, i) {
  57. if (datetime_format_type === 'time') {
  58. return new Date(timestamp).format('HH:MM');
  59. } else {
  60. return new Date(timestamp).format('mm-dd');
  61. }
  62. }
  63. function render_cpu_memory_chart(uuid, granularity) {
  64. var url = '/api/performance/cpu_memory/last_hour/' + uuid;
  65. if (granularity === 'hour') {
  66. url = '/api/performance/cpu_memory/last_hour/' + uuid
  67. } else if (granularity === 'six_hours') {
  68. url = '/api/performance/cpu_memory/last_six_hours/' + uuid
  69. } else if (granularity === 'day') {
  70. url = '/api/performance/cpu_memory/last_day/' + uuid
  71. } else {
  72. url = '/api/performance/cpu_memory/last_seven_days/' + uuid
  73. }
  74. $.ajax({
  75. url : url,
  76. type : 'GET',
  77. contentType: "application/json; charset=utf-8",
  78. dataType: 'json',
  79. error : function() {
  80. alter_danger('获取图表数据失败失败!');
  81. },
  82. success : function(data, textStatus, xhr) {
  83. if (data.data.length > 1) {
  84. if ((data.data[data.data.length - 1]['timestamp'] - data.data[0]['timestamp']) >= 86400) {
  85. datetime_format_type = 'date';
  86. }
  87. }
  88. var option = {
  89. color: ['#3BC0FF'],
  90. title: {
  91. text: 'CPU'
  92. },
  93. legend: {
  94. data:['CPU使用率(%)'],
  95. bottom: 5
  96. },
  97. toolbox: {
  98. feature: {
  99. dataZoom: {
  100. yAxisIndex: 'none'
  101. },
  102. magicType: {type: ['line', 'bar']},
  103. saveAsImage: {show: true}
  104. }
  105. },
  106. tooltip: {
  107. show: true,
  108. trigger: 'axis',
  109. formatter: (function (params, ticket, callback) {
  110. var cpu_load = params[0].data[1];
  111. var seriesName = params[0].seriesName;
  112. var marker = params[0].marker;
  113. var datetime = new Date(params[0].data[0]).format('yyyy-mm-dd HH:MM:ss');
  114. if (cpu_load === null) {
  115. cpu_load = '无数据';
  116. }
  117. return datetime + '<br />' + [marker, seriesName, cpu_load].join(' ')
  118. })
  119. },
  120. xAxis: {
  121. type: 'time',
  122. axisTick: {
  123. show: false
  124. },
  125. axisLine: {
  126. lineStyle: {
  127. opacity: 0.1,
  128. color: '#3d4245'
  129. }
  130. },
  131. splitLine: {
  132. show: false
  133. },
  134. axisLabel: {
  135. formatter: format_time
  136. }
  137. },
  138. yAxis: {
  139. min: 0,
  140. max: 'dataMax',
  141. minInterval: 2,
  142. axisTick: {
  143. show: false
  144. },
  145. axisLine: {
  146. lineStyle: {
  147. opacity: 0,
  148. color: '#8c8f91'
  149. }
  150. },
  151. splitLine: {
  152. show: true,
  153. lineStyle: {
  154. width: 1,
  155. opacity: 0.5
  156. }
  157. }
  158. },
  159. series: [{
  160. name: 'CPU使用率(%)',
  161. type: 'line',
  162. showSymbol: false,
  163. smooth: true,
  164. lineStyle: {
  165. normal: {
  166. width: 1
  167. }
  168. },
  169. data: (function () {
  170. var d = [];
  171. $.each(data.data, function(i, ele) {
  172. d.push([
  173. ele['timestamp'] * 1000,
  174. ele['cpu_load']
  175. ])
  176. });
  177. return d;
  178. })()
  179. }]
  180. };
  181. cpu_chart.setOption(option);
  182. }
  183. });
  184. }
  185. function render_traffic_chart(uuid, granularity) {
  186. var url = '/api/performance/traffic/last_hour/' + uuid;
  187. if (granularity === 'hour') {
  188. url = '/api/performance/traffic/last_hour/' + uuid
  189. } else if (granularity === 'six_hours') {
  190. url = '/api/performance/traffic/last_six_hours/' + uuid
  191. } else if (granularity === 'day') {
  192. url = '/api/performance/traffic/last_day/' + uuid
  193. } else {
  194. url = '/api/performance/traffic/last_seven_days/' + uuid
  195. }
  196. $.ajax({
  197. url : url,
  198. type : 'GET',
  199. contentType: "application/json; charset=utf-8",
  200. dataType: 'json',
  201. error : function() {
  202. alter_danger('获取图表数据失败失败!');
  203. },
  204. success : function(data, textStatus, xhr) {
  205. if (data.data.length > 1) {
  206. if ((data.data[data.data.length - 1]['timestamp'] - data.data[0]['timestamp']) >= 86400) {
  207. datetime_format_type = 'date';
  208. }
  209. }
  210. var option = {
  211. color: ['#3BC0FF', '#e5b715'],
  212. title: {
  213. text: '网络'
  214. },
  215. legend: {
  216. data:['流入(kbps)', '流出(kbps)'],
  217. bottom: 5
  218. },
  219. toolbox: {
  220. feature: {
  221. dataZoom: {
  222. yAxisIndex: 'none'
  223. },
  224. magicType: {type: ['line', 'bar']},
  225. saveAsImage: {show: true}
  226. }
  227. },
  228. tooltip: {
  229. show: true,
  230. trigger: 'axis',
  231. formatter: (function (params, ticket, callback) {
  232. var inflowSeriesName = params[0].seriesName;
  233. var outflowSeriesName = params[1].seriesName;
  234. var inflow = params[0].data[1];
  235. var outflow = params[1].data[1];
  236. var inflowMarker = params[0].marker;
  237. var outflowMarker = params[1].marker;
  238. var datetime = new Date(params[0].data[0]).format('yyyy-mm-dd HH:MM:ss');
  239. if (inflow === null) {
  240. inflow = '无数据';
  241. }
  242. if (outflow === null) {
  243. outflow = '无数据';
  244. }
  245. return datetime + '<br />' + [inflowMarker, inflowSeriesName, inflow].join(' ') +
  246. '<br />' + [outflowMarker, outflowSeriesName, outflow].join(' ')
  247. })
  248. },
  249. xAxis: {
  250. type: 'time',
  251. axisTick: {
  252. show: false
  253. },
  254. axisLine: {
  255. lineStyle: {
  256. opacity: 0.1,
  257. color: '#3d4245'
  258. }
  259. },
  260. splitLine: {
  261. show: false
  262. },
  263. axisLabel: {
  264. formatter: format_time
  265. }
  266. },
  267. yAxis: {
  268. min: 0,
  269. max: 'dataMax',
  270. minInterval: 2,
  271. axisTick: {
  272. show: false
  273. },
  274. axisLine: {
  275. lineStyle: {
  276. opacity: 0,
  277. color: '#8c8f91'
  278. }
  279. },
  280. splitLine: {
  281. show: true,
  282. lineStyle: {
  283. width: 1,
  284. opacity: 0.5
  285. }
  286. }
  287. },
  288. series: [{
  289. name: '流入(kbps)',
  290. type: 'line',
  291. showSymbol: false,
  292. smooth: true,
  293. lineStyle: {
  294. normal: {
  295. width: 1
  296. }
  297. },
  298. data: (function () {
  299. var d = [];
  300. $.each(data.data, function(i, ele) {
  301. d.push([
  302. ele['timestamp'] * 1000,
  303. ele['rx_bytes'] / 1000
  304. ])
  305. });
  306. return d;
  307. })()
  308. },{
  309. name: '流出(kbps)',
  310. type: 'line',
  311. showSymbol: false,
  312. smooth: true,
  313. lineStyle: {
  314. normal: {
  315. width: 1
  316. }
  317. },
  318. data: (function () {
  319. var d = [];
  320. $.each(data.data, function(i, ele) {
  321. d.push([
  322. ele['timestamp'] * 1000,
  323. ele['tx_bytes'] / 1000
  324. ])
  325. });
  326. return d;
  327. })()
  328. }]
  329. };
  330. traffic_chart.setOption(option);
  331. }
  332. });
  333. }
  334. $(document).ready(function() {
  335. $('body').addClass('add-transition');
  336. $('.add-page-transition').on('click', function(){
  337. var transAttr = $(this).attr('data-transition');
  338. $('.add-transition').attr('class', 'add-transition');
  339. $('.add-transition').addClass(transAttr);
  340. });
  341. cpu_chart = echarts.init(document.getElementById('cpu_chart'));
  342. traffic_chart = echarts.init(document.getElementById('traffic_chart'));
  343. render_cpu_memory_chart(uuid, 'six_hours');
  344. render_traffic_chart(uuid, 'six_hours');
  345. });
  346. </script>
  347. <div class="container" style="padding-top: 100px; width: 90%; max-width: 100%;">
  348. <div class="panel">
  349. <div class="panel-body">
  350. <h3 class="title-hero" style="display: inline;">
  351. 虚拟机实例详情
  352. </h3>
  353. <a href="/guests" class="btn btn-xs btn-default add-page-transition" data-transition="pt-page-moveFromLeft-init" style="margin-bottom: 4px; margin-left: 10px;">
  354. <span class="glyph-icon icon-separator" style="transform: rotateY(-180deg);">
  355. <i class="glyph-icon icon-level-up"></i>
  356. </span>
  357. <span class="button-content">
  358. 返回虚拟机列表
  359. </span>
  360. </a>
  361. <div class="row" style="margin-top: 10px;">
  362. <div class="col-xs-4">
  363. <div style="background: #F5f6FA; border: 1px solid #e1e6eb; padding: 10px; font-size: 14px; width: 100%;">
  364. <span>
  365. 实例信息
  366. </span>
  367. </div>
  368. <table class="table table-bordered">
  369. <tbody>
  370. <tr>
  371. <td>
  372. <span class="guest-label">UUID:&nbsp;&nbsp;&nbsp;&nbsp;</span>
  373. <span class="guest-desc">
  374. {{ guest_ret.data.uuid }}
  375. </span>
  376. </td>
  377. </tr>
  378. <tr>
  379. <td>
  380. <span class="guest-label">标识:&nbsp;&nbsp;&nbsp;&nbsp;</span>
  381. <span class="guest-desc">
  382. {{ guest_ret.data.label }}
  383. </span>
  384. </td>
  385. </tr>
  386. <tr>
  387. <td>
  388. <span class="guest-label">名称:&nbsp;&nbsp;&nbsp;&nbsp;</span>
  389. <span class="guest-desc">
  390. {{ guest_ret.data.remark }}
  391. </span>
  392. </td>
  393. </tr>
  394. <tr>
  395. <td>
  396. <span class="guest-label">CPU:&nbsp;&nbsp;&nbsp;&nbsp;</span>
  397. <span class="guest-desc">
  398. {{ guest_ret.data.cpu }} 核
  399. </span>
  400. </td>
  401. </tr>
  402. <tr>
  403. <td>
  404. <span class="guest-label">内存:&nbsp;&nbsp;&nbsp;&nbsp;</span>
  405. <span class="guest-desc">
  406. {{ guest_ret.data.memory }} GB
  407. </span>
  408. </td>
  409. </tr>
  410. <tr>
  411. <td>
  412. <span class="guest-label">操作系统:&nbsp;&nbsp;&nbsp;&nbsp;</span>
  413. <span class="guest-desc">
  414. {{ os_template_ret.data.label }}
  415. </span>&nbsp;&nbsp;&nbsp;&nbsp;
  416. <span class="{{ os_template_ret.data.icon }}"></span>
  417. </td>
  418. </tr>
  419. <tr>
  420. <td>
  421. <span class="guest-label">IP:&nbsp;&nbsp;&nbsp;&nbsp;</span>
  422. <span class="guest-desc">
  423. {{ guest_ret.data.ip }}
  424. </span>
  425. </td>
  426. </tr>
  427. <tr>
  428. <td>
  429. <span class="guest-label">密码:&nbsp;&nbsp;&nbsp;&nbsp;</span>
  430. <span class="guest-desc">
  431. {{ guest_ret.data.password }}
  432. </span>
  433. </td>
  434. </tr>
  435. <tr>
  436. <td>
  437. <span class="guest-label">所在宿主机:&nbsp;&nbsp;&nbsp;&nbsp;</span>
  438. <span class="guest-desc">
  439. {{ guest_ret.data.on_host }}
  440. </span>
  441. </td>
  442. </tr>
  443. <tr>
  444. <td>
  445. <span class="guest-label">创建时间:&nbsp;&nbsp;&nbsp;&nbsp;</span>
  446. <span class="guest-desc">
  447. {{ format_datetime_by_tus(guest_ret.data.create_time) }}
  448. </span>
  449. </td>
  450. </tr>
  451. </tbody>
  452. </table>
  453. </div>
  454. <div class="col-xs-8">
  455. <div id="cpu_chart" style="width: 800px;height:280px;"></div>
  456. <div id="traffic_chart" style="width: 800px;height:280px;"></div>
  457. </div>
  458. </div>
  459. </div>
  460. </div>
  461. </div>
  462. {% endblock body %}