whatap 0.4.98 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/conf/config-default.js +10 -3
- package/lib/conf/configure.js +12 -3
- package/lib/conf/log-config-default.js +37 -0
- package/lib/control/control-handler.js +19 -6
- package/lib/core/agent.js +10 -8
- package/lib/core/shimmer.js +98 -0
- package/lib/counter/task/agentinfo.js +1 -1
- package/lib/data/datapack-sender.js +17 -0
- package/lib/data/zipprofile.js +2 -2
- package/lib/logger.js +25 -1
- package/lib/logsink/line-log-util.js +87 -0
- package/lib/logsink/line-log.js +12 -0
- package/lib/logsink/log-sender.js +78 -0
- package/lib/logsink/log-tracer.js +40 -0
- package/lib/logsink/sender-util.js +51 -0
- package/lib/logsink/zip/zip-send.js +177 -0
- package/lib/net/paramdef.js +1 -0
- package/lib/net/security-master.js +1 -1
- package/lib/observers/global-observer.js +200 -0
- package/lib/observers/grpc-observer.js +336 -0
- package/lib/observers/http-observer.js +11 -8
- package/lib/observers/process-observer.js +55 -8
- package/lib/observers/redis-observer.js +74 -11
- package/lib/observers/socket.io-observer.js +76 -67
- package/lib/pack/event-pack.js +1 -1
- package/lib/pack/log-sink-pack.js +139 -0
- package/lib/pack/packenum.js +3 -1
- package/lib/pack/zip-pack.js +0 -1
- package/lib/topology/link.js +63 -0
- package/lib/topology/nodeinfo.js +123 -0
- package/lib/topology/status-detector.js +111 -0
- package/lib/util/compare-util.js +131 -0
- package/lib/util/linkedset.js +278 -0
- package/lib/util/oidutil.js +4 -1
- package/package.json +2 -2
|
@@ -4,27 +4,24 @@
|
|
|
4
4
|
* can be found in the LICENSE file.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
var
|
|
8
|
-
TraceContextManager = require('../trace/trace-context-manager'),
|
|
7
|
+
var TraceContextManager = require('../trace/trace-context-manager'),
|
|
9
8
|
SocketStep = require('../step/socket-step'),
|
|
10
9
|
conf = require('../conf/configure'),
|
|
11
10
|
IPUtil = require('../util/iputil'),
|
|
12
11
|
Logger = require('../logger');
|
|
13
|
-
const {Detector: URLPatternDetector} = require("
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const ResourceProfile = require("whatap/lib/util/resourceprofile");
|
|
12
|
+
const {Detector: URLPatternDetector} = require("../trace/serviceurl-pattern-detector");
|
|
13
|
+
const DataTextAgent = require("../data/datatext-agent");
|
|
14
|
+
const ResourceProfile = require("../util/resourceprofile");
|
|
17
15
|
const ProfilePack = require('../pack/profile-pack');
|
|
18
16
|
const TxRecord = require('../service/tx-record');
|
|
19
17
|
const DateUtil = require('../util/dateutil');
|
|
20
18
|
const SecurityMaster = require('../net/security-master');
|
|
21
19
|
const DataProfileAgent = require('../data/dataprofile-agent');
|
|
22
|
-
const
|
|
23
|
-
const MeterUsers = require("whatap/lib/counter/meter/meter-users");
|
|
24
|
-
const DataPackSender = require("whatap/lib/data/datapack-sender");
|
|
20
|
+
const MeterUsers = require("../counter/meter/meter-users");
|
|
25
21
|
const MeterService = require('../counter/meter/meter-service').MeterService;
|
|
22
|
+
const shimmer = require('../core/shimmer');
|
|
26
23
|
|
|
27
|
-
var trace_background_socket_enabled = conf.getProperty('trace_background_socket_enabled',
|
|
24
|
+
var trace_background_socket_enabled = conf.getProperty('trace_background_socket_enabled', true);
|
|
28
25
|
conf.on('trace_background_socket_enabled', function (newProps) {
|
|
29
26
|
trace_background_socket_enabled = newProps;
|
|
30
27
|
})
|
|
@@ -55,66 +52,78 @@ SocketIOObserver.prototype.inject = function (mod, moduleName) {
|
|
|
55
52
|
Logger.initPrint("SocketIOObserver");
|
|
56
53
|
|
|
57
54
|
var self = this;
|
|
58
|
-
var aop = self.agent.aop;
|
|
59
55
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if(
|
|
63
|
-
return
|
|
56
|
+
shimmer.wrap(mod.prototype, 'on', function (original) {
|
|
57
|
+
return function (event, listener) {
|
|
58
|
+
if (event === 'connection') {
|
|
59
|
+
return original.call(this, event, function (socket) {
|
|
60
|
+
shimmer.wrap(socket, 'emit', function (origEmit) {
|
|
61
|
+
return function (emitEvent, ...args) {
|
|
62
|
+
if (trace_background_socket_enabled) {
|
|
63
|
+
self.__handleSocketEmitEvent(socket, emitEvent, args);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return origEmit.apply(this, [emitEvent, ...args]);
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
return listener.apply(this, [socket]);
|
|
71
|
+
});
|
|
64
72
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
73
|
+
|
|
74
|
+
return original.call(this, event, listener);
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
SocketIOObserver.prototype.__handleSocketEmitEvent = function(socket, event, args) {
|
|
80
|
+
if (trace_sampling_enabled) {
|
|
81
|
+
var now = Date.now();
|
|
82
|
+
if (!socket_count.start_time) {
|
|
83
|
+
socket_count.start_time = now;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if ((now - socket_count.start_time) > 5000) {
|
|
87
|
+
socket_count.start_time = now;
|
|
88
|
+
socket_count.count = 0;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
socket_count.count++;
|
|
92
|
+
if (socket_count.count > trace_sampling_tps) {
|
|
93
|
+
MeterService.add(0, 1, 0, 0, 0, 0);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
TraceContextManager._asyncLocalStorage.run(initCtx(socket, args), () => {
|
|
99
|
+
try {
|
|
100
|
+
var ctx = TraceContextManager._asyncLocalStorage.getStore();
|
|
101
|
+
if (!ctx) return;
|
|
102
|
+
|
|
103
|
+
ctx.footprint('Socket Emit Event: ' + event);
|
|
104
|
+
|
|
105
|
+
var host;
|
|
106
|
+
if (socket.conn && socket.conn.remoteAddress && socket.conn.remoteAddress.includes(':')) {
|
|
107
|
+
host = socket.conn.remoteAddress.substring(socket.conn.remoteAddress.lastIndexOf(':') + 1);
|
|
81
108
|
}
|
|
82
109
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
step.start_time = ctx.getElapsedTime();
|
|
101
|
-
step.ipaddr = Buffer.from(IPUtil.stringToBytes(host));
|
|
102
|
-
// step.port = port;
|
|
103
|
-
|
|
104
|
-
ctx.socket_connecting = false;
|
|
105
|
-
step.elapsed = ctx.getElapsedTime() - step.start_time;
|
|
106
|
-
ctx.profile.push(step);
|
|
107
|
-
|
|
108
|
-
ctx.footprint('Socket Connecting Done');
|
|
109
|
-
|
|
110
|
-
self.__endTransaction(null, ctx);
|
|
111
|
-
return;
|
|
112
|
-
}catch (e) {
|
|
113
|
-
Logger.printError('WHATAP-616', 'socket.io transaction error..', e, false);
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
});
|
|
110
|
+
ctx.socket_connecting = true;
|
|
111
|
+
ctx.footprint('Socket Connecting: ' + host);
|
|
112
|
+
|
|
113
|
+
var step = new SocketStep();
|
|
114
|
+
step.start_time = ctx.getElapsedTime();
|
|
115
|
+
step.ipaddr = Buffer.from(IPUtil.stringToBytes(host));
|
|
116
|
+
// step.port = port;
|
|
117
|
+
|
|
118
|
+
ctx.socket_connecting = false;
|
|
119
|
+
step.elapsed = ctx.getElapsedTime() - step.start_time;
|
|
120
|
+
ctx.profile.push(step)
|
|
121
|
+
|
|
122
|
+
this.__endTransaction(null, ctx);
|
|
123
|
+
|
|
124
|
+
} catch (e) {
|
|
125
|
+
Logger.printError('WHATAP-616', 'socket.io emit transaction error..', e, false);
|
|
126
|
+
}
|
|
118
127
|
});
|
|
119
128
|
};
|
|
120
129
|
|
|
@@ -163,7 +172,7 @@ function initCtx(socket, args) {
|
|
|
163
172
|
if (!ctx) {return;}
|
|
164
173
|
|
|
165
174
|
var remote_addr;
|
|
166
|
-
const address = socket.
|
|
175
|
+
const address = socket.conn.remoteAddress;
|
|
167
176
|
if(address && address.includes(':')){
|
|
168
177
|
remote_addr = address.substring(address.lastIndexOf(':')+1);
|
|
169
178
|
}
|
package/lib/pack/event-pack.js
CHANGED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
const Pack = require('./pack');
|
|
2
|
+
const PackEnum = require('./packenum');
|
|
3
|
+
const MapValue = require('../value/map-value');
|
|
4
|
+
const DataOutputX = require('../io/data-outputx');
|
|
5
|
+
const DataInputX = require('../io/data-inputx');
|
|
6
|
+
const HashUtil = require('../util/hashutil');
|
|
7
|
+
const Value = require('../value/value');
|
|
8
|
+
const BooleanValue = require('../value/boolean-value');
|
|
9
|
+
|
|
10
|
+
function LogSinkPack() {
|
|
11
|
+
Pack.call(this);
|
|
12
|
+
this.category = '';
|
|
13
|
+
this.tagHash = 0;
|
|
14
|
+
this.tags = new MapValue();
|
|
15
|
+
this.line = 0;
|
|
16
|
+
this.content = '';
|
|
17
|
+
this.fields = new MapValue();
|
|
18
|
+
this.dropped = false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
LogSinkPack.prototype = Object.create(Pack.prototype);
|
|
22
|
+
LogSinkPack.prototype.constructor = LogSinkPack;
|
|
23
|
+
|
|
24
|
+
LogSinkPack.prototype.getPackType = function () {
|
|
25
|
+
return PackEnum.LOGSINK;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
LogSinkPack.prototype.toString = function () {
|
|
29
|
+
return `${Pack.prototype.toString.call(this)} [category=${this.category}, tagHash=${this.tagHash}, tags=${this.tags}, content=${this.content}, fields=${this.fields}]`;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
LogSinkPack.prototype.getTagAsBytes = function () {
|
|
33
|
+
const out = new DataOutputX();
|
|
34
|
+
out.writeValue(this.tags);
|
|
35
|
+
return out.toByteArray();
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
LogSinkPack.prototype.getContentBytes = function () {
|
|
39
|
+
const o = new DataOutputX();
|
|
40
|
+
o.writeByte(1);
|
|
41
|
+
o.writeText(this.content);
|
|
42
|
+
o.writeDecimal(this.line);
|
|
43
|
+
return o.toByteArray();
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
LogSinkPack.prototype.putCtr = function (key, value) {
|
|
47
|
+
if (key.charAt(0) === '!') {
|
|
48
|
+
this.fields.putValue(key, value);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
LogSinkPack.prototype.getCtr = function (key) {
|
|
53
|
+
return this.fields.get(key);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
LogSinkPack.prototype.getCtrBoolean = function (key) {
|
|
57
|
+
const v = this.fields.get(key);
|
|
58
|
+
if (v instanceof BooleanValue) {
|
|
59
|
+
return v.value;
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
LogSinkPack.prototype.content = function () {
|
|
65
|
+
return this.content || '';
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
LogSinkPack.prototype.setContent = function (str) {
|
|
69
|
+
this.content = str;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
LogSinkPack.prototype.setContentBytes = function (d) {
|
|
73
|
+
try {
|
|
74
|
+
if (!d || d.length < 1) return;
|
|
75
|
+
const inStream = new DataInputX(d);
|
|
76
|
+
const ver = inStream.readByte();
|
|
77
|
+
if (ver === 1) {
|
|
78
|
+
this.content = inStream.readText();
|
|
79
|
+
this.line = inStream.readDecimal();
|
|
80
|
+
}
|
|
81
|
+
} catch (e) {
|
|
82
|
+
// Handle error
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
LogSinkPack.prototype.write = function (dout) {
|
|
87
|
+
Pack.prototype.write.call(this, dout);
|
|
88
|
+
dout.writeByte(0);
|
|
89
|
+
dout.writeText(this.category);
|
|
90
|
+
dout.writeDecimal(this.tagHash);
|
|
91
|
+
dout.writeValue(this.tags);
|
|
92
|
+
dout.writeDecimal(this.line);
|
|
93
|
+
dout.writeText(this.content);
|
|
94
|
+
if (this.fields.size() > 0) {
|
|
95
|
+
dout.writeBoolean(true);
|
|
96
|
+
dout.writeValue(this.fields);
|
|
97
|
+
} else {
|
|
98
|
+
dout.writeBoolean(false);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
LogSinkPack.prototype.read = function (din) {
|
|
103
|
+
Pack.prototype.read.call(this, din);
|
|
104
|
+
const ver = din.readByte();
|
|
105
|
+
this.category = din.readText();
|
|
106
|
+
this.tagHash = din.readDecimal();
|
|
107
|
+
this.tags = din.readValue();
|
|
108
|
+
this.line = din.readDecimal();
|
|
109
|
+
this.content = din.readText();
|
|
110
|
+
if (din.readBoolean()) {
|
|
111
|
+
this.fields = din.readValue();
|
|
112
|
+
}
|
|
113
|
+
return this;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
LogSinkPack.prototype.resetTagHash = function () {
|
|
117
|
+
const out = new DataOutputX();
|
|
118
|
+
out.writeValue(this.tags);
|
|
119
|
+
const tagBytes = out.toByteArray();
|
|
120
|
+
this.tagHash = HashUtil.hash64(tagBytes);
|
|
121
|
+
return tagBytes;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
LogSinkPack.prototype.transferOidToTag = function () {
|
|
125
|
+
if (this.oid !== 0 && !this.tags.containsKey('oid')) {
|
|
126
|
+
this.tags.putValue('oid', this.oid);
|
|
127
|
+
this.tagHash = 0;
|
|
128
|
+
}
|
|
129
|
+
if (this.okind !== 0 && !this.tags.containsKey('okind')) {
|
|
130
|
+
this.tags.putValue('okind', this.okind);
|
|
131
|
+
this.tagHash = 0;
|
|
132
|
+
}
|
|
133
|
+
if (this.onode !== 0 && !this.tags.containsKey('onode')) {
|
|
134
|
+
this.tags.putValue('onode', this.onode);
|
|
135
|
+
this.tagHash = 0;
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
module.exports = LogSinkPack;
|
package/lib/pack/packenum.js
CHANGED
|
@@ -32,6 +32,7 @@ exports.HITMAP5M = 0x1700;
|
|
|
32
32
|
|
|
33
33
|
exports.TAG_COUNT = 0x1601;
|
|
34
34
|
exports.ZIP = 0x170b;
|
|
35
|
+
exports.LOGSINK = 0x170a;
|
|
35
36
|
|
|
36
37
|
exports.PACK_NAME = {
|
|
37
38
|
0x0100 : 'PARAMETER',
|
|
@@ -58,6 +59,7 @@ exports.PACK_NAME = {
|
|
|
58
59
|
0x1600 : 'COUNTER5M',
|
|
59
60
|
0x1700 : 'HITMAP5M',
|
|
60
61
|
0x1601 : 'TAG_COUNT',
|
|
61
|
-
0x170b : 'ZIP'
|
|
62
|
+
0x170b : 'ZIP',
|
|
63
|
+
0x170a : 'LOGSINK',
|
|
62
64
|
};
|
|
63
65
|
|
package/lib/pack/zip-pack.js
CHANGED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
var { InetAddress } = require('net');
|
|
2
|
+
var CompareUtil = require('../util/compare-util');
|
|
3
|
+
var HashUtil = require('../util/hashutil');
|
|
4
|
+
|
|
5
|
+
function LINK() {
|
|
6
|
+
this.ip = null;
|
|
7
|
+
this.port = 0;
|
|
8
|
+
|
|
9
|
+
this.toString = function () {
|
|
10
|
+
if (this.ip === null) return `0.0.0.0:${this.port}`;
|
|
11
|
+
try {
|
|
12
|
+
return `${InetAddress.getByAddress(this.ip).getHostAddress()}:${this.port}`;
|
|
13
|
+
} catch (e) {
|
|
14
|
+
return `0.0.0.0:${this.port}`;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
this.include = function (k) {
|
|
19
|
+
if (!CompareUtil.equals(this.ip, k.ip)) return false;
|
|
20
|
+
if (this.port === 0) return true;
|
|
21
|
+
return this.port === k.port;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
this.equals = function (o) {
|
|
25
|
+
if (o.constructor !== this.constructor) return false;
|
|
26
|
+
var k = o;
|
|
27
|
+
if (!CompareUtil.equals(this.ip, k.ip)) return false;
|
|
28
|
+
return this.port === k.port;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
this.hashCode = function () {
|
|
32
|
+
return HashUtil.hash(this.ip) | this.port;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
this.toBytes = function (out) {
|
|
36
|
+
out.writeBlob(this.ip);
|
|
37
|
+
out.writeInt(this.port);
|
|
38
|
+
return this;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
this.toObject = function (din) {
|
|
42
|
+
this.ip = din.readBlob();
|
|
43
|
+
this.port = din.readInt();
|
|
44
|
+
return this;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
LINK.create = function (ipStr, port) {
|
|
49
|
+
var k = new LINK();
|
|
50
|
+
try {
|
|
51
|
+
k.ip = InetAddress.getByName(ipStr).getAddress();
|
|
52
|
+
} catch (e) {
|
|
53
|
+
k.ip = new Buffer(4);
|
|
54
|
+
}
|
|
55
|
+
k.port = port;
|
|
56
|
+
return k;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
LINK.prototype = new LINK();
|
|
60
|
+
LINK.prototype.constructor = LINK;
|
|
61
|
+
|
|
62
|
+
module.exports = LINK;
|
|
63
|
+
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
const DataOutputX = require('../io/data-outputx');
|
|
2
|
+
const DataInputX = require('../io/data-inputx');
|
|
3
|
+
const MapValue = require('../value/map-value');
|
|
4
|
+
const LINK = require('./link');
|
|
5
|
+
const net = require('net');
|
|
6
|
+
|
|
7
|
+
function NodeInfo() {
|
|
8
|
+
this.attr = new MapValue();
|
|
9
|
+
this.listen = new Set();
|
|
10
|
+
this.outter = new Set();
|
|
11
|
+
|
|
12
|
+
this.addListen = function (localIPs, address) {
|
|
13
|
+
const ipo = this.getIPPORT(address);
|
|
14
|
+
if (!ipo || this.isLocal127(ipo)) return;
|
|
15
|
+
|
|
16
|
+
if (ipo.ip === '*' || ipo.ip === '0.0.0.0' || ipo.ip === '::') {
|
|
17
|
+
localIPs.forEach(local_ip => {
|
|
18
|
+
const k = LINK.create(local_ip, parseInt(ipo.port, 10));
|
|
19
|
+
if (k) this.listen.add(k);
|
|
20
|
+
});
|
|
21
|
+
} else {
|
|
22
|
+
const k = LINK.create(ipo.ip, parseInt(ipo.port, 10));
|
|
23
|
+
if (k) this.listen.add(k);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
this.addOutter = function (local, remote) {
|
|
28
|
+
const localIPO = this.getIPPORT(local);
|
|
29
|
+
if (!localIPO || this.isIPv6(localIPO)) return;
|
|
30
|
+
if (this.hasListen(localIPO.ip, localIPO.port)) return;
|
|
31
|
+
|
|
32
|
+
const remoteIPO = this.getIPPORT(remote);
|
|
33
|
+
if (!remoteIPO || this.isIPv6(remoteIPO) || this.isLocal127(remoteIPO)) return;
|
|
34
|
+
|
|
35
|
+
const k = LINK.create(remoteIPO.ip, parseInt(remoteIPO.port, 10));
|
|
36
|
+
if (k) this.outter.add(k);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
this.hasListen = function (ip, port) {
|
|
40
|
+
const k = LINK.create(ip, parseInt(port, 10));
|
|
41
|
+
return this.listen.has(k);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
this.getIPPORT = function (address) {
|
|
45
|
+
try {
|
|
46
|
+
const ipo = {};
|
|
47
|
+
const x = address.lastIndexOf(':');
|
|
48
|
+
ipo.ip = address.substring(0, x);
|
|
49
|
+
ipo.port = address.substring(x + 1);
|
|
50
|
+
return ipo;
|
|
51
|
+
} catch (e) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
this.toBytes = function () {
|
|
57
|
+
const out = new DataOutputX();
|
|
58
|
+
out.writeByte(0);
|
|
59
|
+
out.writeValue(this.attr);
|
|
60
|
+
this.toLinkBytes(this.listen, out);
|
|
61
|
+
this.toLinkBytes(this.outter, out);
|
|
62
|
+
return out.toByteArray();
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
this.toObject = function (b) {
|
|
66
|
+
const din = new DataInputX(b);
|
|
67
|
+
const ver = din.readByte();
|
|
68
|
+
this.attr = din.readValue();
|
|
69
|
+
this.listen = this.toLinkObject(din);
|
|
70
|
+
this.outter = this.toLinkObject(din);
|
|
71
|
+
return this;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
this.toLinkObject = function (din) {
|
|
75
|
+
const data = new Set();
|
|
76
|
+
const sz = din.readDecimal();
|
|
77
|
+
for (let i = 0; i < sz; i++) {
|
|
78
|
+
data.add(new LINK().toObject(din));
|
|
79
|
+
}
|
|
80
|
+
return data;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
this.toLinkBytes = function (data, out) {
|
|
84
|
+
out.writeDecimal(data.size);
|
|
85
|
+
if (data.size === 0) return;
|
|
86
|
+
data.forEach(k => k.toBytes(out));
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
this.toJSON = function () {
|
|
90
|
+
const o = new Map();
|
|
91
|
+
o.put('attr', JSON.stringify(this.attr));
|
|
92
|
+
o.put('listen', JSON.parse(this.listen));
|
|
93
|
+
o.put('outter', JSON.parse(this.outter));
|
|
94
|
+
return o;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
this.toJSON = function (data) {
|
|
98
|
+
const out = new JSONArray();
|
|
99
|
+
data.forEach(k => out.put(k.toString()));
|
|
100
|
+
return out;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
this.isIPv6 = function(data) {
|
|
104
|
+
var ip = data.ip;
|
|
105
|
+
if(ip){
|
|
106
|
+
return net.isIPv6(ip);
|
|
107
|
+
}
|
|
108
|
+
return false;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
this.isLocal127 = function (data) {
|
|
112
|
+
var ip = data.ip;
|
|
113
|
+
if(ip){
|
|
114
|
+
return ip === '127.0.0.1';
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
NodeInfo.prototype = new NodeInfo();
|
|
121
|
+
NodeInfo.prototype.constructor = NodeInfo;
|
|
122
|
+
|
|
123
|
+
module.exports = NodeInfo;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
var { exec } = require('child_process');
|
|
2
|
+
var os = require('os');
|
|
3
|
+
var NodeInfo = require('./nodeinfo');
|
|
4
|
+
var Logger = require('../logger');
|
|
5
|
+
|
|
6
|
+
function StatusDetector() {
|
|
7
|
+
this.process = async function () {
|
|
8
|
+
let node = new NodeInfo();
|
|
9
|
+
let stat = await this.netstat();
|
|
10
|
+
|
|
11
|
+
if (!stat) {
|
|
12
|
+
node = new NodeInfo();
|
|
13
|
+
} else {
|
|
14
|
+
try {
|
|
15
|
+
node = this.parse(stat);
|
|
16
|
+
} catch (e) {
|
|
17
|
+
node = new NodeInfo();
|
|
18
|
+
Logger.printError("WHATAP-203", "NodeInfo parse error", e, false);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
node.attr.type = 'nodejs';
|
|
23
|
+
node.attr.time = Date.now();
|
|
24
|
+
node.attr.ip = this.getLocalIpAddress();
|
|
25
|
+
node.attr.pid = process.pid;
|
|
26
|
+
node.attr.pname = process.title;
|
|
27
|
+
|
|
28
|
+
return node;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
this.netstat = function () {
|
|
32
|
+
return new Promise((resolve, reject) => {
|
|
33
|
+
let cmd = 'netstat -an -t';
|
|
34
|
+
if (os.platform() === 'darwin') {
|
|
35
|
+
cmd = 'netstat -an -p tcp';
|
|
36
|
+
} else if (os.platform() === 'win32') {
|
|
37
|
+
resolve('');
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
exec(cmd, (error, stdout, stderr) => {
|
|
42
|
+
if (error) {
|
|
43
|
+
reject(error);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
resolve(stdout);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
this.parse = function (netstat) {
|
|
52
|
+
var node = new NodeInfo();
|
|
53
|
+
var localIPs = this.getLocalIpSet();
|
|
54
|
+
|
|
55
|
+
var lines = netstat.split('\n');
|
|
56
|
+
lines.forEach(line => {
|
|
57
|
+
if (line.startsWith('tcp')) {
|
|
58
|
+
this.parseLine(node, line, localIPs);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
return node;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
this.parseLine = function (node, line, localIPs) {
|
|
66
|
+
var tokens = line.trim().split(/\s+/);
|
|
67
|
+
if (!tokens[0].startsWith('tcp')) return;
|
|
68
|
+
|
|
69
|
+
var localAddress = tokens[3].replace(/(\d+\.\d+\.\d+\.\d+)\.(\d+)/, '$1:$2');
|
|
70
|
+
var remoteAddress = tokens[4].replace(/(\d+\.\d+\.\d+\.\d+)\.(\d+)/, '$1:$2');
|
|
71
|
+
|
|
72
|
+
if (tokens[5] === 'LISTEN') {
|
|
73
|
+
node.addListen(localIPs, localAddress);
|
|
74
|
+
} else {
|
|
75
|
+
node.addOutter(localAddress, remoteAddress);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
this.getLocalIpSet = function () {
|
|
80
|
+
var ipSet = new Set();
|
|
81
|
+
var interfaces = os.networkInterfaces();
|
|
82
|
+
for (var devName in interfaces) {
|
|
83
|
+
var iface = interfaces[devName];
|
|
84
|
+
iface.forEach(alias => {
|
|
85
|
+
if (alias.family === 'IPv4' && !alias.internal) {
|
|
86
|
+
ipSet.add(alias.address);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return ipSet;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
this.getLocalIpAddress = function () {
|
|
94
|
+
var interfaces = os.networkInterfaces();
|
|
95
|
+
for (var devName in interfaces) {
|
|
96
|
+
var iface = interfaces[devName];
|
|
97
|
+
for (let i = 0; i < iface.length; i++) {
|
|
98
|
+
var alias = iface[i];
|
|
99
|
+
if (alias.family === 'IPv4' && !alias.internal) {
|
|
100
|
+
return alias.address;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return '0.0.0.0';
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
StatusDetector.prototype = new StatusDetector();
|
|
109
|
+
StatusDetector.prototype.constructor = StatusDetector;
|
|
110
|
+
|
|
111
|
+
module.exports = StatusDetector;
|