From 5d4e48f0f9fcd75f590649d86988f22589c7bf08 Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Sat, 20 Nov 2021 11:57:25 -0800 Subject: [PATCH] Improve logs (#89) --- assets/js/logs.js | 69 ++++++++++++++++++++++++ assets/js/routes.js | 9 +++- assets/plugins/js-yaml/js-yaml.min.js | 1 - cmd/distribyted/main.go | 12 ++--- config/config.go | 9 +++- config/handler.go | 11 +--- config/model.go | 10 ++++ go.mod | 1 + go.sum | 2 + http/api.go | 49 +++++++++++++++++ http/http.go | 4 +- http/web.go | 4 ++ log/log.go | 40 ++++++++++++-- templates/config_template.yaml | 38 +++++++++++-- templates/logs.html | 77 +++++++++++++++++++++++++++ templates/navbar.html | 10 ++++ templates/routes.html | 10 +++- torrent/service.go | 20 +++++-- 18 files changed, 343 insertions(+), 33 deletions(-) create mode 100644 assets/js/logs.js delete mode 100644 assets/plugins/js-yaml/js-yaml.min.js create mode 100644 templates/logs.html diff --git a/assets/js/logs.js b/assets/js/logs.js new file mode 100644 index 0000000..e50912f --- /dev/null +++ b/assets/js/logs.js @@ -0,0 +1,69 @@ +Distribyted.logs = { + loadView: function () { + fetch("/api/log") + .then(response => { + if (response.ok) { + return response.body.getReader(); + } else { + response.json().then(json => { + Distribyted.message.error('Error getting logs from server. Error: ' + json.error); + }).catch(error => { + Distribyted.message.error('Error getting logs from server. Error: ' + error); + }) + } + }) + .then(reader => { + var decoder = new TextDecoder() + var lastString = '' + reader.read().then(function processText({ done, value }) { + if (done) { + return; + } + + const string = `${lastString}${decoder.decode(value)}` + const lines = string.split(/\r\n|[\r\n]/g) + this.lastString = lines.pop() || '' + + lines.forEach(element => { + try { + var json = JSON.parse(element) + var properties = "" + for (let [key, value] of Object.entries(json)) { + if (key == "level" || key == "component" || key == "message" || key == "time") { + continue + } + + properties += `${key}=${value} ` + } + + var tableClass = "table-primary" + switch (json.level) { + case "info": + tableClass = "" + break; + case "error": + tableClass = "table-danger" + break; + case "warn": + tableClass = "table-warning" + break; + case "debug": + tableClass = "table-info" + break; + default: + break; + } + template = `${new Date(json.time*1000).toLocaleString()}${json.level}${json.component}${json.message}${properties}`; + document.getElementById("log_table").innerHTML += template; + } catch (err) { + // server can send some corrupted json line + console.log(err); + } + }); + + + return reader.read().then(processText); + }).catch(err => console.log(err)); + }).catch(err => console.log(err)); + } +} diff --git a/assets/js/routes.js b/assets/js/routes.js index 63f6306..2a24c13 100644 --- a/assets/js/routes.js +++ b/assets/js/routes.js @@ -129,6 +129,7 @@ Distribyted.routes = { .then(function (response) { if (response.ok) { Distribyted.message.info('Torrent deleted.') + Distribyted.routes.loadView(); } else { response.json().then(json => { Distribyted.message.error('Error deletting torrent. Response: ' + json.error) @@ -159,7 +160,8 @@ $("#new-magnet").submit(function (event) { let url = '/api/routes/' + route + '/torrent' let body = JSON.stringify({ magnet: magnet }) - console.log("LOG", url, body) + document.getElementById("submit_magnet_loading").style = "display:block" + fetch(url, { method: 'POST', body: body @@ -167,6 +169,7 @@ $("#new-magnet").submit(function (event) { .then(function (response) { if (response.ok) { Distribyted.message.info('New magnet added.') + Distribyted.routes.loadView(); } else { response.json().then(json => { Distribyted.message.error('Error adding new magnet. Response: ' + json.error) @@ -176,6 +179,8 @@ $("#new-magnet").submit(function (event) { } }) .catch(function (error) { - Distribyted.message.error('Error deletting torrent: ' + error.message) + Distribyted.message.error('Error adding torrent: ' + error.message) + }).then(function () { + document.getElementById("submit_magnet_loading").style = "display:none" }); }); \ No newline at end of file diff --git a/assets/plugins/js-yaml/js-yaml.min.js b/assets/plugins/js-yaml/js-yaml.min.js deleted file mode 100644 index f72401e..0000000 --- a/assets/plugins/js-yaml/js-yaml.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).jsyaml=e()}(function(){return function o(a,s,c){function u(t,e){if(!s[t]){if(!a[t]){var n="function"==typeof require&&require;if(!e&&n)return n(t,!0);if(l)return l(t,!0);var i=new Error("Cannot find module '"+t+"'");throw i.code="MODULE_NOT_FOUND",i}var r=s[t]={exports:{}};a[t][0].call(r.exports,function(e){return u(a[t][1][e]||e)},r,r.exports,o,a,s,c)}return s[t].exports}for(var l="function"==typeof require&&require,e=0;e=i.flowLevel;switch(V(r,n,i.indent,t,function(e){return function(e,t){for(var n=0,i=e.implicitTypes.length;n"+z(r,i.indent)+J(U(function(t,n){var e,i,r=/(\n+)([^\n]*)/g,o=function(){var e=-1!==(e=t.indexOf("\n"))?e:t.length;return r.lastIndex=e,Q(t.slice(0,e),n)}(),a="\n"===t[0]||" "===t[0];for(;i=r.exec(t);){var s=i[1],c=i[2];e=" "===c[0],o+=s+(a||e||""===c?"":"\n")+Q(c,n),a=e}return o}(r,t),e));case G:return'"'+function(e){for(var t,n,i,r="",o=0;ot&&o tag resolver accepts not "'+o+'" style');i=r.represent[o](t,o)}e.dump=i}return 1}}function ee(e,t,n,i,r,o){e.tag=null,e.dump=n,X(e,n,!1)||X(e,n,!0);var a=p.call(e.dump);i=i&&(e.flowLevel<0||e.flowLevel>t);var s,c,u="[object Object]"===a||"[object Array]"===a;if(u&&(c=-1!==(s=e.duplicates.indexOf(n))),(null!==e.tag&&"?"!==e.tag||c||2!==e.indent&&0 "+e.dump)}return 1}function te(e,t){var n,i,r=[],o=[];for(!function e(t,n,i){var r,o,a;if(null!==t&&"object"==typeof t)if(-1!==(o=n.indexOf(t)))-1===i.indexOf(o)&&i.push(o);else if(n.push(t),Array.isArray(t))for(o=0,a=t.length;o>10),56320+(s-65536&1023)),e.position++}else N(e,"unknown escape sequence");n=i=e.position}else O(p)?(L(e,n,i,!0),B(e,Y(e,!1,t)),n=i=e.position):e.position===e.lineStart&&R(e)?N(e,"unexpected end of the document within a double quoted scalar"):(e.position++,i=e.position)}N(e,"unexpected end of the stream within a double quoted scalar")}}function W(e,t){var n,i,r=e.tag,o=e.anchor,a=[],s=!1;for(null!==e.anchor&&(e.anchorMap[e.anchor]=a),i=e.input.charCodeAt(e.position);0!==i&&45===i&&F(e.input.charCodeAt(e.position+1));)if(s=!0,e.position++,Y(e,!0,-1)&&e.lineIndent<=t)a.push(null),i=e.input.charCodeAt(e.position);else if(n=e.line,K(e,t,A,!1,!0),a.push(e.result),Y(e,!0,-1),i=e.input.charCodeAt(e.position),(e.line===n||e.lineIndent>t)&&0!==i)N(e,"bad indentation of a sequence entry");else if(e.lineIndentt?d=1:e.lineIndent===t?d=0:e.lineIndentt?d=1:e.lineIndent===t?d=0:e.lineIndentt)&&(K(e,t,b,!0,r)&&(m?d=e.result:h=e.result),m||(U(e,l,p,f,d,h,o,a),f=d=h=null),Y(e,!0,-1),s=e.input.charCodeAt(e.position)),e.lineIndent>t&&0!==s)N(e,"bad indentation of a mapping entry");else if(e.lineIndentu&&(u=e.lineIndent),O(f))l++;else{if(e.lineIndent=t){a=!0,f=e.input.charCodeAt(e.position);continue}e.position=o,e.line=s,e.lineStart=c,e.lineIndent=u;break}}a&&(L(e,r,o,!1),B(e,e.line-s),r=o=e.position,a=!1),E(f)||(o=e.position+1),f=e.input.charCodeAt(++e.position)}if(L(e,r,o,!1),e.result)return 1;e.kind=l,e.result=p}}(e,p,x===n)&&(m=!0,null===e.tag&&(e.tag="?")):(m=!0,null===e.tag&&null===e.anchor||N(e,"alias node should not have any properties")),null!==e.anchor&&(e.anchorMap[e.anchor]=e.result)):0===d&&(m=s&&W(e,f))),null!==e.tag&&"!"!==e.tag)if("?"===e.tag){for(null!==e.result&&"scalar"!==e.kind&&N(e,'unacceptable node kind for ! tag; it should be "scalar", not "'+e.kind+'"'),c=0,u=e.implicitTypes.length;c tag; it should be "'+l.kind+'", not "'+e.kind+'"'),l.resolve(e.result)?(e.result=l.construct(e.result),null!==e.anchor&&(e.anchorMap[e.anchor]=e.result)):N(e,"cannot resolve a node with !<"+e.tag+"> explicit tag")):N(e,"unknown tag !<"+e.tag+">");return null!==e.listener&&e.listener("close",e),null!==e.tag||null!==e.anchor||m}function $(e,t){t=t||{},0!==(e=String(e)).length&&(10!==e.charCodeAt(e.length-1)&&13!==e.charCodeAt(e.length-1)&&(e+="\n"),65279===e.charCodeAt(0)&&(e=e.slice(1)));var n=new h(e,t),i=e.indexOf("\0");for(-1!==i&&(n.position=i,N(n,"null byte is not allowed in input")),n.input+="\0";32===n.input.charCodeAt(n.position);)n.lineIndent+=1,n.position+=1;for(;n.positiont/2-1){n=" ... ",i+=5;break}for(r="",o=this.position;ot/2-1){r=" ... ",o-=5;break}return a=this.buffer.slice(i,o),s.repeat(" ",e)+n+a+r+"\n"+s.repeat(" ",e+this.position-i+n.length)+"^"},i.prototype.toString=function(e){var t,n="";return this.name&&(n+='in "'+this.name+'" '),n+="at line "+(this.line+1)+", column "+(this.column+1),e||(t=this.getSnippet())&&(n+=":\n"+t),n},t.exports=i},{"./common":2}],7:[function(e,t,n){"use strict";var r=e("./common"),o=e("./exception"),a=e("./type");function s(e,t,i){var r=[];return e.include.forEach(function(e){i=s(e,t,i)}),e[t].forEach(function(n){i.forEach(function(e,t){e.tag===n.tag&&e.kind===n.kind&&r.push(t)}),i.push(n)}),i.filter(function(e,t){return-1===r.indexOf(t)})}function c(e){this.include=e.include||[],this.implicit=e.implicit||[],this.explicit=e.explicit||[],this.implicit.forEach(function(e){if(e.loadKind&&"scalar"!==e.loadKind)throw new o("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.")}),this.compiledImplicit=s(this,"implicit",[]),this.compiledExplicit=s(this,"explicit",[]),this.compiledTypeMap=function(){var e,t,n={scalar:{},sequence:{},mapping:{},fallback:{}};function i(e){n[e.kind][e.tag]=n.fallback[e.tag]=e}for(e=0,t=arguments.length;e>16&255),a.push(o>>8&255),a.push(255&o)),o=o<<6|r.indexOf(n.charAt(s));return 0==(t=i%4*6)?(a.push(o>>16&255),a.push(o>>8&255),a.push(255&o)):18==t?(a.push(o>>10&255),a.push(o>>2&255)):12==t&&a.push(o>>4&255),c?c.from?c.from(a):new c(a):a},predicate:function(e){return c&&c.isBuffer(e)},represent:function(e){for(var t,n="",i=0,r=e.length,o=u,a=0;a>18&63],n+=o[i>>12&63],n+=o[i>>6&63],n+=o[63&i]),i=(i<<8)+e[a];return 0==(t=r%3)?(n+=o[i>>18&63],n+=o[i>>12&63],n+=o[i>>6&63],n+=o[63&i]):2==t?(n+=o[i>>10&63],n+=o[i>>4&63],n+=o[i<<2&63],n+=o[64]):1==t&&(n+=o[i>>2&63],n+=o[i<<4&63],n+=o[64],n+=o[64]),n}})},{"../type":13}],15:[function(e,t,n){"use strict";var i=e("../type");t.exports=new i("tag:yaml.org,2002:bool",{kind:"scalar",resolve:function(e){if(null===e)return!1;var t=e.length;return 4===t&&("true"===e||"True"===e||"TRUE"===e)||5===t&&("false"===e||"False"===e||"FALSE"===e)},construct:function(e){return"true"===e||"True"===e||"TRUE"===e},predicate:function(e){return"[object Boolean]"===Object.prototype.toString.call(e)},represent:{lowercase:function(e){return e?"true":"false"},uppercase:function(e){return e?"TRUE":"FALSE"},camelcase:function(e){return e?"True":"False"}},defaultStyle:"lowercase"})},{"../type":13}],16:[function(e,t,n){"use strict";var i=e("../common"),r=e("../type"),o=new RegExp("^(?:[-+]?(?:0|[1-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");var a=/^[-+]?[0-9]+e/;t.exports=new r("tag:yaml.org,2002:float",{kind:"scalar",resolve:function(e){return null!==e&&!(!o.test(e)||"_"===e[e.length-1])},construct:function(e){var t,n=e.replace(/_/g,"").toLowerCase(),i="-"===n[0]?-1:1,r=[];return 0<="+-".indexOf(n[0])&&(n=n.slice(1)),".inf"===n?1==i?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===n?NaN:0<=n.indexOf(":")?(n.split(":").forEach(function(e){r.unshift(parseFloat(e,10))}),n=0,t=1,r.forEach(function(e){n+=e*t,t*=60}),i*n):i*parseFloat(n,10)},predicate:function(e){return"[object Number]"===Object.prototype.toString.call(e)&&(e%1!=0||i.isNegativeZero(e))},represent:function(e,t){var n;if(isNaN(e))switch(t){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===e)switch(t){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===e)switch(t){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(i.isNegativeZero(e))return"-0.0";return n=e.toString(10),a.test(n)?n.replace("e",".e"):n},defaultStyle:"lowercase"})},{"../common":2,"../type":13}],17:[function(e,t,n){"use strict";var i=e("../common"),r=e("../type");t.exports=new r("tag:yaml.org,2002:int",{kind:"scalar",resolve:function(e){if(null===e)return!1;var t,n,i,r,o=e.length,a=0,s=!1;if(!o)return!1;if("-"!==(t=e[a])&&"+"!==t||(t=e[++a]),"0"===t){if(a+1===o)return!0;if("b"===(t=e[++a])){for(a++;a + + + {{template "header.html" "Logs"}} + + + + +
+ {{template "navbar.html" "logs"}} + +
+ + + +
+
+
+
+
+
+

Logs

+
+
+
+ + + + + + + + + + + + +
TimeTypeComponentMessageProperties
+
+ + +
+
+
+
+
+
+ +
+ +
+
+ + {{template "footer.html"}} + + + + + + \ No newline at end of file diff --git a/templates/navbar.html b/templates/navbar.html index ec1e122..abdd264 100644 --- a/templates/navbar.html +++ b/templates/navbar.html @@ -37,6 +37,16 @@ Routes + {{if eq . "logs"}} +
  • + {{else}} +
  • + {{end}} + + + Logs + +