Update the design of default HTML pages
[svrjs.git] / logviewer.js
blobb2d62b9fb6dbe4151b5c2db964a66319262e35bb
1 //SVR.JS LOG VIEWER
3 var fs = require("fs");
4 var readline = require("readline");
5 var process = require("process");
7 var args = process.argv;
8 for (var i = (process.argv[0].indexOf("node") > -1 || process.argv[0].indexOf("bun") > -1 ? 2 : 1); i < args.length; i++) {
9   if (args[i] == "-h" || args[i] == "--help" || args[i] == "-?" || args[i] == "/h" || args[i] == "/?") {
10     console.log("SVR.JS log viewer usage:");
11     console.log("node logviewer.js [-h] [--help] [-?] [/h] [/?]");
12     console.log("-h -? /h /? --help    -- Displays help");
13     process.exit(0);
14   } else {
15     console.log("Unrecognized argument: " + args[i]);
16     console.log("SVR.JS log viewer usage:");
17     console.log("node logviewer.js [-h] [--help] [-?] [/h] [/?]");
18     console.log("-h -? /h /? --help    -- Displays help");
19     process.exit(1);
20   }
23 var logo = ["", "", "", "            \x1b[38;5;002m&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&", "          &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&", "         &&&\x1b[38;5;243m(((((((((((((((((((((((((((((((((((((((((((((((((((\x1b[38;5;002m&&&", "         \x1b[38;5;002m&&\x1b[38;5;243m((((((\x1b[38;5;241m###########\x1b[38;5;243m(((((((((((((((((((((((\x1b[38;5;011m***\x1b[38;5;243m(\x1b[38;5;011m***\x1b[38;5;243m(\x1b[38;5;011m***\x1b[38;5;243m((\x1b[38;5;002m&&", "         \x1b[38;5;002m&&&\x1b[38;5;243m(((((((((((((((((((((((((((((((((((((((((((((((((((\x1b[38;5;002m&&&", "         \x1b[38;5;002m&&&\x1b[38;5;243m(((((((((((((((((((((((((((((((((((((((((((((((((((\x1b[38;5;002m&&&", "         \x1b[38;5;002m&&\x1b[38;5;243m((((((\x1b[38;5;241m###########\x1b[38;5;243m(((((((((((((((((((((((\x1b[38;5;011m***\x1b[38;5;243m(\x1b[38;5;015m   \x1b[38;5;243m(\x1b[38;5;011m***\x1b[38;5;243m((\x1b[38;5;002m&&", "         \x1b[38;5;002m&&&\x1b[38;5;243m(((((((((((((((((((((((((((((((((((((((((((((((((((\x1b[38;5;002m&&&", "         \x1b[38;5;002m&&&\x1b[38;5;243m(((((((((((((((((((((((((((((((((((((((((((((((((((\x1b[38;5;002m&&&", "         \x1b[38;5;002m&&\x1b[38;5;243m((((((\x1b[38;5;241m###########\x1b[38;5;243m(((((((((((((((((((((((\x1b[38;5;015m   \x1b[38;5;243m(\x1b[38;5;015m   \x1b[38;5;243m(\x1b[38;5;015m   \x1b[38;5;243m((\x1b[38;5;002m&&", "         \x1b[38;5;002m&&&\x1b[38;5;243m(((((((((((((((((((((((((((((((((((((((((((((((((((\x1b[38;5;002m&&&", "         \x1b[38;5;002m&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&", "         \x1b[38;5;002m&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&", "         \x1b[38;5;002m&&&&&&&&\x1b[38;5;010m#########################################\x1b[38;5;002m&&&&&&&&", "         \x1b[38;5;002m&&&&&\x1b[38;5;010m###############################################\x1b[38;5;002m&&&&&", "         \x1b[38;5;002m&&&\x1b[38;5;010m###################################################\x1b[38;5;002m&&&", "         \x1b[38;5;002m&&\x1b[38;5;010m####\x1b[38;5;016m@@@@@@\x1b[38;5;010m#\x1b[38;5;016m@@@\x1b[38;5;010m###\x1b[38;5;016m@@@\x1b[38;5;010m#\x1b[38;5;016m@@@@@@@\x1b[38;5;010m###########\x1b[38;5;016m@@\x1b[38;5;010m##\x1b[38;5;016m@@@@@@\x1b[38;5;010m####\x1b[38;5;002m&&", "         \x1b[38;5;002m&&\x1b[38;5;010m###\x1b[38;5;016m@@\x1b[38;5;010m#######\x1b[38;5;016m@@\x1b[38;5;010m###\x1b[38;5;016m@@\x1b[38;5;010m##\x1b[38;5;016m@@\x1b[38;5;010m####\x1b[38;5;016m@@\x1b[38;5;010m##########\x1b[38;5;016m@@\x1b[38;5;010m#\x1b[38;5;016m@@\x1b[38;5;010m#########\x1b[38;5;002m&&", "         \x1b[38;5;002m&&\x1b[38;5;010m######\x1b[38;5;040m#\x1b[38;5;016m@@@@\x1b[38;5;010m##\x1b[38;5;016m@@\x1b[38;5;010m#\x1b[38;5;016m@@\x1b[38;5;010m###\x1b[38;5;016m@@@@@@@\x1b[38;5;010m#######\x1b[38;5;016m@@\x1b[38;5;010m##\x1b[38;5;016m@@\x1b[38;5;010m####\x1b[38;5;040m#\x1b[38;5;016m@@@@\x1b[38;5;010m###\x1b[38;5;002m&&", "         \x1b[38;5;002m&&\x1b[38;5;010m###\x1b[38;5;016m@@\x1b[38;5;034m%\x1b[38;5;010m###\x1b[38;5;016m@@\x1b[38;5;010m###\x1b[38;5;016m@@@\x1b[38;5;010m####\x1b[38;5;016m@@\x1b[38;5;010m####\x1b[38;5;016m@@\x1b[38;5;010m##\x1b[38;5;016m@@\x1b[38;5;010m###\x1b[38;5;016m@@@@\x1b[38;5;010m##\x1b[38;5;016m@@\x1b[38;5;034m%\x1b[38;5;010m###\x1b[38;5;016m@@\x1b[38;5;010m###\x1b[38;5;002m&&", "         \x1b[38;5;002m&&\x1b[38;5;010m#####################################################\x1b[38;5;002m&&", "         \x1b[38;5;002m&&&\x1b[38;5;010m###################################################\x1b[38;5;002m&&&", "         \x1b[38;5;002m&&&&&\x1b[38;5;010m###############################################\x1b[38;5;002m&&&&&", "         \x1b[38;5;002m&&&&&&&&\x1b[38;5;010m#########################################\x1b[38;5;002m&&&&&&&&", "         \x1b[38;5;002m&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&", "          &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&", "            &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&", "                                  \x1b[38;5;246m///////", "                                  ///////", "                                 \x1b[38;5;208m((((/))))", "                                \x1b[38;5;208m(((((/)))))", "            \x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m///\x1b[38;5;247m*\x1b[38;5;246m///\x1b[38;5;247m*\x1b[38;5;246m///\x1b[38;5;247m*\x1b[38;5;246m///\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m/\x1b[38;5;208m(((((/)))))\x1b[38;5;246m//\x1b[38;5;247m*\x1b[38;5;246m///\x1b[38;5;247m*\x1b[38;5;246m///\x1b[38;5;247m*\x1b[38;5;246m///\x1b[38;5;247m*\x1b[38;5;246m///\x1b[38;5;247m*\x1b[38;5;246m/", "           //\x1b[38;5;247m*\x1b[38;5;246m///////\x1b[38;5;247m*\x1b[38;5;246m///////\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m/\x1b[38;5;208m(((((/)))))\x1b[38;5;246m//\x1b[38;5;247m*\x1b[38;5;246m///////\x1b[38;5;247m*\x1b[38;5;246m///////\x1b[38;5;247m*\x1b[38;5;246m//", "           *\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;208m(((((/)))))\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*", "                                 \x1b[38;5;208m((((/))))", "", "", "", "\x1b[0m"];
25 for(var i=0;i<logo.length;i++) {
26   console.log(logo[i]);
28 console.log("Welcome to SVR.JS log viewer");
30 if(!fs.existsSync("log")) {
31   console.log("No log directory, exiting...");
32   process.exit(1);
35 function prompt(options) {
36 var rl = readline.createInterface({
37   input: process.stdin,
38   output: process.stdout,
39   prompt: 'logviewer> '
40 });
41 console.log("Options:");
42 for(var i=0;i<options.length;i++) {
43   console.log("[" + i + "] - " + options[i].name);
45 rl.prompt();
46 rl.on('line', (line) => {
47   var op = line.trim();
48   if(op == "") {
49     rl.prompt();
50     return;
51   }
52   var opn = parseInt(op);
53   rl.close();
54   if(options[op]) {
55     options[op].callback();
56   } else {
57     console.log("Invalid option.");
58     prompt(options);
59   }
60 });
64 function viewLog(log) {
65     if(log[log.length-1] == "") log.pop();
66     if(log[0] == "") log.shift();
67     for(var i=0;i<log.length;i++) {
68       if(log[i].indexOf("SERVER REQUEST MESSAGE") != -1) {
69         log[i] = log[i].replace("SERVER REQUEST MESSAGE","\x1b[34m\x1b[1mSERVER REQUEST MESSAGE\x1b[22m") + "\x1b[37m\x1b[0m";
70       } else if(log[i].indexOf("SERVER RESPONSE MESSAGE") != -1) {
71         log[i] = log[i].replace("SERVER RESPONSE MESSAGE","\x1b[32m\x1b[1mSERVER RESPONSE MESSAGE\x1b[22m") + "\x1b[37m\x1b[0m";
72       } else if(log[i].indexOf("SERVER RESPONSE ERROR MESSAGE") != -1) {
73         log[i] = log[i].replace("SERVER RESPONSE ERROR MESSAGE","\x1b[31m\x1b[1mSERVER RESPONSE ERROR MESSAGE\x1b[22m") + "\x1b[37m\x1b[0m";
74       } else if(log[i].indexOf("SERVER ERROR MESSAGE") != -1) {
75         log[i] = log[i].replace("SERVER ERROR MESSAGE","\x1b[41m\x1b[1mSERVER ERROR MESSAGE\x1b[22m") + "\x1b[40m\x1b[0m";
76       } else if(log[i].indexOf("SERVER WARNING MESSAGE") != -1) {
77         log[i] = log[i].replace("SERVER WARNING MESSAGE","\x1b[43m\x1b[1mSERVER WARNING MESSAGE\x1b[22m") + "\x1b[40m\x1b[0m";
78       } else if(log[i].indexOf("SERVER MESSAGE") != -1) {
79         log[i] = log[i].replace("SERVER MESSAGE","\x1b[1mSERVER MESSAGE\x1b[22m");
80       }
81       console.log(log[i]);
82     }
85 function viewMasterLogs() {
86   var logList = fs.readdirSync("log");
87   var masterLogs = [];
88   for(var i=0;i<logList.length;i++) {
89       if(logList[i].match(/^master-[0-9]+\.log$/)) {
90           masterLogs.push(logList[i]);
91       }
92   }
93   if(masterLogs.length == 0) {
94       console.log("No master log.");
95       return;
96   }
97   var latestLogFileName = masterLogs.sort().reverse()[0];
98   viewLog(fs.readFileSync("log/" + latestLogFileName).toString().split("\n"));
99   prompt(mainOptions);
102 function viewWorkerLogs() {
103   var logList = fs.readdirSync("log");
104   var masterLogs = [];
105   for(var i=0;i<logList.length;i++) {
106       if(logList[i].match(/^worker-[0-9]+\.log$/)) {
107           masterLogs.push(logList[i]);
108       }
109   }
110   if(masterLogs.length == 0) {
111       console.log("No worker logs.");
112       return;
113   }
114   var latestLogFileNames = masterLogs.sort().reverse().slice(0,5).reverse();
115   var log = [];
116   for(var i=0;i<latestLogFileNames.length;i++) {
117       var rlog = fs.readFileSync("log/" + latestLogFileNames[i]).toString().split("\n");
118       if(rlog[rlog.length-1] == "") rlog.pop();
119       if(rlog[0] == "") rlog.shift();
120       for(var j=0;j<rlog.length;j++) {
121           log.push(rlog[j]);
122       }
123   }
124   log = log.sort();
125   viewLog(log);
126   prompt(mainOptions);
129 function viewFilteredWorkerLogs(filter) {
130   var logList = fs.readdirSync("log");
131   var masterLogs = [];
132   for(var i=0;i<logList.length;i++) {
133       if(logList[i].match(/^worker-[0-9]+\.log$/)) {
134           masterLogs.push(logList[i]);
135       }
136   }
137   if(masterLogs.length == 0) {
138       console.log("No worker logs.");
139       return;
140   }
141   var latestLogFileNames = masterLogs.sort().reverse().slice(0,20).reverse();
142   var log = [];
143   for(var i=0;i<latestLogFileNames.length;i++) {
144       var rlog = fs.readFileSync("log/" + latestLogFileNames[i]).toString().split("\n");
145       if(rlog[rlog.length-1] == "") rlog.pop();
146       if(rlog[0] == "") rlog.shift();
147       for(var j=0;j<rlog.length;j++) {
148           if(rlog[j].indexOf(filter) != -1) log.push(rlog[j]);
149       }
150   }
151   log = log.sort();
152   viewLog(log);
153   prompt(mainOptions);
156 function viewFilteredWorkerLogsPrompt() {
157 var rl2 = readline.createInterface({
158   input: process.stdin,
159   output: process.stdout,
160   prompt: 'filter> '
162 console.log("Input filter:");
163 rl2.prompt();
164 rl2.on('line', (line) => {
165     rl2.close();
166     viewFilteredWorkerLogs(line);
170 var mainOptions = [
171   {name: "View latest master log", callback: viewMasterLogs},
172   {name: "View 5 latest worker logs", callback: viewWorkerLogs},
173   {name: "View filtered worker logs (latest 20 logs)", callback: viewFilteredWorkerLogsPrompt},
174   {name: "Exit log viewer", callback: function(){console.log("Bye!");process.exit(0);}}
177 prompt(mainOptions);