uptime.html 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  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. var uptime5xxErrorMessage = {
  24. "500": "Internal Server Error",
  25. "501": "Not Implemented",
  26. "502": "Bad Gateway",
  27. "503": "Service Unavailable",
  28. "504": "Gateway Timeout",
  29. "505": "HTTP Version Not Supported",
  30. "506": "Variant Also Negotiates",
  31. "507": "Insufficient Storage",
  32. "508": "Loop Detected",
  33. "510": "Not Extended",
  34. "511": "Network Authentication Required",
  35. "520": "Web Server Returned an Unknown Error (Cloudflare)",
  36. "521": "Web Server is Down (Cloudflare)",
  37. "522": "Connection Timed Out (Cloudflare)",
  38. "523": "Origin is Unreachable (Cloudflare)",
  39. "524": "A Timeout Occurred (Cloudflare)",
  40. "525": "SSL Handshake Failed (Cloudflare)",
  41. "526": "Invalid SSL Certificate (Cloudflare)",
  42. "527": "Railgun Error (Cloudflare)",
  43. "530": "Site is Frozen (Pantheon)"
  44. }
  45. $('#utmEnable').checkbox({
  46. onChange: function() {
  47. var utmEnable = $('input[name="utmEnable"]').is(":checked");
  48. $.post({
  49. url: '/api/toggle-utm',
  50. data: {utmEnable: utmEnable},
  51. success: function(response) {
  52. console.log(response);
  53. },
  54. error: function(error) {
  55. console.log(error);
  56. }
  57. });
  58. }
  59. });
  60. function initUptimeTable(){
  61. $.get("/api/utm/list", function(data){
  62. let records = data;
  63. renderRecords(records);
  64. })
  65. }
  66. initUptimeTable();
  67. function reloadUptimeList(){
  68. $("#utmrender").html(`<div class="ui segment">
  69. <div class="ui active inverted dimmer" style="z-index: 2;">
  70. <div class="ui text loader">Loading</div>
  71. </div>
  72. <br><br><br><br>
  73. </div>`);
  74. setTimeout(initUptimeTable, 300);
  75. }
  76. //For every 5 minutes
  77. setInterval(function(){
  78. $.get("/api/utm/list", function(data){
  79. console.log("Status Updated");
  80. records = data;
  81. renderRecords(records);
  82. });
  83. }, (300 * 1000));
  84. function renderRecords(records){
  85. $("#utmrender").html("");
  86. for (let [key, value] of Object.entries(records)) {
  87. renderUptimeData(key, value);
  88. }
  89. }
  90. function format_time(s) {
  91. const date = new Date(s * 1e3);
  92. return(date.toLocaleString());
  93. }
  94. function resolveUptime5xxErrorMessage(errorCode){
  95. if (uptime5xxErrorMessage[errorCode] != undefined){
  96. return uptime5xxErrorMessage[errorCode]
  97. }else{
  98. return "Unknown Error";
  99. }
  100. }
  101. function renderUptimeData(key, value){
  102. if (value.length == 0){
  103. return
  104. }
  105. let id = value[0].ID;
  106. let name = value[0].Name;
  107. let url = value[value.length - 1].URL;
  108. let protocol = value[0].Protocol;
  109. //Generate the status dot
  110. let statusDotList = ``;
  111. for(var i = 0; i < (288 - value.length); i++){
  112. //Padding
  113. statusDotList += `<div class="padding statusDot"></div>`
  114. }
  115. let ontimeRate = 0;
  116. for (var i = 0; i < value.length; i++){
  117. //Render status to html
  118. let thisStatus = value[i];
  119. let dotType = "";
  120. let statusCode = thisStatus.StatusCode;
  121. if (!thisStatus.Online && statusCode == 0){
  122. dotType = "offline";
  123. }else if (statusCode < 200){
  124. //1xx
  125. dotType = "error";
  126. ontimeRate++;
  127. }else if (statusCode < 300){
  128. //2xx
  129. dotType = "online";
  130. ontimeRate++;
  131. }else if (statusCode < 400){
  132. //3xx
  133. dotType = "online";
  134. ontimeRate++;
  135. }else if (statusCode < 500){
  136. //4xx
  137. dotType = "error";
  138. ontimeRate++;
  139. }else if (statusCode < 600){
  140. //5xx
  141. dotType = "error";
  142. }else {
  143. dotType = "offline";
  144. }
  145. let datetime = format_time(thisStatus.Timestamp);
  146. statusDotList += `<div title="${datetime}" class="${dotType} statusDot"></div>`
  147. }
  148. ontimeRate = ontimeRate / value.length * 100;
  149. let ontimeColor = "#df484a"
  150. if (ontimeRate > 0.8){
  151. ontimeColor = "#3bd671";
  152. }else if(ontimeRate > 0.5) {
  153. ontimeColor = "#f29030";
  154. }
  155. //Check of online status now
  156. let currentOnlineStatus = "Unknown";
  157. let onlineStatusCss = ``;
  158. let reminderEle = ``;
  159. if (value[value.length - 1].Online){
  160. currentOnlineStatus = `<i class="circle icon"></i> Online`;
  161. onlineStatusCss = `color: #3bd671;`;
  162. }else{
  163. if (value[value.length - 1].StatusCode >= 500 && value[value.length - 1].StatusCode < 600){
  164. var latestStatusCode = value[value.length - 1].StatusCode
  165. currentOnlineStatus = `<i class="exclamation circle icon"></i>${latestStatusCode} - ${resolveUptime5xxErrorMessage(latestStatusCode)}`;
  166. onlineStatusCss = `color: #f38020;`;
  167. reminderEle = `<small style="${onlineStatusCss}">Downstream proxy server is responsive but returning server error</small>`;
  168. }else if (value[value.length - 1].StatusCode >= 400 && value[value.length - 1].StatusCode <= 405){
  169. let latestStatusCode = value[value.length - 1].StatusCode;
  170. switch(latestStatusCode){
  171. case 400:
  172. currentOnlineStatus = `<i class="exclamation circle icon"></i> Bad Request`;
  173. break;
  174. case 401:
  175. currentOnlineStatus = `<i class="exclamation circle icon"></i> Unauthorized`;
  176. break;
  177. case 403:
  178. currentOnlineStatus = `<i class="exclamation circle icon"></i> Forbidden`;
  179. break;
  180. case 404:
  181. currentOnlineStatus = `<i class="exclamation circle icon"></i> Not Found`;
  182. break;
  183. case 405:
  184. currentOnlineStatus = `<i class="exclamation circle icon"></i> Method Not Allowed`;
  185. break;
  186. default:
  187. currentOnlineStatus = `<i class="exclamation circle icon"></i> Status Code: ${latestStatusCode}`;
  188. break;
  189. }
  190. onlineStatusCss = `color: #f38020;`;
  191. reminderEle = `<small style="${onlineStatusCss}">Target online but not accessible</small>`;
  192. }else{
  193. currentOnlineStatus = `<i class="circle icon"></i> Offline`;
  194. onlineStatusCss = `color: #df484a;`;
  195. }
  196. }
  197. //Generate the html
  198. $("#utmrender").append(`<div class="ui basic segment statusbar">
  199. <div class="domain">
  200. <div style="position: absolute; top: 0; right: 0.4em;">
  201. <p class="onlineStatus" style="display: inline-block; font-size: 1.2em; padding-right: 0.5em; padding-left: 0.3em; ${onlineStatusCss}">${currentOnlineStatus}</p>
  202. </div>
  203. <div>
  204. <h3 class="ui header" style="margin-bottom: 0.2em;">${name}</h3>
  205. <a href="${url}" target="_blank">${url}</a> | <span style="color: ${ontimeColor};">${(ontimeRate).toFixed(2)}%<span>
  206. </div>
  207. <div class="ui basic label protocol" style="position: absolute; bottom: 0; right: 0.2em; margin-bottom: -0.6em;">
  208. proto: ${protocol}
  209. </div>
  210. </div>
  211. <div class="status" style="marign-top: 1em;">
  212. ${statusDotList}
  213. </div>
  214. ${reminderEle}
  215. <div class="ui divider"></div>
  216. </div>`);
  217. }
  218. </script>