status.html 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <!--
  4. $Id$
  5. (c) 2011 Jerome Loyet
  6. The PHP License, version 3.01
  7. This is sample real-time status page for FPM. You can change it to better feet your needs.
  8. -->
  9. <head>
  10. <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  11. <style type="text/css">
  12. body {background-color: #ffffff; color: #000000;}
  13. body, td, th, h1, h2 {font-family: sans-serif;}
  14. pre {margin: 0px; font-family: monospace;}
  15. a:link {color: #000099; text-decoration: none; background-color: #ffffff;}
  16. a:hover {text-decoration: underline;}
  17. table {border-collapse: collapse;}
  18. .center {text-align: center;}
  19. .center table { margin-left: auto; margin-right: auto; text-align: left;}
  20. .center th { text-align: center !important; }
  21. td, th { border: 1px solid #000000; font-size: 75%; vertical-align: baseline;}
  22. h1 {font-size: 150%;}
  23. h2 {font-size: 125%;}
  24. .p {text-align: left;}
  25. .e {background-color: #ccccff; font-weight: bold; color: #000000;}
  26. .h {background-color: #9999cc; font-weight: bold; color: #000000;}
  27. .v {background-color: #cccccc; color: #000000;}
  28. .w {background-color: #ccccff; color: #000000;}
  29. .h th {
  30. cursor: pointer;
  31. }
  32. img {float: right; border: 0px;}
  33. hr {width: 600px; background-color: #cccccc; border: 0px; height: 1px; color: #000000;}
  34. </style>
  35. <title>PHP-FPM status page</title>
  36. <meta name="ROBOTS" content="NOINDEX,NOFOLLOW,NOARCHIVE" /></head>
  37. <body>
  38. <div class="center">
  39. <table border="0" cellpadding="3" width="95%">
  40. <tr class="h">
  41. <td>
  42. <a href="http://www.php.net/"><img border="0" src="https://static.php.net/www.php.net/images/php.gif" alt="PHP Logo" /></a><h1 class="p">PHP-FPM real-time status page</h1>
  43. </td>
  44. </tr>
  45. </table>
  46. <br />
  47. <table border="0" cellpadding="3" width="95%">
  48. <tr><td class="e">Status URL</td><td class="v"><input type="text" id="url" size="45" /></td></tr>
  49. <tr><td class="e">Ajax status</td><td class="v" id="status"></td></tr>
  50. <tr><td class="e">Refresh Rate</td><td class="v"><input type="text" id="rate" value="1" /></td></tr>
  51. <tr>
  52. <td class="e">Actions</td>
  53. <td class="v">
  54. <button onclick="javascript:refresh();">Manual Refresh</button>
  55. <button id="play" onclick="javascript:playpause();">Play</button>
  56. </td>
  57. </tr>
  58. </table>
  59. <h1>Pool Status</h1>
  60. <table border="0" cellpadding="3" width="95%" id="short">
  61. <tr style="display: none;"><td>&nbsp;</td></tr>
  62. </table>
  63. <h1>Active Processes status</h1>
  64. <table border="0" cellpadding="3" width="95%" id="active">
  65. <tr class="h"><th>PID&darr;</th><th>Start Time</th><th>Start Since</th><th>Requests Served</th><th>Request Duration</th><th>Request method</th><th>Request URI</th><th>Content Length</th><th>User</th><th>Script</th></tr>
  66. </table>
  67. <h1>Idle Processes status</h1>
  68. <table border="0" cellpadding="3" width="95%" id="idle">
  69. <tr class="h"><th>PID&darr;</th><th>Start Time</th><th>Start Since</th><th>Requests Served</th><th>Request Duration</th><th>Request method</th><th>Request URI</th><th>Content Length</th><th>User</th><th>Script</th><th>Last Request %CPU</th><th>Last Request Memory</th></tr>
  70. </table>
  71. </div>
  72. <p>
  73. <a href="http://validator.w3.org/check?uri=referer">
  74. <img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0 Transitional" height="31" width="88" />
  75. </a>
  76. </p>
  77. <script type="text/javascript">
  78. <!--
  79. var xhr_object = null;
  80. var doc_url = document.getElementById("url");
  81. var doc_rate = document.getElementById("rate");
  82. var doc_status = document.getElementById("status");
  83. var doc_play = document.getElementById("play");
  84. var doc_short = document.getElementById("short");
  85. var doc_active = document.getElementById("active");
  86. var doc_idle = document.getElementById("idle");
  87. var rate = 0;
  88. var play=0;
  89. var delay = 1000;
  90. var order_active_index = 0;
  91. var order_active_reverse = 0;
  92. var order_idle_index = 0;
  93. var order_idle_reverse = 0;
  94. var sort_index;
  95. var sort_order;
  96. doc_url.value = location.protocol + '//' + location.host + "/status?json&full";
  97. ths = document.getElementsByTagName("th");
  98. for (var i=0; i<ths.length; i++) {
  99. var th = ths[i];
  100. if (th.parentNode.className == "h") {
  101. th.onclick = function() { order(this); return false; };
  102. }
  103. }
  104. xhr_object = create_ajax();
  105. function create_ajax() {
  106. if (window.XMLHttpRequest) {
  107. return new XMLHttpRequest();
  108. }
  109. var names = [
  110. "Msxml2.XMLHTTP.6.0",
  111. "Msxml2.XMLHTTP.3.0",
  112. "Msxml2.XMLHTTP",
  113. "Microsoft.XMLHTTP"
  114. ];
  115. for(var i in names)
  116. {
  117. try {
  118. return new ActiveXObject(names[i]);
  119. } catch(e){}
  120. }
  121. alert("Browser not compatible ...");
  122. }
  123. function order(cell) {
  124. var table;
  125. if (cell.constructor != HTMLTableCellElement && cell.constructor != HTMLTableHeaderCellElement) {
  126. return;
  127. }
  128. table = cell.parentNode.parentNode.parentNode;
  129. if (table == doc_active) {
  130. if (order_active_index == cell.cellIndex) {
  131. if (order_active_reverse == 0) {
  132. cell.innerHTML = cell.innerHTML.replace(/.$/, "&uarr;");
  133. order_active_reverse = 1;
  134. } else {
  135. cell.innerHTML = cell.innerHTML.replace(/.$/, "&darr;");
  136. order_active_reverse = 0;
  137. }
  138. } else {
  139. var c = doc_active.rows[0].cells[order_active_index];
  140. c.innerHTML = c.innerHTML.replace(/.$/, "");
  141. cell.innerHTML = cell.innerHTML.replace(/$/, order_active_reverse == 0 ? "&darr;" : "&uarr;");
  142. order_active_index = cell.cellIndex;
  143. }
  144. reorder(table, order_active_index, order_active_reverse);
  145. return;
  146. }
  147. if (table == doc_idle) {
  148. if (order_idle_index == cell.cellIndex) {
  149. if (order_idle_reverse == 0) {
  150. cell.innerHTML = cell.innerHTML.replace(/.$/, "&uarr;");
  151. order_idle_reverse = 1;
  152. } else {
  153. cell.innerHTML = cell.innerHTML.replace(/.$/, "&darr;");
  154. order_idle_reverse = 0;
  155. }
  156. } else {
  157. var c = doc_idle.rows[0].cells[order_idle_index];
  158. c.innerHTML = c.innerHTML.replace(/.$/, "");
  159. cell.innerHTML = cell.innerHTML.replace(/$/, order_idle_reverse == 0 ? "&darr;" : "&uarr;");
  160. order_idle_index = cell.cellIndex;
  161. }
  162. reorder(table, order_idle_index, order_idle_reverse);
  163. return;
  164. }
  165. }
  166. function reorder(table, index, order) {
  167. var rows = [];
  168. while (table.rows.length > 1) {
  169. rows.push(table.rows[1]);
  170. table.deleteRow(1);
  171. }
  172. sort_index = index;
  173. sort_order = order;
  174. rows.sort(sort_table);
  175. for (var i in rows) {
  176. table.appendChild(rows[i]);
  177. }
  178. var odd = 1;
  179. for (var i=1; i<table.rows.length; i++) {
  180. table.rows[i].className = odd++ % 2 == 0 ? "v" : "w";
  181. }
  182. return;
  183. }
  184. function sort_table(a, b) {
  185. if (a.cells[0].tagName == "TH") return -1;
  186. if (b.cells[0].tagName == "TH") return 1;
  187. if (a.cells[sort_index].__search_t == 0) { /* integer */
  188. if (!sort_order) return a.cells[sort_index].__search_v - b.cells[sort_index].__search_v;
  189. return b.cells[sort_index].__search_v - a.cells[sort_index].__search_v;;
  190. }
  191. /* string */
  192. if (!sort_order) return a.cells[sort_index].__search_v.localeCompare(b.cells[sort_index].__search_v);
  193. else return b.cells[sort_index].__search_v.localeCompare(a.cells[sort_index].__search_v);
  194. }
  195. function playpause() {
  196. rate = 0;
  197. if (play) {
  198. play = 0;
  199. doc_play.innerHTML = "Play";
  200. doc_rate.disabled = false;
  201. } else {
  202. delay = parseInt(doc_rate.value);
  203. if (!delay || delay < 1) {
  204. doc_status.innerHTML = "Not valid 'refresh' value";
  205. return;
  206. }
  207. play = 1;
  208. doc_rate.disabled = true;
  209. doc_play.innerHTML = "Pause";
  210. setTimeout("callback()", delay * 1000);
  211. }
  212. }
  213. function refresh() {
  214. if (xhr_object == null) return;
  215. if (xhr_object.readyState > 0 && xhr_object.readyState < 4) {
  216. return; /* request is running */
  217. }
  218. xhr_object.open("GET", doc_url.value, true);
  219. xhr_object.onreadystatechange = function() {
  220. switch(xhr_object.readyState) {
  221. case 0:
  222. doc_status.innerHTML = "uninitialized";
  223. break;
  224. case 1:
  225. doc_status.innerHTML = "loading ...";
  226. break;
  227. case 2:
  228. doc_status.innerHTML = "loaded";
  229. break;
  230. case 3:
  231. doc_status.innerHTML = "interactive";
  232. break;
  233. case 4:
  234. doc_status.innerHTML = "complete";
  235. if (xhr_object.status == 200) {
  236. fpm_status(xhr_object.responseText);
  237. } else {
  238. doc_status.innerHTML = "Error " + xhr_object.status;
  239. }
  240. break;
  241. }
  242. }
  243. xhr_object.send();
  244. }
  245. function callback() {
  246. if (!play) return;
  247. refresh();
  248. setTimeout("callback()", delay * 1000);
  249. }
  250. function fpm_status(txt) {
  251. var json = null;
  252. while (doc_short.rows.length > 0) {
  253. doc_short.deleteRow(0);
  254. }
  255. while (doc_active.rows.length > 1) {
  256. doc_active.deleteRow(1);
  257. }
  258. while (doc_idle.rows.length > 1) {
  259. doc_idle.deleteRow(1);
  260. }
  261. try {
  262. json = JSON.parse(txt);
  263. } catch (e) {
  264. doc_status.innerHTML = "Error while parsing json: '" + e + "': <br /><pre>" + txt + "</pre>";
  265. return;
  266. }
  267. for (var key in json) {
  268. if (key == "processes") continue;
  269. if (key == "state") continue;
  270. var row = doc_short.insertRow(doc_short.rows.length);
  271. var value = json[key];
  272. if (key == "start time") {
  273. value = new Date(value * 1000).toLocaleString();
  274. }
  275. if (key == "start since") {
  276. value = time_s(value);
  277. }
  278. var cell = row.insertCell(row.cells.length);
  279. cell.className = "e";
  280. cell.innerHTML = key;
  281. cell = row.insertCell(row.cells.length);
  282. cell.className = "v";
  283. cell.innerHTML = value;
  284. }
  285. if (json.processes) {
  286. process_full(json.processes, doc_active, "Idle", 0, 0);
  287. reorder(doc_active, order_active_index, order_active_reverse);
  288. process_full(json.processes, doc_idle, "Idle", 1, 1);
  289. reorder(doc_idle, order_idle_index, order_idle_reverse);
  290. }
  291. }
  292. function process_full(processes, table, state, equal, cpumem) {
  293. var odd = 1;
  294. for (var i in processes) {
  295. var proc = processes[i];
  296. if ((equal && proc.state == state) || (!equal && proc.state != state)) {
  297. var c = odd++ % 2 == 0 ? "v" : "w";
  298. var row = table.insertRow(-1);
  299. row.className = c;
  300. row.insertCell(-1).innerHTML = proc.pid;
  301. row.cells[row.cells.length - 1].__search_v = proc.pid;
  302. row.cells[row.cells.length - 1].__search_t = 0;
  303. row.insertCell(-1).innerHTML = date(proc['start time'] * 1000);;
  304. row.cells[row.cells.length - 1].__search_v = proc['start time'];
  305. row.cells[row.cells.length - 1].__search_t = 0;
  306. row.insertCell(-1).innerHTML = time_s(proc['start since']);
  307. row.cells[row.cells.length - 1].__search_v = proc['start since'];
  308. row.cells[row.cells.length - 1].__search_t = 0;
  309. row.insertCell(-1).innerHTML = proc.requests;
  310. row.cells[row.cells.length - 1].__search_v = proc.requests;
  311. row.cells[row.cells.length - 1].__search_t = 0;
  312. row.insertCell(-1).innerHTML = time_u(proc['request duration']);
  313. row.cells[row.cells.length - 1].__search_v = proc['request duration'];
  314. row.cells[row.cells.length - 1].__search_t = 0;
  315. row.insertCell(-1).innerHTML = proc['request method'];
  316. row.cells[row.cells.length - 1].__search_v = proc['request method'];
  317. row.cells[row.cells.length - 1].__search_t = 1;
  318. row.insertCell(-1).innerHTML = proc['request uri'];
  319. row.cells[row.cells.length - 1].__search_v = proc['request uri'];
  320. row.cells[row.cells.length - 1].__search_t = 1;
  321. row.insertCell(-1).innerHTML = proc['content length'];
  322. row.cells[row.cells.length - 1].__search_v = proc['content length'];
  323. row.cells[row.cells.length - 1].__search_t = 0;
  324. row.insertCell(-1).innerHTML = proc.user;
  325. row.cells[row.cells.length - 1].__search_v = proc.user;
  326. row.cells[row.cells.length - 1].__search_t = 1;
  327. row.insertCell(-1).innerHTML = proc.script;
  328. row.cells[row.cells.length - 1].__search_v = proc.script;
  329. row.cells[row.cells.length - 1].__search_t = 1;
  330. if (cpumem) {
  331. row.insertCell(-1).innerHTML = cpu(proc['last request cpu']);
  332. row.cells[row.cells.length - 1].__search_v = proc['last request cpu'];
  333. row.cells[row.cells.length - 1].__search_t = 0;
  334. row.insertCell(-1).innerHTML = memory(proc['last request memory']);
  335. row.cells[row.cells.length - 1].__search_v = proc['last request memory'];
  336. row.cells[row.cells.length - 1].__search_t = 0;
  337. }
  338. }
  339. }
  340. }
  341. function date(d) {
  342. var t = new Date(d);
  343. var r = "";
  344. r += (t.getDate() < 10 ? '0' : '') + t.getDate();
  345. r += '/';
  346. r += (t.getMonth() + 1 < 10 ? '0' : '') + (t.getMonth() + 1);
  347. r += '/';
  348. r += t.getFullYear();
  349. r += ' ';
  350. r += (t.getHours() < 10 ? '0' : '') + t.getHours();
  351. r += ':';
  352. r += (t.getMinutes() < 10 ? '0' : '') + t.getMinutes();
  353. r += ':';
  354. r += (t.getSeconds() < 10 ? '0' : '') + t.getSeconds();
  355. return r;
  356. }
  357. function cpu(c) {
  358. if (c == 0) return 0;
  359. return c + "%";
  360. }
  361. function memory(mem) {
  362. if (mem == 0) return 0;
  363. if (mem < 1024) {
  364. return mem + "B";
  365. }
  366. if (mem < 1024 * 1024) {
  367. return mem/1024 + "KB";
  368. }
  369. if (mem < 1024*1024*1024) {
  370. return mem/1024/1024 + "MB";
  371. }
  372. }
  373. function time_s(t) {
  374. var r = "";
  375. if (t < 60) {
  376. return t + 's';
  377. }
  378. r = (t % 60) + 's';
  379. t = Math.floor(t / 60);
  380. if (t < 60) {
  381. return t + 'm ' + r;
  382. }
  383. r = (t % 60) + 'm ' + r;
  384. t = Math.floor(t/60);
  385. if (t < 24) {
  386. return t + 'h ' + r;
  387. }
  388. return Math.floor(t/24) + 'd ' + (t % 24) + 'h ' + t;
  389. }
  390. function time_u(t) {
  391. var r = "";
  392. if (t < 1000) {
  393. return t + '&micro;s'
  394. }
  395. r = (t % 1000) + '&micro;s';
  396. t = Math.floor(t / 1000);
  397. if (t < 1000) {
  398. return t + 'ms ' + r;
  399. }
  400. return time_s(Math.floor(t/1000)) + ' ' + (t%1000) + 'ms ' + r;
  401. }
  402. -->
  403. </script>
  404. </body>
  405. </html>