whatap 1.0.2 → 1.0.3-canary.0
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/README.md +77 -33
- package/agent/darwin/arm64/whatap_nodejs +0 -0
- package/agent/linux/amd64/whatap_nodejs +0 -0
- package/agent/linux/arm64/whatap_nodejs +0 -0
- package/build.txt +4 -0
- package/lib/conf/config-default.js +3 -10
- package/lib/conf/configure.js +349 -369
- package/lib/conf/license.js +1 -1
- package/lib/control/packagectr-helper.js +3 -34
- package/lib/core/agent.js +888 -176
- package/lib/core/interceptor.js +6 -6
- package/lib/core/shimmer.js +36 -82
- package/lib/counter/counter-manager.js +8 -79
- package/lib/counter/task/activetransaction.js +17 -68
- package/lib/io/data-inputx.js +3 -13
- package/lib/io/data-outputx.js +206 -268
- package/lib/logger.js +6 -6
- package/lib/net/security-master.js +20 -139
- package/lib/observers/apollo-server-observer.js +27 -33
- package/lib/observers/global-observer.js +80 -155
- package/lib/observers/http-observer.js +236 -666
- package/lib/observers/ioredis-observer.js +294 -0
- package/lib/observers/maria-observer.js +362 -204
- package/lib/observers/mongodb-observer.js +226 -169
- package/lib/observers/mongoose-observer.js +323 -518
- package/lib/observers/mssql-observer.js +418 -177
- package/lib/observers/mysql-observer.js +449 -342
- package/lib/observers/mysql2-observer.js +358 -396
- package/lib/observers/oracle-observer.js +384 -559
- package/lib/observers/pgsql-observer.js +489 -231
- package/lib/observers/prisma-observer.js +92 -303
- package/lib/observers/process-observer.js +35 -79
- package/lib/observers/redis-observer.js +331 -166
- package/lib/observers/socket.io-observer.js +187 -226
- package/lib/observers/websocket-observer.js +301 -175
- package/lib/pack/counter-pack.js +0 -3
- package/lib/pack/log-sink-pack.js +52 -14
- package/lib/pack/tagcount-pack.js +4 -4
- package/lib/{counter/task → system}/gc-action.js +74 -27
- package/lib/trace/trace-context-manager.js +25 -113
- package/lib/trace/trace-context.js +7 -21
- package/lib/trace/trace-httpc.js +11 -17
- package/lib/trace/trace-sql.js +21 -29
- package/lib/udp/async_sender.js +119 -0
- package/lib/udp/index.js +17 -0
- package/lib/udp/packet_enum.js +52 -0
- package/lib/udp/packet_queue.js +69 -0
- package/lib/udp/packet_type_enum.js +33 -0
- package/lib/udp/param_def.js +72 -0
- package/lib/udp/udp_session.js +336 -0
- package/lib/util/escape-literal-sql.js +5 -5
- package/lib/util/hashutil.js +18 -18
- package/lib/util/keygen.js +3 -0
- package/lib/util/linkedset.js +2 -1
- package/lib/util/nodeutil.js +1 -2
- package/lib/util/sql-util.js +178 -0
- package/lib/util/trace-helper.js +91 -0
- package/lib/util/transfer.js +58 -0
- package/lib/value/map-value.js +2 -3
- package/package.json +5 -9
- package/whatap.conf +4 -1
- package/lib/conf/conf-sys-mon.js +0 -101
- package/lib/control/cmd-config.js +0 -24
- package/lib/control/control-handler.js +0 -367
- package/lib/core/request-agent.js +0 -27
- package/lib/counter/meter/meter-activex.js +0 -67
- package/lib/counter/meter/meter-httpc.js +0 -57
- package/lib/counter/meter/meter-resource.js +0 -9
- package/lib/counter/meter/meter-service.js +0 -168
- package/lib/counter/meter/meter-socket.io.js +0 -51
- package/lib/counter/meter/meter-sql.js +0 -71
- package/lib/counter/meter/meter-users.js +0 -58
- package/lib/counter/meter.js +0 -183
- package/lib/counter/task/agentinfo.js +0 -107
- package/lib/counter/task/gcstat.js +0 -34
- package/lib/counter/task/heapmem.js +0 -25
- package/lib/counter/task/httpc.js +0 -76
- package/lib/counter/task/metering-info.js +0 -125
- package/lib/counter/task/proc-cpu.js +0 -29
- package/lib/counter/task/realtimeuser.js +0 -31
- package/lib/counter/task/res/systemECSTask.js +0 -39
- package/lib/counter/task/res/systemKubeTask.js +0 -53
- package/lib/counter/task/res/util/awsEcsClientThread.js +0 -218
- package/lib/counter/task/res/util/linuxProcStatUtil.js +0 -14
- package/lib/counter/task/res-sys-cpu.js +0 -62
- package/lib/counter/task/service.js +0 -202
- package/lib/counter/task/socketio.js +0 -30
- package/lib/counter/task/sql.js +0 -105
- package/lib/counter/task/systemperf.js +0 -43
- package/lib/data/datapack-sender.js +0 -289
- package/lib/data/dataprofile-agent.js +0 -162
- package/lib/data/datatext-agent.js +0 -135
- package/lib/data/event-level.js +0 -15
- package/lib/data/test.js +0 -49
- package/lib/data/zipprofile.js +0 -197
- package/lib/env/constants.js +0 -21
- package/lib/error/error-handler.js +0 -437
- package/lib/kube/kube-client.js +0 -144
- package/lib/lang/text-types.js +0 -58
- package/lib/logsink/line-log-util.js +0 -87
- package/lib/logsink/line-log.js +0 -12
- package/lib/logsink/log-sender.js +0 -78
- package/lib/logsink/log-tracer.js +0 -40
- package/lib/logsink/sender-util.js +0 -56
- package/lib/logsink/zip/zip-send.js +0 -177
- package/lib/net/netflag.js +0 -55
- package/lib/net/receiver.js +0 -66
- package/lib/net/sender.js +0 -141
- package/lib/net/tcp-return.js +0 -18
- package/lib/net/tcp-session.js +0 -286
- package/lib/net/tcpreq-client-proxy.js +0 -70
- package/lib/net/tcprequest-mgr.js +0 -58
- package/lib/observers/cluster-observer.js +0 -22
- package/lib/observers/express-observer.js +0 -215
- package/lib/observers/file-observer.js +0 -184
- package/lib/observers/grpc-observer.js +0 -336
- package/lib/observers/memcached-observer.js +0 -56
- package/lib/observers/mongo-observer.js +0 -317
- package/lib/observers/net-observer.js +0 -77
- package/lib/observers/promise-observer.js +0 -31
- package/lib/observers/schedule-observer.js +0 -67
- package/lib/observers/stream-observer.js +0 -19
- package/lib/observers/thrift-observer.js +0 -197
- package/lib/pack/activestack-pack.js +0 -55
- package/lib/pack/apenum.js +0 -8
- package/lib/pack/errorsnap-pack.js +0 -69
- package/lib/pack/event-pack.js +0 -54
- package/lib/pack/hitmap-pack.js +0 -63
- package/lib/pack/hitmap-pack1.js +0 -152
- package/lib/pack/netstat.js +0 -15
- package/lib/pack/otype.js +0 -7
- package/lib/pack/profile-pack.js +0 -49
- package/lib/pack/realtimeuser-pack.js +0 -41
- package/lib/pack/stat-general-pack.js +0 -96
- package/lib/pack/staterror-pack.js +0 -120
- package/lib/pack/stathttpc-pack.js +0 -66
- package/lib/pack/stathttpc-rec.js +0 -78
- package/lib/pack/statremote-pack.js +0 -46
- package/lib/pack/statservice-pack.js +0 -63
- package/lib/pack/statservice-pack1.js +0 -88
- package/lib/pack/statservice-rec.js +0 -292
- package/lib/pack/statservice-rec_dep.js +0 -151
- package/lib/pack/statsql-pack.js +0 -69
- package/lib/pack/statsql-rec.js +0 -100
- package/lib/pack/statuseragent-pack.js +0 -44
- package/lib/pack/tagctr.js +0 -15
- package/lib/pack/text-pack.js +0 -50
- package/lib/pack/time-count.js +0 -25
- package/lib/pack/websocket.js +0 -15
- package/lib/pack/zip-pack.js +0 -70
- package/lib/pii/pii-item.js +0 -31
- package/lib/pii/pii-mask.js +0 -174
- package/lib/plugin/plugin-loadermanager.js +0 -57
- package/lib/plugin/plugin.js +0 -75
- package/lib/service/tx-record.js +0 -332
- package/lib/stat/stat-error.js +0 -116
- package/lib/stat/stat-httpc.js +0 -98
- package/lib/stat/stat-remote-ip.js +0 -46
- package/lib/stat/stat-remote-ipurl.js +0 -88
- package/lib/stat/stat-sql.js +0 -113
- package/lib/stat/stat-tranx.js +0 -58
- package/lib/stat/stat-tx-caller.js +0 -160
- package/lib/stat/stat-tx-domain.js +0 -111
- package/lib/stat/stat-tx-referer.js +0 -112
- package/lib/stat/stat-useragent.js +0 -48
- package/lib/stat/timingsender.js +0 -76
- package/lib/step/activestack-step.js +0 -38
- package/lib/step/dbc-step.js +0 -36
- package/lib/step/http-stepx.js +0 -67
- package/lib/step/message-step.js +0 -40
- package/lib/step/method-stepx.js +0 -45
- package/lib/step/resultset-step.js +0 -40
- package/lib/step/securemsg-step.js +0 -44
- package/lib/step/socket-step.js +0 -46
- package/lib/step/sql-stepx.js +0 -68
- package/lib/step/sqlxtype.js +0 -16
- package/lib/step/step.js +0 -66
- package/lib/step/stepenum.js +0 -54
- package/lib/topology/link.js +0 -63
- package/lib/topology/nodeinfo.js +0 -123
- package/lib/topology/status-detector.js +0 -111
- package/lib/util/anylist.js +0 -103
- package/lib/util/cardinality/hyperloglog.js +0 -106
- package/lib/util/cardinality/murmurhash.js +0 -31
- package/lib/util/cardinality/registerset.js +0 -75
- package/lib/util/errordata.js +0 -21
- package/lib/util/iputil_x.js +0 -527
- package/lib/util/kube-util.js +0 -73
- package/lib/util/paramsecurity.js +0 -80
- package/lib/util/pre-process.js +0 -13
- package/lib/util/process-seq.js +0 -166
- package/lib/util/property-util.js +0 -36
- package/lib/util/request-queue.js +0 -70
- package/lib/util/requestdouble-queue.js +0 -72
- package/lib/util/resourceprofile.js +0 -157
- package/lib/util/stop-watch.js +0 -30
- package/lib/util/system-util.js +0 -10
- package/lib/util/userid-util.js +0 -57
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
const udpSession = require('./udp_session');
|
|
2
|
+
const PacketTypeEnum = require('./packet_type_enum');
|
|
3
|
+
const PacketQueue = require('./packet_queue');
|
|
4
|
+
|
|
5
|
+
const SendType = {
|
|
6
|
+
DATAS: 1,
|
|
7
|
+
RELAY: 2
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const packetQueue = PacketQueue.getInstance();
|
|
11
|
+
let initialized = false;
|
|
12
|
+
let sendThread = null;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Send a packet asynchronously
|
|
16
|
+
* @param {number} packet_type - Type of packet from PacketTypeEnum
|
|
17
|
+
* @param {object} ctx - Trace context
|
|
18
|
+
* @param {array} datas - Array of data strings to send
|
|
19
|
+
*/
|
|
20
|
+
function send_packet(packet_type, ctx, datas = []) {
|
|
21
|
+
_initThread();
|
|
22
|
+
|
|
23
|
+
// Deep copy the context to prevent modification
|
|
24
|
+
let copiedCtx = structuredClone(ctx);
|
|
25
|
+
if (packetQueue.full()) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
packetQueue.put([SendType.DATAS, [packet_type, copiedCtx, datas]]);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Send relay pack data asynchronously
|
|
34
|
+
* @param {Buffer} packbytes - Bytes to send
|
|
35
|
+
*/
|
|
36
|
+
function send_relaypack(packbytes) {
|
|
37
|
+
_initThread();
|
|
38
|
+
|
|
39
|
+
if (packetQueue.full()) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
packetQueue.put([SendType.RELAY, packbytes]);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Start the async processing thread
|
|
48
|
+
*/
|
|
49
|
+
function startWhatapThread() {
|
|
50
|
+
// If thread is already running, don't start another
|
|
51
|
+
if (sendThread) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Start processing loop
|
|
56
|
+
const processQueue = () => {
|
|
57
|
+
const packet = packetQueue.get();
|
|
58
|
+
|
|
59
|
+
if (!packet) {
|
|
60
|
+
// No packet, wait and try again
|
|
61
|
+
setTimeout(processQueue, 100);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
const [sendType, params] = packet;
|
|
67
|
+
if (sendType === SendType.DATAS) {
|
|
68
|
+
const [packet_type, ctx, datas] = params;
|
|
69
|
+
udpSession.send_packet(packet_type, ctx, datas);
|
|
70
|
+
} else if (sendType === SendType.RELAY) {
|
|
71
|
+
const packbytes = params;
|
|
72
|
+
udpSession.send_relaypack(packbytes);
|
|
73
|
+
}
|
|
74
|
+
} catch (e) {
|
|
75
|
+
console.error("Error processing queue item:", e);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Continue processing
|
|
79
|
+
setTimeout(processQueue, 0);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// Start the processing loop
|
|
83
|
+
sendThread = setTimeout(processQueue, 0);
|
|
84
|
+
console.log("WhaTap async sender thread started");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Initialize the thread if not already initialized
|
|
89
|
+
*/
|
|
90
|
+
function _initThread() {
|
|
91
|
+
if (initialized) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Lock used to avoid multiple initializations
|
|
96
|
+
const initLock = function() {
|
|
97
|
+
if (initialized) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
try {
|
|
102
|
+
initialized = true;
|
|
103
|
+
startWhatapThread();
|
|
104
|
+
} catch (e) {
|
|
105
|
+
console.error("Error initializing thread:", e);
|
|
106
|
+
initialized = false;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
initLock();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Export functions
|
|
114
|
+
module.exports = {
|
|
115
|
+
send_packet,
|
|
116
|
+
send_relaypack,
|
|
117
|
+
startWhatapThread,
|
|
118
|
+
_initThread
|
|
119
|
+
};
|
package/lib/udp/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main entry point for UDP module
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const PacketEnum = require('./packet_enum');
|
|
6
|
+
const PacketTypeEnum = require('./packet_type_enum');
|
|
7
|
+
const ParamDef = require('./param_def');
|
|
8
|
+
const UdpSession = require('./udp_session');
|
|
9
|
+
const AsyncSender = require('./async_sender');
|
|
10
|
+
|
|
11
|
+
module.exports = {
|
|
12
|
+
PacketEnum,
|
|
13
|
+
PacketTypeEnum,
|
|
14
|
+
ParamDef,
|
|
15
|
+
UdpSession,
|
|
16
|
+
AsyncSender
|
|
17
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
class PacketEnum {
|
|
2
|
+
static get PACKET_BUFFER_SIZE() { return 48 * 1024; }
|
|
3
|
+
static get PACKET_SEND_BUFFER_SIZE() { return 64 * 1024; }
|
|
4
|
+
static get DATA_SIZE_LIMIT() { return 30 * 1024 + 1; }
|
|
5
|
+
|
|
6
|
+
static get SERVER() { return "127.0.0.1"; }
|
|
7
|
+
static get PORT() { return 6600; }
|
|
8
|
+
static get PACKET_VERSION() { return 60101; }
|
|
9
|
+
|
|
10
|
+
// PACKET_HEADER
|
|
11
|
+
static get PACKET_HEADER_TYPE_POS() { return 0; }
|
|
12
|
+
static get PACKET_HEADER_TYPE_SIZE() { return 1; }
|
|
13
|
+
|
|
14
|
+
static get PACKET_HEADER_VERSION_POS() { return 1; }
|
|
15
|
+
static get PACKET_HEADER_VERSION_SIZE() { return 4; }
|
|
16
|
+
|
|
17
|
+
static get PACKET_HEADER_LEN_POS() { return 5; }
|
|
18
|
+
static get PACKET_HEADER_LEN_SIZE() { return 4; }
|
|
19
|
+
|
|
20
|
+
// PACKET_BODY
|
|
21
|
+
static get PACKET_BODY_ID_POS() { return 9; }
|
|
22
|
+
static get PACKET_BODY_ID_SIZE() { return 8; }
|
|
23
|
+
|
|
24
|
+
static get PACKET_BODY_START_TIME_POS() { return 17; }
|
|
25
|
+
static get PACKET_BODY_START_TIME_SIZE() { return 8; }
|
|
26
|
+
|
|
27
|
+
static get PACKET_BODY_ELAPSED_POS() { return 25; }
|
|
28
|
+
static get PACKET_BODY_ELAPSED_SIZE() { return 4; }
|
|
29
|
+
|
|
30
|
+
static get PACKET_BODY_CPU_POS() { return 29; }
|
|
31
|
+
static get PACKET_BODY_CPU_SIZE() { return 8; }
|
|
32
|
+
|
|
33
|
+
static get PACKET_BODY_MEMORY_POS() { return 37; }
|
|
34
|
+
static get PACKET_BODY_MEMORY_SIZE() { return 8; }
|
|
35
|
+
|
|
36
|
+
static get PACKET_BODY_THREAD_ID_POS() { return 45; }
|
|
37
|
+
static get PACKET_BODY_THREAD_ID_SIZE() { return 8; }
|
|
38
|
+
|
|
39
|
+
static get PACKET_BODY_TRACE_DATA_POS() { return 53; }
|
|
40
|
+
|
|
41
|
+
// PACKET_SIZE
|
|
42
|
+
static get PACKET_HEADER_SIZE() {
|
|
43
|
+
return this.PACKET_HEADER_TYPE_SIZE + this.PACKET_HEADER_VERSION_SIZE + this.PACKET_HEADER_LEN_SIZE;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static get PACKET_BODY_REQUIRED_SIZE() {
|
|
47
|
+
return this.PACKET_BODY_ID_SIZE + this.PACKET_BODY_START_TIME_SIZE + this.PACKET_BODY_ELAPSED_SIZE +
|
|
48
|
+
this.PACKET_BODY_CPU_SIZE + this.PACKET_BODY_MEMORY_SIZE;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = PacketEnum;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PacketQueue - Queue implementation for async sending packets
|
|
3
|
+
* Implemented as a singleton to ensure only one queue exists.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
class PacketQueue {
|
|
7
|
+
constructor(maxSize = 1000) {
|
|
8
|
+
// Singleton pattern: If instance exists, return it
|
|
9
|
+
if (PacketQueue.instance) {
|
|
10
|
+
return PacketQueue.instance;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Initialize queue
|
|
14
|
+
this.queue = [];
|
|
15
|
+
this.maxSize = maxSize;
|
|
16
|
+
|
|
17
|
+
// Store the instance
|
|
18
|
+
PacketQueue.instance = this;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
put(item) {
|
|
22
|
+
if (this.queue.length < this.maxSize) {
|
|
23
|
+
this.queue.push(item);
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
get() {
|
|
30
|
+
if (this.queue.length > 0) {
|
|
31
|
+
return this.queue.shift();
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
full() {
|
|
37
|
+
return this.queue.length >= this.maxSize;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
empty() {
|
|
41
|
+
return this.queue.length === 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
size() {
|
|
45
|
+
return this.queue.length;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
clear() {
|
|
49
|
+
this.queue = [];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Get the singleton instance
|
|
54
|
+
* @param {number} maxSize - Maximum size of the queue (only used if instance doesn't exist)
|
|
55
|
+
* @returns {PacketQueue} - The singleton instance
|
|
56
|
+
*/
|
|
57
|
+
static getInstance(maxSize = 1000) {
|
|
58
|
+
if (!PacketQueue.instance) {
|
|
59
|
+
PacketQueue.instance = new PacketQueue(maxSize);
|
|
60
|
+
}
|
|
61
|
+
return PacketQueue.instance;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Initialize the static instance property
|
|
66
|
+
PacketQueue.instance = null;
|
|
67
|
+
|
|
68
|
+
// Export the class
|
|
69
|
+
module.exports = PacketQueue;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
class PacketTypeEnum {
|
|
2
|
+
static get TX_BLANK() { return 0; }
|
|
3
|
+
static get TX_START() { return 1; }
|
|
4
|
+
static get TX_DB_CONN() { return 2; }
|
|
5
|
+
static get TX_DB_FETCH() { return 3; }
|
|
6
|
+
static get TX_SQL() { return 4; }
|
|
7
|
+
static get TX_SQL_START() { return 5; }
|
|
8
|
+
static get TX_SQL_END() { return 6; }
|
|
9
|
+
|
|
10
|
+
static get TX_HTTPC() { return 7; }
|
|
11
|
+
static get TX_HTTPC_START() { return 8; }
|
|
12
|
+
static get TX_HTTPC_END() { return 9; }
|
|
13
|
+
|
|
14
|
+
static get TX_ERROR() { return 10; }
|
|
15
|
+
static get TX_MSG() { return 11; }
|
|
16
|
+
static get TX_METHOD() { return 12; }
|
|
17
|
+
|
|
18
|
+
static get TX_SECURE_MSG() { return 13; }
|
|
19
|
+
static get TX_WEB_SOCKET() { return 16; }
|
|
20
|
+
|
|
21
|
+
static get TX_END() { return 255; }
|
|
22
|
+
|
|
23
|
+
static get TX_PARAM() { return 30; }
|
|
24
|
+
static get ACTIVE_STACK() { return 40; }
|
|
25
|
+
static get ACTIVE_STATS() { return 41; }
|
|
26
|
+
static get DBCONN_POOL() { return 42; }
|
|
27
|
+
|
|
28
|
+
static get EVENT() { return 50; }
|
|
29
|
+
|
|
30
|
+
static get RELAY_PACK() { return 244; }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
module.exports = PacketTypeEnum;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
class ParamDef {
|
|
2
|
+
static get KEEPALIVE() { return 1; }
|
|
3
|
+
static get AGENT_BOOT_ENV() { return 2; }
|
|
4
|
+
static get CONFIGURE_UPDATE() { return 3; }
|
|
5
|
+
static get CONFIGURE_GET() { return 4; }
|
|
6
|
+
static get COMPO_VERSIONS() { return 5; }
|
|
7
|
+
static get THREAD_LIST() { return 7; }
|
|
8
|
+
static get THREAD_DETAIL() { return 8; }
|
|
9
|
+
static get GET_ACTIVE_STACK() { return 9; }
|
|
10
|
+
static get HEAP_HISTO() { return 10; }
|
|
11
|
+
static get LOADED_CLASS_LIST() { return 11; }
|
|
12
|
+
static get GET_ENV() { return 12; }
|
|
13
|
+
static get SYSTEM_GC() { return 13; }
|
|
14
|
+
static get SET_CONFIG() { return 14; }
|
|
15
|
+
static get OPEN_SOCKET_LIST() { return 15; }
|
|
16
|
+
static get LOADED_CLASS_DETAIL() { return 16; }
|
|
17
|
+
static get LOADED_CLASS_REDEFINE() { return 17; }
|
|
18
|
+
static get AGENT_JAR_LIST() { return 18; }
|
|
19
|
+
static get AGENT_JAR_SAVE() { return 19; }
|
|
20
|
+
static get AGENT_JAR_DELETE() { return 20; }
|
|
21
|
+
static get RESET_STRING_SENT_MARK() { return 21; }
|
|
22
|
+
static get AGENT_LOG_LIST() { return 22; }
|
|
23
|
+
static get AGENT_LOG_READ() { return 23; }
|
|
24
|
+
static get THREAD_CONTROL() { return 24; }
|
|
25
|
+
static get GET_ACTIVE_TRANSACTION_LIST() { return 25; }
|
|
26
|
+
static get GET_ACTIVE_TRANSACTION_DETAIL() { return 26; }
|
|
27
|
+
static get GET_TOPOLOGY() { return 27; }
|
|
28
|
+
static get INFRA_NET_STAT() { return 28; }
|
|
29
|
+
static get INFRA_PS_EF() { return 29; }
|
|
30
|
+
static get INFRA_DOCKER_LIST() { return 30; }
|
|
31
|
+
static get INFRA_REMOTE_CMD() { return 33; }
|
|
32
|
+
static get INFRA_PEER_LIST() { return 34; }
|
|
33
|
+
static get INFRA_AGENT_UPDATE() { return 36; }
|
|
34
|
+
static get AGENT_DUMP_LIST() { return 31; }
|
|
35
|
+
static get AGENT_DUMP_READ() { return 32; }
|
|
36
|
+
static get AGENT_STAT() { return 35; }
|
|
37
|
+
static get JVM_THREAD_DUMP() { return 37; }
|
|
38
|
+
static get JVM_HEAP_DUMP() { return 38; }
|
|
39
|
+
static get KUBENETES() { return 39; }
|
|
40
|
+
static get GET_ACTIVE_STATS() { return 40; }
|
|
41
|
+
static get GET_DBCONN_POOL() { return 41; }
|
|
42
|
+
static get MODULE_DEPENDENCY() { return 101; }
|
|
43
|
+
static get DBX_INFO() { return 201; }
|
|
44
|
+
static get DBX_SETTINGS() { return 202; }
|
|
45
|
+
static get DBX_USER_SCRIPT() { return 207; }
|
|
46
|
+
static get DBX_SCRIPT_LIST() { return 208; }
|
|
47
|
+
static get DBX_SCRIPT_SQL() { return 209; }
|
|
48
|
+
static get DBX_KILL_SESSION() { return 210; }
|
|
49
|
+
static get DBX_GET_ALERT() { return 211; }
|
|
50
|
+
static get DBX_SET_ALERT() { return 212; }
|
|
51
|
+
static get DBX_PLAN() { return 213; }
|
|
52
|
+
static get DBX_SESSION_LIST() { return 214; }
|
|
53
|
+
static get DBX_SET_CPUCORES() { return 215; }
|
|
54
|
+
static get DBX_SESSION_STAT() { return 203; }
|
|
55
|
+
static get DBX_SESSION_EVENT() { return 204; }
|
|
56
|
+
static get DBX_TOPSTAT() { return 205; }
|
|
57
|
+
static get DBX_TOPEVENT() { return 206; }
|
|
58
|
+
static get CONFIG_DBC() { return 301; }
|
|
59
|
+
static get METHOD_PERF_STAT() { return 302; }
|
|
60
|
+
static get BLOCKING_DETECT() { return 303; }
|
|
61
|
+
static get CW_INFO() { return 401; }
|
|
62
|
+
static get CW_EVENTS() { return 402; }
|
|
63
|
+
static get CW_CREDENTIAL() { return 403; }
|
|
64
|
+
static get CW_REGIONS() { return 404; }
|
|
65
|
+
static get CW_METRIC_NAMES() { return 405; }
|
|
66
|
+
static get CW_AWS_RESOURCE_IDS() { return 406; }
|
|
67
|
+
static get CW_STATISTICS() { return 407; }
|
|
68
|
+
static get CW_UNITS() { return 408; }
|
|
69
|
+
static get CW_METRICS() { return 409; }
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
module.exports = ParamDef;
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JavaScript implementation of Python's UdpSession
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const dgram = require('dgram');
|
|
6
|
+
const os = require('os');
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
const PacketEnum = require('./packet_enum');
|
|
11
|
+
const PacketTypeEnum = require('./packet_type_enum');
|
|
12
|
+
const ParamDef = require('./param_def');
|
|
13
|
+
const DataOutputX = require('../io/data-outputx');
|
|
14
|
+
const TraceContextManager = require('../trace/trace-context-manager');
|
|
15
|
+
const PackageCtrHelper = require('../../lib/control/packagectr-helper');
|
|
16
|
+
const ActiveTransaction = require('../counter/task/activetransaction');
|
|
17
|
+
const GCAction = require('../system/gc-action');
|
|
18
|
+
const DataOuputX = require('../../lib/io/data-outputx');
|
|
19
|
+
|
|
20
|
+
class UdpSession {
|
|
21
|
+
constructor() {
|
|
22
|
+
this.socket = null;
|
|
23
|
+
this.bufferArr = [];
|
|
24
|
+
this.threadLock = false; // Simple lock simulation
|
|
25
|
+
this.readTimeout = 5000; // 5 seconds
|
|
26
|
+
this.serverHost = PacketEnum.SERVER;
|
|
27
|
+
this.serverPort = PacketEnum.PORT;
|
|
28
|
+
this.isConnected = false; // connected-UDP 여부
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Initialize UDP socket
|
|
33
|
+
*/
|
|
34
|
+
udp(config) {
|
|
35
|
+
const self = this;
|
|
36
|
+
const conf = config || {};
|
|
37
|
+
|
|
38
|
+
// Close existing socket if open
|
|
39
|
+
if (self.socket) {
|
|
40
|
+
try {
|
|
41
|
+
self.socket.close();
|
|
42
|
+
} catch (e) {
|
|
43
|
+
console.error("Error closing UDP socket:", e);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Create UDP socket
|
|
48
|
+
self.socket = dgram.createSocket('udp4');
|
|
49
|
+
|
|
50
|
+
// Check if Unix socket is configured
|
|
51
|
+
const whatapHome = process.env.WHATAP_HOME;
|
|
52
|
+
|
|
53
|
+
if (conf.unix_socket_enabled === true && whatapHome) {
|
|
54
|
+
// Unix socket not directly supported in Node.js dgram
|
|
55
|
+
// We'll use the regular UDP socket with the configured server and port
|
|
56
|
+
console.log("Unix socket not supported in Node.js, using UDP instead");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Configure server info
|
|
60
|
+
self.serverHost = conf.net_udp_host || PacketEnum.SERVER;
|
|
61
|
+
self.serverPort = parseInt(conf.net_udp_port || PacketEnum.PORT);
|
|
62
|
+
|
|
63
|
+
// console.log(`UDP initialized with server ${self.serverHost}:${self.serverPort}`);
|
|
64
|
+
|
|
65
|
+
// "connected UDP" 로 전환: lsof에서 peer가 보이도록
|
|
66
|
+
self.socket.connect(self.serverPort, self.serverHost, () => {
|
|
67
|
+
self.isConnected = true;
|
|
68
|
+
// 참고: UDP라 실제 연결 성사 여부 확인 절차는 없음 (peer 고정만 됨)
|
|
69
|
+
// 필요시 ephemeral 로컬 포트를 고정하고 싶으면 bind 후 connect 실행
|
|
70
|
+
// self.socket.bind(0, '127.0.0.1', () => self.socket.connect(...));
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Set up error handling
|
|
74
|
+
self.socket.on('error', function (err) {
|
|
75
|
+
console.error("UDP socket error:", err);
|
|
76
|
+
});
|
|
77
|
+
self.socket.on('close', () => { self.isConnected = false; });
|
|
78
|
+
|
|
79
|
+
self.socket.on('message', function (msg, rinfo) {
|
|
80
|
+
self.handleMessage(msg, rinfo);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
return self.socket;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Handle incoming UDP messages
|
|
88
|
+
*/
|
|
89
|
+
handleMessage(msg, rinfo) {
|
|
90
|
+
const self = this;
|
|
91
|
+
try {
|
|
92
|
+
const received = msg.toString();
|
|
93
|
+
const parts = received.split(',');
|
|
94
|
+
|
|
95
|
+
if (parts.length >= 2) {
|
|
96
|
+
const paramId = parseInt(parts[0]);
|
|
97
|
+
const request = parts[1];
|
|
98
|
+
const extra = parts.length > 2 ? parts[2] : '';
|
|
99
|
+
|
|
100
|
+
self.handle(paramId, request, extra);
|
|
101
|
+
}
|
|
102
|
+
} catch (e) {
|
|
103
|
+
console.error("Error handling UDP message:", e);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Handle received requests
|
|
109
|
+
*/
|
|
110
|
+
handle(paramId, request, extra) {
|
|
111
|
+
const self = this;
|
|
112
|
+
if(!paramId)
|
|
113
|
+
return;
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
let threadId = 0;
|
|
117
|
+
let pid = 0;
|
|
118
|
+
|
|
119
|
+
if (extra) {
|
|
120
|
+
const extraData = extra.replace(' ', ', ').split(', ');
|
|
121
|
+
if (extraData.length > 1) {
|
|
122
|
+
threadId = parseInt(extraData[1]);
|
|
123
|
+
// In Node.js there's no direct thread ID, so using PID
|
|
124
|
+
pid = process.pid;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
let data = '';
|
|
129
|
+
let datas = [String(paramId), request];
|
|
130
|
+
|
|
131
|
+
if (paramId === ParamDef.SYSTEM_GC){
|
|
132
|
+
const gcAction = new GCAction();
|
|
133
|
+
const p = gcAction.execSystemGC();
|
|
134
|
+
|
|
135
|
+
const bout = new DataOuputX();
|
|
136
|
+
bout.writePack(p, null);
|
|
137
|
+
const packbytes = bout.toByteArray();
|
|
138
|
+
|
|
139
|
+
self.send_relaypack(packbytes)
|
|
140
|
+
} else if (paramId === ParamDef.MODULE_DEPENDENCY) {
|
|
141
|
+
const dependencies = PackageCtrHelper.getDependencies();
|
|
142
|
+
// result format: "axios x.x.x, whatap x.x.x, etc x,x,x"
|
|
143
|
+
const result = Object.entries(dependencies)
|
|
144
|
+
.map(([name, version]) => `${name} ${version}`)
|
|
145
|
+
.join(', ');
|
|
146
|
+
datas.push(result);
|
|
147
|
+
self.send_packet(PacketTypeEnum.TX_PARAM, null, datas)
|
|
148
|
+
} else if (paramId === ParamDef.GET_ACTIVE_STATS) {
|
|
149
|
+
const stats = ActiveTransaction.getActiveStats();
|
|
150
|
+
datas = [stats.join(',')];
|
|
151
|
+
self.send_packet(PacketTypeEnum.ACTIVE_STATS, null, datas);
|
|
152
|
+
}
|
|
153
|
+
return;
|
|
154
|
+
} catch (e) {
|
|
155
|
+
console.error("Error in handle method:", e);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Send a packet with trace data
|
|
161
|
+
* @param {number} packet_type - Type of packet from PacketTypeEnum
|
|
162
|
+
* @param {object} ctx - Trace context
|
|
163
|
+
* @param {array} datas - Array of data strings to send
|
|
164
|
+
*/
|
|
165
|
+
send_packet(packet_type, ctx, datas = []) {
|
|
166
|
+
const self = this;
|
|
167
|
+
|
|
168
|
+
try {
|
|
169
|
+
// Calculate total buffer size
|
|
170
|
+
let totalSize = 0;
|
|
171
|
+
for (let i = 0; i < self.bufferArr.length; i++) {
|
|
172
|
+
totalSize += self.bufferArr[i].length;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Add estimated size of new data
|
|
176
|
+
let newDataSize = PacketEnum.PACKET_BODY_REQUIRED_SIZE + 1;
|
|
177
|
+
for (let i = 0; i < datas.length; i++) {
|
|
178
|
+
const data = String(datas[i]);
|
|
179
|
+
newDataSize += Buffer.byteLength(data, 'utf8') + 2; // +2 for UTF encoding length
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (totalSize + newDataSize > PacketEnum.PACKET_BUFFER_SIZE) {
|
|
183
|
+
self.send(packet_type, ctx);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (!datas || datas.length === 0) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Create packet
|
|
191
|
+
const dout = new DataOutputX();
|
|
192
|
+
var startHeaderBufferSize = dout.size();
|
|
193
|
+
|
|
194
|
+
// Write header
|
|
195
|
+
dout.writeByte(packet_type);
|
|
196
|
+
dout.writeInt(PacketEnum.PACKET_VERSION);
|
|
197
|
+
dout.writeInt(0); // Placeholder for length
|
|
198
|
+
|
|
199
|
+
const startBodyBufferSize = dout.size();
|
|
200
|
+
|
|
201
|
+
// Write body if context exists
|
|
202
|
+
if (ctx) {
|
|
203
|
+
dout.writeLong(ctx.id);
|
|
204
|
+
dout.writeLong(ctx.start_time);
|
|
205
|
+
dout.writeInt(ctx.elapsed);
|
|
206
|
+
dout.writeLong(Math.floor(Date.now() / 1000));
|
|
207
|
+
dout.writeLong(0);
|
|
208
|
+
dout.writeInt(process.pid);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Write data with length limit check
|
|
212
|
+
let diff = PacketEnum.PACKET_BUFFER_SIZE - totalSize - (PacketEnum.PACKET_BODY_REQUIRED_SIZE + 1);
|
|
213
|
+
|
|
214
|
+
for (let i = 0; i < datas.length; i++) {
|
|
215
|
+
let data = String(datas[i]).slice(0, PacketEnum.DATA_SIZE_LIMIT);
|
|
216
|
+
diff -= (Buffer.byteLength(data, 'utf8') + 2); // Account for UTF encoding overhead
|
|
217
|
+
|
|
218
|
+
if (diff < 0) {
|
|
219
|
+
data = ' ';
|
|
220
|
+
console.log('message too long.');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
dout.writeUTF(data);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Update length in header
|
|
227
|
+
dout.writeToPos(
|
|
228
|
+
startHeaderBufferSize + PacketEnum.PACKET_HEADER_LEN_POS,
|
|
229
|
+
dout.size() - startBodyBufferSize
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
// Add to buffer array (simulating thread lock)
|
|
233
|
+
if (!self.threadLock) {
|
|
234
|
+
self.threadLock = true;
|
|
235
|
+
self.bufferArr.push(dout.toByteArray());
|
|
236
|
+
self.threadLock = false;
|
|
237
|
+
|
|
238
|
+
// Flush in certain conditions
|
|
239
|
+
if (!ctx || packet_type === PacketTypeEnum.TX_START || packet_type === PacketTypeEnum.TX_END) {
|
|
240
|
+
self.send(packet_type, ctx);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
} catch (e) {
|
|
244
|
+
console.error("Error sending packet:", e);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Send the buffered packets
|
|
250
|
+
*/
|
|
251
|
+
send(packet_type, ctx) {
|
|
252
|
+
const self = this;
|
|
253
|
+
|
|
254
|
+
if (!self.socket || self.bufferArr.length === 0) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
try {
|
|
259
|
+
// Combine all buffers
|
|
260
|
+
const sendbuf = Buffer.concat(self.bufferArr);
|
|
261
|
+
|
|
262
|
+
// Send via UDP
|
|
263
|
+
const cb = (err) => {
|
|
264
|
+
if (err) {
|
|
265
|
+
console.error("Failed to send UDP packet:", err);
|
|
266
|
+
// Consider reinitializing UDP connection on error
|
|
267
|
+
self.udp();
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
if (self.isConnected) {
|
|
272
|
+
// connected UDP: 목적지 인자 없이 전송
|
|
273
|
+
self.socket.send(sendbuf, cb);
|
|
274
|
+
} else {
|
|
275
|
+
// fallback (미연결 상태)
|
|
276
|
+
self.socket.send(sendbuf, 0, sendbuf.length, self.serverPort, self.serverHost, cb);
|
|
277
|
+
}
|
|
278
|
+
} catch (e) {
|
|
279
|
+
console.error("Error in send method:", e);
|
|
280
|
+
} finally {
|
|
281
|
+
// Clear buffer array
|
|
282
|
+
self.bufferArr = [];
|
|
283
|
+
|
|
284
|
+
// Handle context cleanup for TX_END
|
|
285
|
+
if (packet_type === PacketTypeEnum.TX_END && ctx && ctx.id) {
|
|
286
|
+
if (ctx.id) {
|
|
287
|
+
TraceContextManager.end(ctx.id)
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Send relay pack data
|
|
295
|
+
*/
|
|
296
|
+
send_relaypack(packbytes) {
|
|
297
|
+
const self = this;
|
|
298
|
+
const packet_type = PacketTypeEnum.RELAY_PACK;
|
|
299
|
+
|
|
300
|
+
try {
|
|
301
|
+
// Check buffer size and flush if needed
|
|
302
|
+
let totalSize = 0;
|
|
303
|
+
for (let i = 0; i < self.bufferArr.length; i++) {
|
|
304
|
+
totalSize += self.bufferArr[i].length;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
if (totalSize + PacketEnum.PACKET_BODY_REQUIRED_SIZE + 1 > PacketEnum.PACKET_BUFFER_SIZE) {
|
|
308
|
+
self.send(packet_type, null);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (!packbytes) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Create packet
|
|
316
|
+
const dout = new DataOutputX();
|
|
317
|
+
|
|
318
|
+
// Write header
|
|
319
|
+
dout.writeByte(packet_type);
|
|
320
|
+
dout.writeInt(PacketEnum.PACKET_VERSION);
|
|
321
|
+
dout.writeIntBytes(packbytes);
|
|
322
|
+
|
|
323
|
+
// Add to buffer
|
|
324
|
+
if (!self.threadLock) {
|
|
325
|
+
self.threadLock = true;
|
|
326
|
+
self.bufferArr.push(dout.toByteArray());
|
|
327
|
+
self.threadLock = false;
|
|
328
|
+
}
|
|
329
|
+
} catch (e) {
|
|
330
|
+
console.error("Error sending relay pack:", e);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Export a singleton instance
|
|
336
|
+
module.exports = new UdpSession();
|