uptime.html 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <div class="standardContainer">
  2. <div class="ui basic segment">
  3. <h2>Uptime Monitor</h2>
  4. <p>Check the online state of proxied targets</p>
  5. </div>
  6. <div class="ui divider"></div>
  7. <div id="utmrender" class="ui basic segment">
  8. <div class="ui basic segment">
  9. <h4 class="ui header">
  10. <i class="red remove icon"></i>
  11. <div class="content">
  12. Uptime Monitoring service is currently unavailable
  13. <div class="sub header">This might be caused by an error in cluster communication within the host servers. Please wait for administrator to resolve the issue.</div>
  14. </div>
  15. </h4>
  16. </div>
  17. </div>
  18. <div align="center">
  19. <button class="ui basic circular green icon button" onclick="reloadUptimeList();"><i class="refresh icon"></i></button>
  20. </div>
  21. </div>
  22. <script>
  23. $('#utmEnable').checkbox({
  24. onChange: function() {
  25. var utmEnable = $('input[name="utmEnable"]').is(":checked");
  26. $.post({
  27. url: '/api/toggle-utm',
  28. data: {utmEnable: utmEnable},
  29. success: function(response) {
  30. console.log(response);
  31. },
  32. error: function(error) {
  33. console.log(error);
  34. }
  35. });
  36. }
  37. });
  38. function initUptimeTable(){
  39. $.get("/api/utm/list", function(data){
  40. let records = data;
  41. renderRecords(records);
  42. })
  43. }
  44. initUptimeTable();
  45. function reloadUptimeList(){
  46. $("#utmrender").html(`<div class="ui segment">
  47. <div class="ui active inverted dimmer" style="z-index: 2;">
  48. <div class="ui text loader">Loading</div>
  49. </div>
  50. <br><br><br><br>
  51. </div>`);
  52. setTimeout(initUptimeTable, 300);
  53. }
  54. //For every 5 minutes
  55. setInterval(function(){
  56. $.get("/api/utm/list", function(data){
  57. console.log("Status Updated");
  58. records = data;
  59. renderRecords(records);
  60. });
  61. }, (300 * 1000));
  62. function renderRecords(records){
  63. $("#utmrender").html("");
  64. for (let [key, value] of Object.entries(records)) {
  65. renderUptimeData(key, value);
  66. }
  67. }
  68. function format_time(s) {
  69. const date = new Date(s * 1e3);
  70. return(date.toLocaleString());
  71. }
  72. function renderUptimeData(key, value){
  73. if (value.length == 0){
  74. return
  75. }
  76. let id = value[0].ID;
  77. let name = value[0].Name;
  78. let url = value[value.length - 1].URL;
  79. let protocol = value[0].Protocol;
  80. //Generate the status dot
  81. let statusDotList = ``;
  82. for(var i = 0; i < (288 - value.length); i++){
  83. //Padding
  84. statusDotList += `<div class="padding statusDot"></div>`
  85. }
  86. let ontimeRate = 0;
  87. for (var i = 0; i < value.length; i++){
  88. //Render status to html
  89. let thisStatus = value[i];
  90. let dotType = "";
  91. if (thisStatus.Online){
  92. if (thisStatus.StatusCode < 200 || thisStatus.StatusCode >= 300){
  93. dotType = "error";
  94. }else{
  95. dotType = "online";
  96. }
  97. ontimeRate++;
  98. }else{
  99. if (thisStatus.StatusCode >= 500 && thisStatus.StatusCode < 600){
  100. //Special type of error, cause by downstream reverse proxy
  101. dotType = "error";
  102. }else if (thisStatus.StatusCode == 401){
  103. //Unauthorized error
  104. dotType = "error";
  105. }else{
  106. dotType = "offline";
  107. }
  108. }
  109. let datetime = format_time(thisStatus.Timestamp);
  110. statusDotList += `<div title="${datetime}" class="${dotType} statusDot"></div>`
  111. }
  112. ontimeRate = ontimeRate / value.length * 100;
  113. let ontimeColor = "#df484a"
  114. if (ontimeRate > 0.8){
  115. ontimeColor = "#3bd671";
  116. }else if(ontimeRate > 0.5) {
  117. ontimeColor = "#f29030";
  118. }
  119. //Check of online status now
  120. let currentOnlineStatus = "Unknown";
  121. let onlineStatusCss = ``;
  122. let reminderEle = ``;
  123. if (value[value.length - 1].Online){
  124. currentOnlineStatus = `<i class="circle icon"></i> Online`;
  125. onlineStatusCss = `color: #3bd671;`;
  126. }else{
  127. if (value[value.length - 1].StatusCode >= 500 && value[value.length - 1].StatusCode < 600){
  128. currentOnlineStatus = `<i class="exclamation circle icon"></i> Misconfigured`;
  129. onlineStatusCss = `color: #f38020;`;
  130. reminderEle = `<small style="${onlineStatusCss}">Downstream proxy server is online with misconfigured settings</small>`;
  131. }else if (value[value.length - 1].StatusCode >= 400 && value[value.length - 1].StatusCode <= 405){
  132. switch(value[value.length - 1].StatusCode){
  133. case 400:
  134. currentOnlineStatus = `<i class="exclamation circle icon"></i> Bad Request`;
  135. break;
  136. case 401:
  137. currentOnlineStatus = `<i class="exclamation circle icon"></i> Unauthorized`;
  138. break;
  139. case 403:
  140. currentOnlineStatus = `<i class="exclamation circle icon"></i> Forbidden`;
  141. break;
  142. case 404:
  143. currentOnlineStatus = `<i class="exclamation circle icon"></i> Not Found`;
  144. break;
  145. case 405:
  146. currentOnlineStatus = `<i class="exclamation circle icon"></i> Method Not Allowed`;
  147. break;
  148. }
  149. onlineStatusCss = `color: #f38020;`;
  150. reminderEle = `<small style="${onlineStatusCss}">Target online but not accessible</small>`;
  151. }else{
  152. currentOnlineStatus = `<i class="circle icon"></i> Offline`;
  153. onlineStatusCss = `color: #df484a;`;
  154. }
  155. }
  156. //Generate the html
  157. $("#utmrender").append(`<div class="ui basic segment statusbar">
  158. <div class="domain">
  159. <div style="position: absolute; top: 0; right: 0.4em;">
  160. <p class="onlineStatus" style="display: inline-block; font-size: 1.2em; padding-right: 0.5em; padding-left: 0.3em; ${onlineStatusCss}">${currentOnlineStatus}</p>
  161. </div>
  162. <div>
  163. <h3 class="ui header" style="margin-bottom: 0.2em;">${name}</h3>
  164. <a href="${url}" target="_blank">${url}</a> | <span style="color: ${ontimeColor};">${(ontimeRate).toFixed(2)}%<span>
  165. </div>
  166. <div class="ui basic label protocol" style="position: absolute; bottom: 0; right: 0.2em; margin-bottom: -0.6em;">
  167. proto: ${protocol}
  168. </div>
  169. </div>
  170. <div class="status" style="marign-top: 1em;">
  171. ${statusDotList}
  172. </div>
  173. ${reminderEle}
  174. <div class="ui divider"></div>
  175. </div>`);
  176. }
  177. </script>