Added error log parsing capability
Bryan Roe committed
Apr 13, 2021 at 18:14 UTC
20086dc361d721bf413d51b6a96c1f96fa426360
2 files changed
+196
-1
agents/meshcore.js
+17
-1
@@ -2736,7 +2736,7 @@ function processConsoleCommand(cmd, args, rights, sessionid) {
2736
var response = null;
2737
switch (cmd) {
2738
case 'help': { // Displays available commands
2739
- var fin = '', f = '', availcommands = 'agentupdate,msh,timerinfo,coreinfo,coredump,service,fdsnapshot,fdcount,startupoptions,alert,agentsize,versions,help,info,osinfo,args,print,type,dbkeys,dbget,dbset,dbcompact,eval,parseuri,httpget,wslist,plugin,wsconnect,wssend,wsclose,notify,ls,ps,kill,netinfo,location,power,wakeonlan,setdebug,smbios,rawsmbios,toast,lock,users,openurl,getscript,getclip,setclip,log,av,cpuinfo,sysinfo,apf,scanwifi,wallpaper,agentmsg';
2739
+ var fin = '', f = '', availcommands = 'agentupdate,errorlog,msh,timerinfo,coreinfo,coredump,service,fdsnapshot,fdcount,startupoptions,alert,agentsize,versions,help,info,osinfo,args,print,type,dbkeys,dbget,dbset,dbcompact,eval,parseuri,httpget,wslist,plugin,wsconnect,wssend,wsclose,notify,ls,ps,kill,netinfo,location,power,wakeonlan,setdebug,smbios,rawsmbios,toast,lock,users,openurl,getscript,getclip,setclip,log,av,cpuinfo,sysinfo,apf,scanwifi,wallpaper,agentmsg';
2740
if (require('os').dns != null) { availcommands += ',dnsinfo'; }
2741
if (process.platform == 'win32') { availcommands += ',safemode,wpfhwacceleration,uac'; }
2742
if (amt != null) { availcommands += ',amt,amtconfig,amtevents'; }
@@ -2764,6 +2764,22 @@ function processConsoleCommand(cmd, args, rights, sessionid) {
2764
agentUpdate_Start(null, { sessionid: sessionid });
2765
}
2766
break;
2767
+ case 'errorlog':
2768
+ switch(args['_'].length)
2769
+ {
2770
+ case 0:
2771
+ // All Error Logs
2772
+ response = JSON.stringify(require('util-agentlog').read(), null, 1);
2773
+ break;
2774
+ case 1:
2775
+ // Error Logs, by either count or timestamp
2776
+ response = JSON.stringify(require('util-agentlog').read(parseInt(args['_'][0])), null, 1);
2777
+ break;
2778
+ default:
2779
+ response = "Proper usage:\r\n errorlog [lastCount|linuxEpoch]";
2780
+ break;
2781
+ }
2782
+ break;
2783
case 'msh':
2784
response = JSON.stringify(_MSH(), null, 2);
2785
break;
agents/modules_meshcore/util-agentlog.js
new
+179
@@ -0,0 +1,179 @@
1
+/*
2
+Copyright 2021 Intel Corporation
3
+
4
+Licensed under the Apache License, Version 2.0 (the "License");
5
+you may not use this file except in compliance with the License.
6
+You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+Unless required by applicable law or agreed to in writing, software
11
+distributed under the License is distributed on an "AS IS" BASIS,
12
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+See the License for the specific language governing permissions and
14
+limitations under the License.
15
+*/
16
+
17
+
18
+function parseLine(entry)
19
+{
20
+ var test = entry.match(/^\[.*M\]/);
21
+ if (test == null)
22
+ {
23
+ test = entry.match(/\[.+ => .+:[0-9]+\]/);
24
+ if (test != null)
25
+ {
26
+ // Windows Crash Entry
27
+ var file = test[0].substring(1).match(/(?!.+ ).+(?=:)/);
28
+ var line = test[0].match(/(?!:)[0-9]+(?=\]$)/);
29
+ var fn = test[0].match(/(?!\[).+(?= =>)/);
30
+
31
+ if (file != null) { this.results.peek().f = file[0].trim(); }
32
+ if (line != null) { this.results.peek().l = line[0]; }
33
+ if (fn != null) { this.results.peek().fn = fn[0]; }
34
+ }
35
+ else
36
+ {
37
+ test = entry.match(/^[\.\/].+\(\) \[0x[0-9a-fA-F]+\]$/);
38
+ if (test != null)
39
+ {
40
+ // Linux Crash Stack with no symbols
41
+ test = test[0].match(/(?!\[)0x[0-9a-fA-F]+(?=\]$)/);
42
+ if (test != null)
43
+ {
44
+ if (this.results.peek().sx == null) { this.results.peek().sx = []; }
45
+ this.results.peek().sx.unshift(test[0]);
46
+ }
47
+ }
48
+ else
49
+ {
50
+ test = entry.match(/^\[.+_[0-9a-fA-F]{16}\]$/);
51
+ if(test!=null)
52
+ {
53
+ // Linux Crash ID
54
+ test = test[0].match(/(?!_)[0-9a-fA-F]{16}(?=\]$)/);
55
+ this.results.peek().h = test[0];
56
+ }
57
+ }
58
+
59
+ test = entry.match(/(?!^=>)\/+.+:[0-9]+$/);
60
+ if(test!=null)
61
+ {
62
+ // Linux Crash Entry
63
+ if (this.results.peek().s == null) { this.results.peek().s = []; }
64
+ this.results.peek().s.unshift(test[0]);
65
+ }
66
+
67
+ }
68
+ return;
69
+ }
70
+ test = test[0];
71
+
72
+ var dd = test.substring(1, test.length -1);
73
+ var c = dd.split(' ');
74
+ var t = c[1].split(':');
75
+ if (c[2] == 'PM') { t[0] = parseInt(t[0]) + 12; if (t[0] == 24) { t[0] = 0; } }
76
+
77
+ var d = Date.parse(c[0] + 'T' + t.join(':'));
78
+ var msg = entry.substring(test.length).trim();
79
+ var hash = msg.match(/^\[[0-9a-fA-F]{16}\]/);
80
+ if (hash != null)
81
+ {
82
+ hash = hash[0].substring(1, hash[0].length - 1);
83
+ msg = msg.substring(hash.length + 2).trim();
84
+ }
85
+ else
86
+ {
87
+ hash = msg.match(/^\[\]/);
88
+ if(hash!=null)
89
+ {
90
+ msg = msg.substring(2).trim();
91
+ hash = null;
92
+ }
93
+ }
94
+
95
+ var log = { t: Math.floor(d / 1000), m: msg };
96
+ if (hash != null) { log.h = hash; }
97
+
98
+ // Check for File/Line in generic log entry
99
+ test = msg.match(/^.+:[0-9]+ \([0-9]+,[0-9]+\)/);
100
+ if (test != null)
101
+ {
102
+ log.m = log.m.substring(test[0].length).trim();
103
+ log.f = test[0].match(/^.+(?=:[0-9]+)/)[0];
104
+ log.l = test[0].match(/(?!:)[0-9]+(?= \([0-9]+,[0-9]+\)$)/)[0];
105
+ }
106
+
107
+ this.results.push(log);
108
+}
109
+
110
+function readLog_data(buffer)
111
+{
112
+ var lines = buffer.toString().split('\n');
113
+ while(lines.length > 0)
114
+ {
115
+ parseLine.call(this, lines.shift());
116
+ }
117
+}
118
+
119
+function readLogEx(path)
120
+{
121
+ var ret = [];
122
+ try
123
+ {
124
+ var s = require('fs').createReadStream(path);
125
+ s.results = ret;
126
+ s.on('data', readLog_data);
127
+ s.resume();
128
+ s.removeAllListeners('data');
129
+ s = null;
130
+ }
131
+ catch(z)
132
+ {
133
+ }
134
+
135
+ return (ret);
136
+}
137
+
138
+function readLog(criteria, path)
139
+{
140
+ var objects = readLogEx(path == null ? (process.execPath.split('.exe').join('') + '.log') : path);
141
+ var ret = [];
142
+
143
+ if (typeof (criteria) == 'string')
144
+ {
145
+ try
146
+ {
147
+ var dstring = Date.parse(criteria);
148
+ criteria = Math.floor(dstring / 1000);
149
+ }
150
+ catch(z)
151
+ {
152
+ }
153
+ }
154
+
155
+ if (typeof (criteria) == 'number')
156
+ {
157
+ if(criteria < 1000)
158
+ {
159
+ // Return the last xxx entries
160
+ ret = objects.slice(objects.length - ((criteria > objects.length) ? objects.length : criteria));
161
+ }
162
+ else
163
+ {
164
+ // Return entries that are newer than xxx
165
+ var i;
166
+ for (i = 0; i < objects.length && objects[i].t <= criteria; ++i) { }
167
+ ret = objects.slice(i);
168
+ }
169
+ }
170
+ else
171
+ {
172
+ ret = objects;
173
+ }
174
+
175
+ return (ret);
176
+}
177
+
178
+module.exports = { read: readLog, readEx: readLogEx }
179
+