summaryrefslogtreecommitdiffstats
path: root/web/log.js
diff options
context:
space:
mode:
Diffstat (limited to 'web/log.js')
-rw-r--r--web/log.js192
1 files changed, 192 insertions, 0 deletions
diff --git a/web/log.js b/web/log.js
new file mode 100644
index 0000000..36fd553
--- /dev/null
+++ b/web/log.js
@@ -0,0 +1,192 @@
+/* Copyright (c) 2012: Daniel Richman. License: GNU GPL 3 */
+/* Additional features: Priyesh Patel */
+
+(function () {
+
+var dataelem = "#data";
+var pausetoggle = "#pause";
+var scrollelems = ["html", "body"];
+
+var url = "/var/log/compute-tools/container.log";
+var fix_rn = true;
+var load = 10 * 1024; /* 10KB */
+var poll = 1000; /* 1s */
+
+var kill = false;
+var loading = false;
+var pause = false;
+var reverse = true;
+var log_data = "";
+var log_file_size = 0;
+
+/* :-( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt */
+function parseInt2(value) {
+ if(!(/^[0-9]+$/.test(value))) throw "Invalid integer " + value;
+ var v = Number(value);
+ if (isNaN(v)) throw "Invalid integer " + value;
+ return v;
+}
+
+function get_log() {
+ if (kill | loading) return;
+ loading = true;
+
+ var range;
+ var first_load;
+ var must_get_206;
+ if (log_file_size === 0) {
+ /* Get the last 'load' bytes */
+ range = "-" + load.toString();
+ first_load = true;
+ must_get_206 = false;
+ } else {
+ /* Get the (log_file_size - 1)th byte, onwards. */
+ range = (log_file_size - 1).toString() + "-";
+ first_load = false;
+ must_get_206 = log_file_size > 1;
+ }
+
+ /* The "log_file_size - 1" deliberately reloads the last byte, which we already
+ * have. This is to prevent a 416 "Range unsatisfiable" error: a response
+ * of length 1 tells us that the file hasn't changed yet. A 416 shows that
+ * the file has been trucnated */
+
+ $.ajax(url, {
+ dataType: "text",
+ cache: false,
+ headers: {Range: "bytes=" + range},
+ success: function (data, s, xhr) {
+ loading = false;
+
+ var content_size;
+
+ if (xhr.status === 206) {
+ var c_r = xhr.getResponseHeader("Content-Range");
+ if (!c_r)
+ throw "Server did not respond with a Content-Range";
+
+ log_file_size = parseInt2(c_r.split("/")[1]);
+ content_size = parseInt2(xhr.getResponseHeader("Content-Length"));
+ } else if (xhr.status === 200) {
+ if (must_get_206)
+ throw "Expected 206 Partial Content";
+
+ content_size = log_file_size =
+ parseInt2(xhr.getResponseHeader("Content-Length"));
+ } else {
+ throw "Unexpected status " + xhr.status;
+ }
+
+ if (first_load && data.length > load)
+ throw "Server's response was too long";
+
+ var added = false;
+
+ if (first_load) {
+ /* Clip leading part-line if not the whole file */
+ if (content_size < log_file_size) {
+ var start = data.indexOf("\n");
+ log_data = data.substring(start + 1);
+ } else {
+ log_data = data;
+ }
+
+ added = true;
+ } else {
+ /* Drop the first byte (see above) */
+ log_data += data.substring(1);
+
+ if (log_data.length > load) {
+ var start = log_data.indexOf("\n", log_data.length - load);
+ log_data = log_data.substring(start + 1);
+ }
+
+ if (data.length > 1)
+ added = true;
+ }
+
+ if (added)
+ show_log(added);
+ setTimeout(get_log, poll);
+ },
+ error: function (xhr, s, t) {
+ loading = false;
+
+ if (xhr.status === 416 || xhr.status == 404) {
+ /* 416: Requested range not satisfiable: log was truncated. */
+ /* 404: Retry soon, I guess */
+
+ log_file_size = 0;
+ log_data = "";
+ show_log();
+
+ setTimeout(get_log, poll);
+ } else {
+ throw "Unknown AJAX Error (status " + xhr.status + ")";
+ }
+ }
+ });
+}
+
+function scroll(where) {
+ for (var i = 0; i < scrollelems.length; i++) {
+ var s = $(scrollelems[i]);
+ if (where === -1)
+ s.scrollTop(s.height());
+ else
+ s.scrollTop(where);
+ }
+}
+
+function show_log() {
+ if (pause) return;
+
+ var t = log_data;
+
+ if (reverse) {
+ var t_a = t.split(/\n/g);
+ t_a.reverse();
+ if (t_a[0] == "")
+ t_a.shift();
+ t = t_a.join("\n");
+ }
+
+ if (fix_rn)
+ t = t.replace(/\n/g, "\r\n");
+
+ $(dataelem).text(t);
+ if (!reverse)
+ scroll(-1);
+}
+
+function error(what) {
+ kill = true;
+
+ $(dataelem).text("An error occured :-(.\r\n" +
+ "Reloading may help; no promises.\r\n" +
+ what);
+ scroll(0);
+
+ return false;
+}
+
+$(document).ready(function () {
+ window.onerror = error;
+
+ /* If URL is /logtail/?noreverse display in chronological order */
+ var hash = location.search.replace(/^\?/, "");
+ if (hash == "noreverse")
+ reverse = false;
+
+ /* Add pause toggle */
+ $(pausetoggle).click(function (e) {
+ pause = !pause;
+ $(pausetoggle).text(pause ? "Unpause" : "Pause");
+ show_log();
+ e.preventDefault();
+ });
+
+ get_log();
+});
+
+})();