whatap 1.0.3 → 1.0.4
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/core/agent.js
CHANGED
|
@@ -32,7 +32,8 @@ var Interceptor = require('./interceptor').Interceptor,
|
|
|
32
32
|
// GRpcObserver = require('../observers/grpc-observer').GRpcObserver,
|
|
33
33
|
ApolloObserver = require('../observers/apollo-server-observer').ApolloServerObserver,
|
|
34
34
|
PrismaObserver = require('../observers/prisma-observer').PrismaObserver,
|
|
35
|
-
OracleObserver = require('../observers/oracle-observer').OracleObserver
|
|
35
|
+
OracleObserver = require('../observers/oracle-observer').OracleObserver,
|
|
36
|
+
CustomMethodObserver = require('../observers/custom-method-observer').CustomMethodObserver;
|
|
36
37
|
|
|
37
38
|
|
|
38
39
|
var Configuration = require('./../conf/configure'),
|
|
@@ -112,13 +113,13 @@ NodeAgent.prototype.isNodejsAgentProcess = function(pid) {
|
|
|
112
113
|
let processCommand = '';
|
|
113
114
|
|
|
114
115
|
if (platform === 'linux') {
|
|
115
|
-
// On Linux, use /proc filesystem
|
|
116
|
+
// On Linux, use /proc filesystem
|
|
116
117
|
try {
|
|
117
118
|
const cmdlineFile = path.join('/proc', pid.toString(), 'cmdline');
|
|
118
119
|
if (fs.existsSync(cmdlineFile)) {
|
|
119
120
|
processCommand = fs.readFileSync(cmdlineFile, 'utf8');
|
|
120
121
|
// Log for debugging
|
|
121
|
-
Logger.print("WHATAP-
|
|
122
|
+
Logger.print("WHATAP-001", `Process ${pid} command line: ${processCommand}`, false);
|
|
122
123
|
}
|
|
123
124
|
} catch (e) {
|
|
124
125
|
Logger.printError("WHATAP-101", "Error reading Linux process info", e, false);
|
|
@@ -128,7 +129,7 @@ NodeAgent.prototype.isNodejsAgentProcess = function(pid) {
|
|
|
128
129
|
// On macOS, use ps command
|
|
129
130
|
try {
|
|
130
131
|
processCommand = child_process.execSync(`ps -p ${pid} -o command=`, { encoding: 'utf8' }).trim();
|
|
131
|
-
Logger.print("WHATAP-
|
|
132
|
+
Logger.print("WHATAP-001", `Process ${pid} command line: ${processCommand}`, false);
|
|
132
133
|
} catch (e) {
|
|
133
134
|
Logger.printError("WHATAP-102", "Error reading MacOS process info", e, false);
|
|
134
135
|
return false;
|
|
@@ -141,7 +142,7 @@ NodeAgent.prototype.isNodejsAgentProcess = function(pid) {
|
|
|
141
142
|
const match = output.match(/"([^"]+)"/);
|
|
142
143
|
if (match && match[1]) {
|
|
143
144
|
processCommand = match[1];
|
|
144
|
-
Logger.print("WHATAP-
|
|
145
|
+
Logger.print("WHATAP-001", `Process ${pid} command line: ${processCommand}`, false);
|
|
145
146
|
}
|
|
146
147
|
} catch (e) {
|
|
147
148
|
Logger.printError("WHATAP-103", "Error reading Windows process info", e, false);
|
|
@@ -151,19 +152,19 @@ NodeAgent.prototype.isNodejsAgentProcess = function(pid) {
|
|
|
151
152
|
// On other platforms, try generic ps command
|
|
152
153
|
try {
|
|
153
154
|
processCommand = child_process.execSync(`ps -p ${pid} -o command=`, { encoding: 'utf8' }).trim();
|
|
154
|
-
Logger.print("WHATAP-
|
|
155
|
+
Logger.print("WHATAP-001", `Process ${pid} command line: ${processCommand}`, false);
|
|
155
156
|
} catch (e) {
|
|
156
157
|
Logger.printError("WHATAP-104", "Error reading other os process info", e, false);
|
|
157
158
|
return false;
|
|
158
159
|
}
|
|
159
160
|
}
|
|
160
161
|
|
|
161
|
-
// Check if the command contains the agent name
|
|
162
|
+
// Check if the command contains the agent name
|
|
162
163
|
const isAgentProcess = processCommand.indexOf(AGENT_NAME) >= 0;
|
|
163
|
-
Logger.print("WHATAP-
|
|
164
|
+
Logger.print("WHATAP-002", `Process ${pid} is ${isAgentProcess ? '' : 'not '}a WhaTap agent`, false);
|
|
164
165
|
return isAgentProcess;
|
|
165
166
|
} catch (e) {
|
|
166
|
-
Logger.printError("WHATAP-
|
|
167
|
+
Logger.printError("WHATAP-003", "Error in isNodejsAgentProcess", e, false);
|
|
167
168
|
return false;
|
|
168
169
|
}
|
|
169
170
|
};
|
|
@@ -176,7 +177,7 @@ NodeAgent.prototype.readPidFile = function(home, fileName) {
|
|
|
176
177
|
return fs.readFileSync(filePath, 'utf8').trim();
|
|
177
178
|
}
|
|
178
179
|
} catch (e) {
|
|
179
|
-
Logger.printError("WHATAP-
|
|
180
|
+
Logger.printError("WHATAP-004", "Error reading PID file", e, false);
|
|
180
181
|
}
|
|
181
182
|
return '';
|
|
182
183
|
};
|
|
@@ -188,8 +189,8 @@ NodeAgent.prototype.writeToFile = function(home, fileName, value) {
|
|
|
188
189
|
fs.writeFileSync(filePath, value);
|
|
189
190
|
return true;
|
|
190
191
|
} catch (e) {
|
|
191
|
-
Logger.printError("WHATAP-
|
|
192
|
-
Logger.print("WHATAP-
|
|
192
|
+
Logger.printError("WHATAP-005", `Error writing to file ${fileName}`, e, false);
|
|
193
|
+
Logger.print("WHATAP-006", `Try to execute command: \`sudo chmod -R 777 $WHATAP_HOME\``, false);
|
|
193
194
|
return false;
|
|
194
195
|
}
|
|
195
196
|
};
|
|
@@ -206,7 +207,7 @@ NodeAgent.prototype.isGoAgentRunning = function(pid) {
|
|
|
206
207
|
parseInt(pid) - 1
|
|
207
208
|
];
|
|
208
209
|
|
|
209
|
-
Logger.print("WHATAP-
|
|
210
|
+
Logger.print("WHATAP-007", `Checking PIDs: ${pidsToCheck.join(', ')} (original: ${pid})`, false);
|
|
210
211
|
|
|
211
212
|
for (const pidToCheck of pidsToCheck) {
|
|
212
213
|
try {
|
|
@@ -215,7 +216,7 @@ NodeAgent.prototype.isGoAgentRunning = function(pid) {
|
|
|
215
216
|
|
|
216
217
|
// whatap_nodejs 프로세스인지 확인
|
|
217
218
|
if (this.isNodejsAgentProcess(pidToCheck)) {
|
|
218
|
-
Logger.print("WHATAP-
|
|
219
|
+
Logger.print("WHATAP-008",
|
|
219
220
|
`Found agent process at PID ${pidToCheck} (original PID in file: ${pid})`,
|
|
220
221
|
false);
|
|
221
222
|
return true;
|
|
@@ -228,16 +229,16 @@ NodeAgent.prototype.isGoAgentRunning = function(pid) {
|
|
|
228
229
|
}
|
|
229
230
|
}
|
|
230
231
|
|
|
231
|
-
Logger.print("WHATAP-
|
|
232
|
+
Logger.print("WHATAP-009", `No agent process found for PID ${pid} or adjacent PIDs`, false);
|
|
232
233
|
return false;
|
|
233
234
|
} catch (e) {
|
|
234
|
-
Logger.printError("WHATAP-
|
|
235
|
+
Logger.printError("WHATAP-010", "Error checking if agent is running", e, false);
|
|
235
236
|
return false;
|
|
236
237
|
}
|
|
237
238
|
};
|
|
238
239
|
|
|
239
240
|
/**
|
|
240
|
-
* Read content from a file
|
|
241
|
+
* Read content from a file
|
|
241
242
|
* @param {string} home - Environment variable name for home directory
|
|
242
243
|
* @param {string} fileName - Name of the file to read
|
|
243
244
|
* @returns {string} - Content of the file, or empty string on error
|
|
@@ -249,13 +250,13 @@ NodeAgent.prototype.readFile = function(home, fileName) {
|
|
|
249
250
|
return fs.readFileSync(filePath, 'utf8').toString().trim();
|
|
250
251
|
}
|
|
251
252
|
} catch (e) {
|
|
252
|
-
Logger.printError("WHATAP-
|
|
253
|
+
Logger.printError("WHATAP-011", `Error reading file ${fileName}`, e, false);
|
|
253
254
|
}
|
|
254
255
|
return '';
|
|
255
256
|
};
|
|
256
257
|
|
|
257
258
|
/**
|
|
258
|
-
* Write content to a file
|
|
259
|
+
* Write content to a file
|
|
259
260
|
* @param {string} home - Environment variable name for home directory
|
|
260
261
|
* @param {string} fileName - Name of the file to write
|
|
261
262
|
* @param {string} value - Content to write to the file
|
|
@@ -267,14 +268,14 @@ NodeAgent.prototype.writeFile = function(home, fileName, value) {
|
|
|
267
268
|
fs.writeFileSync(filePath, value);
|
|
268
269
|
return true;
|
|
269
270
|
} catch (e) {
|
|
270
|
-
Logger.printError("WHATAP-
|
|
271
|
-
Logger.print("WHATAP-
|
|
271
|
+
Logger.printError("WHATAP-012", `Error writing to file ${fileName}`, e, false);
|
|
272
|
+
Logger.print("WHATAP-013", `Try to execute command: \`sudo chmod -R 777 $WHATAP_HOME\``, false);
|
|
272
273
|
return false;
|
|
273
274
|
}
|
|
274
275
|
};
|
|
275
276
|
|
|
276
277
|
/**
|
|
277
|
-
* Find whatap.conf file by searching directories
|
|
278
|
+
* Find whatap.conf file by searching directories
|
|
278
279
|
* @returns {string|null} - Path to whatap.conf or null if not found
|
|
279
280
|
*/
|
|
280
281
|
NodeAgent.prototype.findWhatapConf = function() {
|
|
@@ -303,7 +304,7 @@ NodeAgent.prototype.findWhatapConf = function() {
|
|
|
303
304
|
};
|
|
304
305
|
|
|
305
306
|
/**
|
|
306
|
-
* Open and lock the port file
|
|
307
|
+
* Open and lock the port file
|
|
307
308
|
* @param {string} filepath - Path to the lock file
|
|
308
309
|
* @returns {object|null} - File descriptor or null if failed
|
|
309
310
|
*/
|
|
@@ -313,7 +314,7 @@ NodeAgent.prototype.openPortFile = function(filepath) {
|
|
|
313
314
|
let fileHandle = null;
|
|
314
315
|
let attempts = 0;
|
|
315
316
|
|
|
316
|
-
// Try to open the file
|
|
317
|
+
// Try to open the file
|
|
317
318
|
while (!fileHandle && attempts < 100) {
|
|
318
319
|
try {
|
|
319
320
|
// Try to open file for reading and writing
|
|
@@ -329,10 +330,10 @@ NodeAgent.prototype.openPortFile = function(filepath) {
|
|
|
329
330
|
fileHandle = fs.openSync(filepath, 'w+');
|
|
330
331
|
}
|
|
331
332
|
} catch (e) {
|
|
332
|
-
Logger.printError("WHATAP-
|
|
333
|
+
Logger.printError("WHATAP-014", `Error opening port file (attempt ${attempts})`, e, false);
|
|
333
334
|
}
|
|
334
335
|
|
|
335
|
-
//
|
|
336
|
+
// Add a delay after 50 attempts
|
|
336
337
|
if (attempts > 50) {
|
|
337
338
|
setTimeout(() => {}, 100); // 0.1 second delay
|
|
338
339
|
}
|
|
@@ -346,7 +347,7 @@ NodeAgent.prototype.openPortFile = function(filepath) {
|
|
|
346
347
|
properLock.lockSync(filepath);
|
|
347
348
|
return { fileHandle, filepath };
|
|
348
349
|
} catch (e) {
|
|
349
|
-
Logger.printError("WHATAP-
|
|
350
|
+
Logger.printError("WHATAP-015", "Failed to lock port file", e, false);
|
|
350
351
|
try {
|
|
351
352
|
fs.closeSync(fileHandle);
|
|
352
353
|
} catch (closeErr) {}
|
|
@@ -357,7 +358,7 @@ NodeAgent.prototype.openPortFile = function(filepath) {
|
|
|
357
358
|
};
|
|
358
359
|
|
|
359
360
|
/**
|
|
360
|
-
* Get available port number for the agent
|
|
361
|
+
* Get available port number for the agent
|
|
361
362
|
* @param {number} defaultPort - Default port to start with
|
|
362
363
|
* @param {string} home - WHATAP_HOME directory
|
|
363
364
|
* @returns {number|null} - Allocated port number or null if failed
|
|
@@ -371,8 +372,33 @@ NodeAgent.prototype.getPortNumber = function(port, home) {
|
|
|
371
372
|
return null;
|
|
372
373
|
}
|
|
373
374
|
|
|
374
|
-
//
|
|
375
|
-
|
|
375
|
+
// PM2 cluster 모드에서는 pm_id를 제외한 identifier 사용 (동일 포트 공유)
|
|
376
|
+
// 일반 모드에서는 pm_id 포함 (각자 다른 포트)
|
|
377
|
+
const appIdentifier = this.getApplicationIdentifier();
|
|
378
|
+
const portKey = `${home}:${appIdentifier}`;
|
|
379
|
+
const isPM2Cluster = this.isPM2ClusterMode();
|
|
380
|
+
|
|
381
|
+
const lockFilePath = process.env.WHATAP_LOCK_FILE || '/tmp/whatap-nodejs.lock';
|
|
382
|
+
|
|
383
|
+
// PM2 cluster 모드에서 whatap_nodejs가 이미 실행 중이면 lock 없이 읽기만
|
|
384
|
+
if (isPM2Cluster) {
|
|
385
|
+
const sharedPidFile = path.join(home, `agent-${appIdentifier}.pid`);
|
|
386
|
+
if (fs.existsSync(sharedPidFile)) {
|
|
387
|
+
try {
|
|
388
|
+
const existingPid = fs.readFileSync(sharedPidFile, 'utf8').trim();
|
|
389
|
+
if (existingPid && this.isGoAgentRunning(existingPid)) {
|
|
390
|
+
// whatap_nodejs가 실행 중이면 lock 없이 포트 파일 읽기
|
|
391
|
+
return this.readPortFromFile(lockFilePath, portKey, appIdentifier, isPM2Cluster);
|
|
392
|
+
}
|
|
393
|
+
} catch (e) {
|
|
394
|
+
Logger.printError("WHATAP-016", "Error checking agent process", e, false);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// 새로운 포트 할당이 필요한 경우 (첫 실행 또는 일반 모드)
|
|
400
|
+
// Open the port file with lock
|
|
401
|
+
const fileInfo = this.openPortFile(lockFilePath);
|
|
376
402
|
if (!fileInfo) {
|
|
377
403
|
return port; // Return default port if we couldn't open the file
|
|
378
404
|
}
|
|
@@ -392,6 +418,7 @@ NodeAgent.prototype.getPortNumber = function(port, home) {
|
|
|
392
418
|
}
|
|
393
419
|
|
|
394
420
|
let lastPortFound = null;
|
|
421
|
+
const existingPorts = new Map();
|
|
395
422
|
|
|
396
423
|
// Process each line
|
|
397
424
|
if (content && content.length > 0) {
|
|
@@ -401,24 +428,30 @@ NodeAgent.prototype.getPortNumber = function(port, home) {
|
|
|
401
428
|
if (!trimmedLine) continue;
|
|
402
429
|
|
|
403
430
|
try {
|
|
404
|
-
// Parse the line "port
|
|
405
|
-
const parts = trimmedLine.split(/\
|
|
431
|
+
// Parse the line "port portKey"
|
|
432
|
+
const parts = trimmedLine.split(/\t/, 2);
|
|
406
433
|
if (parts.length < 2) continue;
|
|
407
434
|
|
|
408
435
|
const portStr = parts[0];
|
|
409
|
-
const
|
|
436
|
+
const storedKey = parts[1];
|
|
410
437
|
const currentPort = parseInt(portStr, 10);
|
|
411
438
|
|
|
412
439
|
if (isNaN(currentPort)) continue;
|
|
413
440
|
|
|
414
|
-
// If
|
|
415
|
-
if (
|
|
441
|
+
// If portKey matches, return the existing port
|
|
442
|
+
if (portKey === storedKey) {
|
|
416
443
|
// Clean up before returning
|
|
417
444
|
properLock.unlockSync(filepath);
|
|
418
445
|
fs.closeSync(fileHandle);
|
|
446
|
+
Logger.print("WHATAP-017",
|
|
447
|
+
`Reusing existing port ${currentPort} for ${appIdentifier}${isPM2Cluster ? ' (PM2 cluster - shared port)' : ''}`,
|
|
448
|
+
false);
|
|
419
449
|
return currentPort;
|
|
420
450
|
}
|
|
421
451
|
|
|
452
|
+
// Store existing ports
|
|
453
|
+
existingPorts.set(storedKey, currentPort);
|
|
454
|
+
|
|
422
455
|
// Track the highest port number
|
|
423
456
|
if (!lastPortFound || lastPortFound < currentPort) {
|
|
424
457
|
lastPortFound = currentPort;
|
|
@@ -432,19 +465,27 @@ NodeAgent.prototype.getPortNumber = function(port, home) {
|
|
|
432
465
|
// Determine the new port number
|
|
433
466
|
const newPort = lastPortFound ? lastPortFound + 1 : port;
|
|
434
467
|
|
|
435
|
-
//
|
|
436
|
-
|
|
468
|
+
// Rebuild the file with existing entries + new entry
|
|
469
|
+
let newContent = '';
|
|
470
|
+
for (const [key, portNum] of existingPorts.entries()) {
|
|
471
|
+
newContent += `${portNum}\t${key}\n`;
|
|
472
|
+
}
|
|
473
|
+
newContent += `${newPort}\t${portKey}\n`;
|
|
437
474
|
|
|
438
|
-
//
|
|
439
|
-
fs.
|
|
475
|
+
// Clear and rewrite the file
|
|
476
|
+
fs.ftruncateSync(fileHandle, 0);
|
|
477
|
+
fs.writeSync(fileHandle, newContent);
|
|
440
478
|
|
|
441
479
|
// Unlock and close the file
|
|
442
480
|
properLock.unlockSync(filepath);
|
|
443
481
|
fs.closeSync(fileHandle);
|
|
444
482
|
|
|
483
|
+
Logger.print("WHATAP-018",
|
|
484
|
+
`Allocated new port ${newPort} for ${appIdentifier}${isPM2Cluster ? ' (PM2 cluster - shared port)' : ''}`,
|
|
485
|
+
false);
|
|
445
486
|
return newPort;
|
|
446
487
|
} catch (e) {
|
|
447
|
-
Logger.printError("WHATAP-
|
|
488
|
+
Logger.printError("WHATAP-019", "Error processing port file", e, false);
|
|
448
489
|
|
|
449
490
|
try {
|
|
450
491
|
properLock.unlockSync(filepath);
|
|
@@ -456,6 +497,56 @@ NodeAgent.prototype.getPortNumber = function(port, home) {
|
|
|
456
497
|
}
|
|
457
498
|
};
|
|
458
499
|
|
|
500
|
+
/**
|
|
501
|
+
* Read port from file without acquiring lock (for PM2 cluster mode)
|
|
502
|
+
* @param {string} filepath - Port file path
|
|
503
|
+
* @param {string} portKey - Port key to search
|
|
504
|
+
* @param {string} appIdentifier - Application identifier
|
|
505
|
+
* @param {boolean} isPM2Cluster - Whether in PM2 cluster mode
|
|
506
|
+
* @returns {number|null} - Port number or null if not found
|
|
507
|
+
*/
|
|
508
|
+
NodeAgent.prototype.readPortFromFile = function(filepath, portKey, appIdentifier, isPM2Cluster) {
|
|
509
|
+
try {
|
|
510
|
+
if (!fs.existsSync(filepath)) {
|
|
511
|
+
Logger.printError("WHATAP-020", "Port file does not exist", null, false);
|
|
512
|
+
return null;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
const content = fs.readFileSync(filepath, 'utf8').trim();
|
|
516
|
+
|
|
517
|
+
if (!content) {
|
|
518
|
+
return null;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
const lines = content.split('\n');
|
|
522
|
+
for (const line of lines) {
|
|
523
|
+
const trimmedLine = line.trim();
|
|
524
|
+
if (!trimmedLine) continue;
|
|
525
|
+
|
|
526
|
+
const parts = trimmedLine.split(/\t/, 2);
|
|
527
|
+
if (parts.length < 2) continue;
|
|
528
|
+
|
|
529
|
+
const portStr = parts[0];
|
|
530
|
+
const storedKey = parts[1];
|
|
531
|
+
const currentPort = parseInt(portStr, 10);
|
|
532
|
+
|
|
533
|
+
if (isNaN(currentPort)) continue;
|
|
534
|
+
|
|
535
|
+
if (portKey === storedKey) {
|
|
536
|
+
Logger.print("WHATAP-021",
|
|
537
|
+
`Reusing existing port ${currentPort} for ${appIdentifier}${isPM2Cluster ? ' (PM2 cluster - shared port, lock-free read)' : ''}`,
|
|
538
|
+
false);
|
|
539
|
+
return currentPort;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
return null;
|
|
544
|
+
} catch (e) {
|
|
545
|
+
Logger.printError("WHATAP-022", "Error reading port file without lock", e, false);
|
|
546
|
+
return null;
|
|
547
|
+
}
|
|
548
|
+
};
|
|
549
|
+
|
|
459
550
|
/**
|
|
460
551
|
* Configure the port for the agent and update the configuration
|
|
461
552
|
* @returns {number|null} - The configured port or null if failed
|
|
@@ -470,7 +561,7 @@ NodeAgent.prototype.configurePort = function() {
|
|
|
470
561
|
};
|
|
471
562
|
|
|
472
563
|
/**
|
|
473
|
-
* Update configuration file with new option value
|
|
564
|
+
* Update configuration file with new option value
|
|
474
565
|
* @param {string} home - Environment variable name for WhaTap home
|
|
475
566
|
* @param {string} optKey - Option key to update
|
|
476
567
|
* @param {string} optValue - Option value to set
|
|
@@ -478,11 +569,13 @@ NodeAgent.prototype.configurePort = function() {
|
|
|
478
569
|
NodeAgent.prototype.updateConfig = function(home, optKey, optValue) {
|
|
479
570
|
const homePath = process.env[home];
|
|
480
571
|
if (!homePath) {
|
|
481
|
-
Logger.print("WHATAP-
|
|
572
|
+
Logger.print("WHATAP-023", `${home} environment variable not set`, false);
|
|
482
573
|
return;
|
|
483
574
|
}
|
|
484
575
|
|
|
485
|
-
|
|
576
|
+
// Use WHATAP_CONF environment variable or default to 'whatap.conf'
|
|
577
|
+
const configFileName = process.env.WHATAP_CONF || 'whatap.conf';
|
|
578
|
+
const configFile = path.join(homePath, configFileName);
|
|
486
579
|
|
|
487
580
|
try {
|
|
488
581
|
let content = '';
|
|
@@ -516,12 +609,22 @@ NodeAgent.prototype.updateConfig = function(home, optKey, optValue) {
|
|
|
516
609
|
|
|
517
610
|
// Write updated content back to file
|
|
518
611
|
fs.writeFileSync(configFile, content);
|
|
519
|
-
Logger.print("WHATAP-
|
|
612
|
+
Logger.print("WHATAP-024", `Updated configuration: ${optKey}=${optValue}`, false);
|
|
520
613
|
} catch (e) {
|
|
521
|
-
Logger.printError("WHATAP-
|
|
614
|
+
Logger.printError("WHATAP-025", `Error updating configuration: ${optKey}=${optValue}`, e, false);
|
|
522
615
|
}
|
|
523
616
|
};
|
|
524
617
|
|
|
618
|
+
/**
|
|
619
|
+
* Check if running in PM2 cluster mode
|
|
620
|
+
* @returns {boolean} - True if PM2 cluster mode
|
|
621
|
+
*/
|
|
622
|
+
NodeAgent.prototype.isPM2ClusterMode = function() {
|
|
623
|
+
return process.env.pm_id !== undefined &&
|
|
624
|
+
process.env.instances !== undefined &&
|
|
625
|
+
parseInt(process.env.instances) > 1;
|
|
626
|
+
};
|
|
627
|
+
|
|
525
628
|
NodeAgent.prototype.getApplicationIdentifier = function() {
|
|
526
629
|
// 1. 명시적 그룹 지정 (환경 변수)
|
|
527
630
|
if (process.env.WHATAP_APP_GROUP) {
|
|
@@ -536,24 +639,35 @@ NodeAgent.prototype.getApplicationIdentifier = function() {
|
|
|
536
639
|
// 3. 자동 생성
|
|
537
640
|
const appRoot = this._conf['app.root'] || process.cwd();
|
|
538
641
|
const appName = this.getApplicationName();
|
|
642
|
+
const isPM2Cluster = this.isPM2ClusterMode();
|
|
643
|
+
|
|
644
|
+
// PM2 cluster 모드에서는 pm_id를 제외하여 모든 인스턴스가 동일한 identifier를 공유
|
|
645
|
+
// 일반 PM2 모드나 단일 인스턴스에서는 pm_id 포함
|
|
646
|
+
let identifierBase = `${appRoot}:${appName}`;
|
|
647
|
+
if (process.env.pm_id !== undefined && !isPM2Cluster) {
|
|
648
|
+
identifierBase += `:${process.env.pm_id}`;
|
|
649
|
+
}
|
|
539
650
|
|
|
540
651
|
const identifier = crypto
|
|
541
652
|
.createHash('md5')
|
|
542
|
-
.update(
|
|
653
|
+
.update(identifierBase)
|
|
543
654
|
.digest('hex')
|
|
544
655
|
.substr(0, 8);
|
|
545
656
|
|
|
546
|
-
Logger.print("WHATAP-
|
|
547
|
-
`Application identifier: ${appName} at ${appRoot} => ${identifier}`,
|
|
657
|
+
Logger.print("WHATAP-026",
|
|
658
|
+
`Application identifier: ${appName} at ${appRoot}${isPM2Cluster ? ' (PM2 cluster mode)' : (process.env.pm_id !== undefined ? ' (PM2 instance: ' + process.env.pm_id + ')' : '')} => ${identifier}`,
|
|
548
659
|
false);
|
|
549
660
|
|
|
550
661
|
return identifier;
|
|
551
662
|
};
|
|
552
663
|
|
|
553
664
|
NodeAgent.prototype.getApplicationName = function() {
|
|
554
|
-
// 1. PM2 실행 시
|
|
555
|
-
if (process.env.
|
|
556
|
-
|
|
665
|
+
// 1. PM2 실행 시 (PM2의 공식 환경 변수 사용)
|
|
666
|
+
if (process.env.pm_id !== undefined) {
|
|
667
|
+
// PM2 환경에서는 name 환경 변수 사용
|
|
668
|
+
if (process.env.name) {
|
|
669
|
+
return process.env.name;
|
|
670
|
+
}
|
|
557
671
|
}
|
|
558
672
|
|
|
559
673
|
// 2. 설정 파일에서
|
|
@@ -588,8 +702,9 @@ NodeAgent.prototype.startGoAgent = function(opts = {}) {
|
|
|
588
702
|
return;
|
|
589
703
|
}
|
|
590
704
|
|
|
591
|
-
// 1. 애플리케이션 식별자 생성
|
|
705
|
+
// 1. 애플리케이션 식별자 생성
|
|
592
706
|
const appIdentifier = this.getApplicationIdentifier();
|
|
707
|
+
const isPM2Cluster = this.isPM2ClusterMode();
|
|
593
708
|
const sharedLockFile = path.join(whatapHome, `agent-${appIdentifier}.lock`);
|
|
594
709
|
const sharedPidFile = path.join(whatapHome, `agent-${appIdentifier}.pid`);
|
|
595
710
|
|
|
@@ -599,33 +714,64 @@ NodeAgent.prototype.startGoAgent = function(opts = {}) {
|
|
|
599
714
|
// PID 파일에서 기존 PID 읽기
|
|
600
715
|
const existingPid = fs.readFileSync(sharedPidFile, 'utf8').trim();
|
|
601
716
|
if (existingPid && this.isGoAgentRunning(existingPid)) {
|
|
602
|
-
|
|
717
|
+
const logMsg = isPM2Cluster
|
|
718
|
+
? `Go agent already running for application ${appIdentifier} (PID: ${existingPid}) - PM2 instance ${process.env.pm_id} will connect to shared agent`
|
|
719
|
+
: `Go agent already running for application ${appIdentifier} (PID: ${existingPid})`;
|
|
720
|
+
Logger.print("WHATAP-027", logMsg, false);
|
|
603
721
|
return;
|
|
604
722
|
} else {
|
|
605
723
|
// 프로세스가 죽었다면 파일 제거
|
|
606
|
-
Logger.print("WHATAP-
|
|
724
|
+
Logger.print("WHATAP-028", `Previous agent process ${existingPid} not found, cleaning up`, false);
|
|
607
725
|
try { fs.unlinkSync(sharedLockFile); } catch (e) {}
|
|
608
726
|
try { fs.unlinkSync(sharedPidFile); } catch (e) {}
|
|
609
727
|
}
|
|
610
728
|
}
|
|
611
729
|
} catch (e) {
|
|
612
|
-
Logger.printError("WHATAP-
|
|
730
|
+
Logger.printError("WHATAP-029", "Error checking shared lock file", e, false);
|
|
613
731
|
}
|
|
614
732
|
|
|
615
|
-
//
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
733
|
+
// 3. PM2 cluster 모드에서는 첫 번째 인스턴스만 에이전트 시작
|
|
734
|
+
if (isPM2Cluster) {
|
|
735
|
+
// 잠금 파일로 동시 실행 방지
|
|
736
|
+
let lockAcquired = false;
|
|
737
|
+
try {
|
|
738
|
+
if (!fs.existsSync(sharedLockFile)) {
|
|
739
|
+
fs.writeFileSync(sharedLockFile, process.pid.toString());
|
|
740
|
+
lockAcquired = true;
|
|
741
|
+
Logger.print("WHATAP-030",
|
|
742
|
+
`PM2 cluster mode: Instance ${process.env.pm_id} will start shared agent`,
|
|
743
|
+
false);
|
|
744
|
+
} else {
|
|
745
|
+
// 다른 인스턴스가 이미 에이전트를 시작하는 중
|
|
746
|
+
Logger.print("WHATAP-031",
|
|
747
|
+
`PM2 cluster mode: Instance ${process.env.pm_id} detected another instance starting the agent, will use shared agent`,
|
|
748
|
+
false);
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
} catch (e) {
|
|
752
|
+
Logger.printError("WHATAP-032", "Error acquiring lock in PM2 cluster mode", e, false);
|
|
753
|
+
return;
|
|
621
754
|
}
|
|
622
|
-
} catch (e) {
|
|
623
|
-
Logger.printError("WHATAP-AGENT", "Error acquiring lock", e, false);
|
|
624
|
-
}
|
|
625
755
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
756
|
+
if (!lockAcquired) {
|
|
757
|
+
return;
|
|
758
|
+
}
|
|
759
|
+
} else {
|
|
760
|
+
// 일반 모드에서는 기존 로직 사용
|
|
761
|
+
let lockAcquired = false;
|
|
762
|
+
try {
|
|
763
|
+
if (!fs.existsSync(sharedLockFile)) {
|
|
764
|
+
fs.writeFileSync(sharedLockFile, process.pid.toString());
|
|
765
|
+
lockAcquired = true;
|
|
766
|
+
}
|
|
767
|
+
} catch (e) {
|
|
768
|
+
Logger.printError("WHATAP-033", "Error acquiring lock", e, false);
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
if (!lockAcquired) {
|
|
772
|
+
Logger.print("WHATAP-034", "Another process is starting the agent, waiting...", false);
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
629
775
|
}
|
|
630
776
|
|
|
631
777
|
// 기존 whatap_nodejs.pid 파일 처리 (호환성 유지)
|
|
@@ -647,7 +793,7 @@ NodeAgent.prototype.startGoAgent = function(opts = {}) {
|
|
|
647
793
|
}
|
|
648
794
|
|
|
649
795
|
// 포트 설정은 initUdp()에서 처리됨
|
|
650
|
-
Logger.print("WHATAP-
|
|
796
|
+
Logger.print("WHATAP-035", "Port configuration will be handled during UDP initialization", false);
|
|
651
797
|
|
|
652
798
|
try {
|
|
653
799
|
// 바이너리 경로 설정
|
|
@@ -660,11 +806,11 @@ NodeAgent.prototype.startGoAgent = function(opts = {}) {
|
|
|
660
806
|
if (!fs.existsSync(agentPath)) {
|
|
661
807
|
try {
|
|
662
808
|
fs.symlinkSync(sourcePath, agentPath);
|
|
663
|
-
Logger.print("WHATAP-
|
|
809
|
+
Logger.print("WHATAP-036", `Created symbolic link for ${AGENT_NAME}`, false);
|
|
664
810
|
} catch (e) {
|
|
665
811
|
if (e.code !== 'EEXIST') {
|
|
666
812
|
if (platform === 'win32') {
|
|
667
|
-
Logger.print("WHATAP-
|
|
813
|
+
Logger.print("WHATAP-037", "Symlink failed, copying binary instead", false);
|
|
668
814
|
fs.copyFileSync(sourcePath, agentPath);
|
|
669
815
|
} else {
|
|
670
816
|
throw e;
|
|
@@ -686,20 +832,34 @@ NodeAgent.prototype.startGoAgent = function(opts = {}) {
|
|
|
686
832
|
newEnv['node.version'] = process.version;
|
|
687
833
|
newEnv['node.tzname'] = new Date().toLocaleString('en', {timeZoneName: 'short'}).split(' ').pop();
|
|
688
834
|
newEnv['os.release'] = os.release();
|
|
689
|
-
newEnv['whatap.enabled'] = '
|
|
835
|
+
newEnv['whatap.enabled'] = 'true';
|
|
690
836
|
newEnv['WHATAP_PID_FILE'] = sharedPidFile; // 공유 PID 파일 사용
|
|
691
|
-
newEnv['NODEJS_PARENT_APP_PID'] = process.pid.toString();
|
|
692
837
|
newEnv['APP_IDENTIFIER'] = appIdentifier;
|
|
693
838
|
newEnv['APP_NAME'] = this.getApplicationName();
|
|
694
839
|
|
|
695
840
|
// PM2 정보 추가
|
|
696
|
-
const isPM2 =
|
|
697
|
-
typeof process.env.pm_id !== 'undefined' ||
|
|
698
|
-
typeof process.env.PM2_JSON_PROCESSING !== 'undefined';
|
|
841
|
+
const isPM2 = process.env.pm_id !== undefined;
|
|
699
842
|
|
|
700
843
|
if (isPM2) {
|
|
701
844
|
newEnv['PM2_APP_NAME'] = process.env.name || '';
|
|
702
|
-
newEnv['
|
|
845
|
+
newEnv['PM2_INSTANCES'] = process.env.instances || '1';
|
|
846
|
+
|
|
847
|
+
// PM2 cluster 모드
|
|
848
|
+
if (isPM2Cluster) {
|
|
849
|
+
// cluster 모드에서는 첫 번째 인스턴스의 ID만 전달
|
|
850
|
+
newEnv['PM2_CLUSTER_MODE'] = 'true';
|
|
851
|
+
newEnv['PM2_STARTER_ID'] = process.env.pm_id || '0';
|
|
852
|
+
Logger.print("WHATAP-038",
|
|
853
|
+
`PM2 cluster mode: Starting shared agent from instance ${process.env.pm_id}`,
|
|
854
|
+
false);
|
|
855
|
+
} else {
|
|
856
|
+
// 단일 인스턴스 모드
|
|
857
|
+
newEnv['PM2_ID'] = process.env.pm_id || '';
|
|
858
|
+
newEnv['NODEJS_PARENT_APP_PID'] = process.pid.toString();
|
|
859
|
+
}
|
|
860
|
+
} else {
|
|
861
|
+
// PM2가 아닌 경우
|
|
862
|
+
newEnv['NODEJS_PARENT_APP_PID'] = process.pid.toString();
|
|
703
863
|
}
|
|
704
864
|
|
|
705
865
|
Object.assign(newEnv, opts);
|
|
@@ -729,7 +889,7 @@ NodeAgent.prototype.startGoAgent = function(opts = {}) {
|
|
|
729
889
|
|
|
730
890
|
// PID 추적을 위한 추가 로직
|
|
731
891
|
agentProcess.on('spawn', () => {
|
|
732
|
-
Logger.print("WHATAP-
|
|
892
|
+
Logger.print("WHATAP-039", `Agent process spawned with PID: ${agentProcess.pid}`, false);
|
|
733
893
|
|
|
734
894
|
// detached 프로세스에서 실제 PID가 다를 수 있으므로 잠시 대기 후 확인
|
|
735
895
|
setTimeout(() => {
|
|
@@ -759,7 +919,7 @@ NodeAgent.prototype.startGoAgent = function(opts = {}) {
|
|
|
759
919
|
const pidNum = parseInt(foundPid);
|
|
760
920
|
// spawn된 PID와 비슷한 범위인지 확인
|
|
761
921
|
if (Math.abs(pidNum - agentProcess.pid) <= 2) {
|
|
762
|
-
Logger.print("WHATAP-
|
|
922
|
+
Logger.print("WHATAP-040",
|
|
763
923
|
`Found actual agent PID: ${foundPid} (spawn returned: ${agentProcess.pid})`,
|
|
764
924
|
false);
|
|
765
925
|
|
|
@@ -772,7 +932,7 @@ NodeAgent.prototype.startGoAgent = function(opts = {}) {
|
|
|
772
932
|
}
|
|
773
933
|
|
|
774
934
|
// 실제 PID를 찾지 못한 경우 spawn이 반환한 PID 사용
|
|
775
|
-
Logger.print("WHATAP-
|
|
935
|
+
Logger.print("WHATAP-041",
|
|
776
936
|
`Using spawn PID: ${agentProcess.pid} (actual PID not found)`,
|
|
777
937
|
false);
|
|
778
938
|
|
|
@@ -780,7 +940,7 @@ NodeAgent.prototype.startGoAgent = function(opts = {}) {
|
|
|
780
940
|
this.writeToFile(home, pidFileName, agentProcess.pid.toString());
|
|
781
941
|
|
|
782
942
|
} catch (e) {
|
|
783
|
-
Logger.printError("WHATAP-
|
|
943
|
+
Logger.printError("WHATAP-042", "Error finding actual PID", e, false);
|
|
784
944
|
// 에러 발생 시 spawn이 반환한 PID 사용
|
|
785
945
|
fs.writeFileSync(sharedPidFile, agentProcess.pid.toString());
|
|
786
946
|
this.writeToFile(home, pidFileName, agentProcess.pid.toString());
|
|
@@ -790,28 +950,29 @@ NodeAgent.prototype.startGoAgent = function(opts = {}) {
|
|
|
790
950
|
|
|
791
951
|
agentProcess.on('close', (code) => {
|
|
792
952
|
if (code !== 0) {
|
|
793
|
-
Logger.printError("WHATAP-
|
|
794
|
-
Logger.print("WHATAP-
|
|
795
|
-
Logger.print("WHATAP-
|
|
953
|
+
Logger.printError("WHATAP-043", `Agent process exited with code ${code}`, null, false);
|
|
954
|
+
Logger.print("WHATAP-044", `STDOUT: ${stdout}`, false);
|
|
955
|
+
Logger.print("WHATAP-045", `STDERR: ${stderr}`, false);
|
|
796
956
|
// 에이전트가 비정상 종료되면 파일 제거
|
|
797
957
|
try { fs.unlinkSync(sharedLockFile); } catch (e) {}
|
|
798
958
|
try { fs.unlinkSync(sharedPidFile); } catch (e) {}
|
|
799
959
|
} else {
|
|
800
|
-
Logger.print("WHATAP-
|
|
960
|
+
Logger.print("WHATAP-046", "Agent started successfully", false);
|
|
801
961
|
}
|
|
802
962
|
});
|
|
803
963
|
|
|
804
964
|
agentProcess.unref();
|
|
805
965
|
|
|
806
|
-
|
|
807
|
-
`AGENT UP! (process name: ${AGENT_NAME}, app: ${appIdentifier})
|
|
808
|
-
|
|
966
|
+
const agentMsg = isPM2Cluster
|
|
967
|
+
? `AGENT UP! (process name: ${AGENT_NAME}, app: ${appIdentifier}, PM2 cluster - shared by ${process.env.instances} instances)`
|
|
968
|
+
: `AGENT UP! (process name: ${AGENT_NAME}, app: ${appIdentifier})`;
|
|
969
|
+
Logger.print("WHATAP-047", agentMsg, false);
|
|
809
970
|
|
|
810
971
|
// 잠금 해제
|
|
811
972
|
try { fs.unlinkSync(sharedLockFile); } catch (e) {}
|
|
812
973
|
|
|
813
974
|
} catch (e) {
|
|
814
|
-
Logger.printError("WHATAP-
|
|
975
|
+
Logger.printError("WHATAP-048", "Error starting agent", e, false);
|
|
815
976
|
// 에러 발생 시 파일 정리
|
|
816
977
|
try { fs.unlinkSync(sharedLockFile); } catch (e) {}
|
|
817
978
|
try { fs.unlinkSync(sharedPidFile); } catch (e) {}
|
|
@@ -820,11 +981,23 @@ NodeAgent.prototype.startGoAgent = function(opts = {}) {
|
|
|
820
981
|
|
|
821
982
|
// 프로세스 종료 시 정리 작업 개선
|
|
822
983
|
process.on('exit', () => {
|
|
823
|
-
if (!process.env.WHATAP_HOME || !NodeAgent.prototype.getApplicationIdentifier) {
|
|
984
|
+
if (!process.env.WHATAP_HOME || !NodeAgent.prototype.getApplicationIdentifier || !NodeAgent.prototype.isPM2ClusterMode) {
|
|
824
985
|
return;
|
|
825
986
|
}
|
|
826
987
|
|
|
827
988
|
try {
|
|
989
|
+
const isPM2Cluster = NodeAgent.prototype.isPM2ClusterMode.call(NodeAgent);
|
|
990
|
+
|
|
991
|
+
// PM2 cluster 모드에서는 인스턴스가 종료되어도 공유 에이전트를 종료하지 않음
|
|
992
|
+
// 다른 인스턴스가 계속 사용 중일 수 있음
|
|
993
|
+
if (isPM2Cluster) {
|
|
994
|
+
Logger.print("WHATAP-049",
|
|
995
|
+
`PM2 cluster instance ${process.env.pm_id} exiting - shared agent will remain running`,
|
|
996
|
+
false);
|
|
997
|
+
return;
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
// 일반 모드에서는 기존 로직 사용
|
|
828
1001
|
const appIdentifier = NodeAgent.prototype.getApplicationIdentifier.call(NodeAgent);
|
|
829
1002
|
const sharedPidFile = path.join(process.env.WHATAP_HOME, `agent-${appIdentifier}.pid`);
|
|
830
1003
|
|
|
@@ -843,12 +1016,11 @@ process.on('exit', () => {
|
|
|
843
1016
|
// graceful shutdown 처리 추가
|
|
844
1017
|
['SIGTERM', 'SIGINT'].forEach((signal) => {
|
|
845
1018
|
process.on(signal, () => {
|
|
846
|
-
Logger.print("WHATAP-
|
|
1019
|
+
Logger.print("WHATAP-050", `Received ${signal}, cleaning up...`, false);
|
|
847
1020
|
process.exit(0);
|
|
848
1021
|
});
|
|
849
1022
|
});
|
|
850
1023
|
|
|
851
|
-
// Updated init method to incorporate configuration setup similar to Python agent
|
|
852
1024
|
NodeAgent.prototype.init = function(cb) {
|
|
853
1025
|
var self = this;
|
|
854
1026
|
if (self._initialized) {
|
|
@@ -869,12 +1041,12 @@ NodeAgent.prototype.init = function(cb) {
|
|
|
869
1041
|
Logger.print('WHATAP-110', 'Start initialize WhaTap Agent... Root[' + self._conf['app.root'] + ']', true);
|
|
870
1042
|
|
|
871
1043
|
if (self._conf['app.root'] == null || self._conf['app.root'].length == 0) {
|
|
872
|
-
return Logger.print("WHATAP-111", "Can not find application root directory",
|
|
1044
|
+
return Logger.print("WHATAP-111", "Can not find application root directory", false);
|
|
873
1045
|
}
|
|
874
1046
|
|
|
875
1047
|
// Initialize configuration with proper home directory
|
|
876
1048
|
if (!self.initConfig('WHATAP_HOME')) {
|
|
877
|
-
Logger.printError("WHATAP-
|
|
1049
|
+
Logger.printError("WHATAP-051", "Failed to initialize configuration", null, false);
|
|
878
1050
|
return self;
|
|
879
1051
|
}
|
|
880
1052
|
|
|
@@ -883,12 +1055,12 @@ NodeAgent.prototype.init = function(cb) {
|
|
|
883
1055
|
self._conf.init(this._userOpt, function(e) {
|
|
884
1056
|
if (e) {
|
|
885
1057
|
Logger.printError("WHATAP-112", "Configuration initialize error. " + e.message,
|
|
886
|
-
e,
|
|
1058
|
+
e, false);
|
|
887
1059
|
return;
|
|
888
1060
|
}
|
|
889
1061
|
Logger.print('WHATAP-113', 'Finish initialize configuration... ' + Boolean(self._conf['reqlog_enabled']), false);
|
|
890
1062
|
if (Boolean(self._conf['reqlog_enabled']) == true) {
|
|
891
|
-
Logger.print("WHATAP-
|
|
1063
|
+
Logger.print("WHATAP-052", "ReqLog Init Start !!!!", false);
|
|
892
1064
|
RequestLog.initializer.process();
|
|
893
1065
|
}
|
|
894
1066
|
|
|
@@ -963,11 +1135,12 @@ NodeAgent.prototype.loadObserves = function() {
|
|
|
963
1135
|
try {
|
|
964
1136
|
require(name);
|
|
965
1137
|
} catch (err) {
|
|
966
|
-
Logger.print("
|
|
1138
|
+
Logger.print("WHATAP-053", 'unable to load ' + name + ' module', false);
|
|
967
1139
|
}
|
|
968
1140
|
}
|
|
969
1141
|
new ProcessObserver(agent).inject(process, 'process');
|
|
970
1142
|
new GlobalObserver(agent).inject(global, 'global');
|
|
1143
|
+
new CustomMethodObserver(agent).inject(null, 'custom-method');
|
|
971
1144
|
};
|
|
972
1145
|
|
|
973
1146
|
NodeAgent.prototype.setServicePort = function (port) {
|
|
@@ -976,13 +1149,13 @@ NodeAgent.prototype.setServicePort = function (port) {
|
|
|
976
1149
|
|
|
977
1150
|
NodeAgent.prototype.initUdp = function() {
|
|
978
1151
|
var self = this;
|
|
979
|
-
Logger.print('WHATAP-
|
|
1152
|
+
Logger.print('WHATAP-054', 'Initializing UDP connection...', false);
|
|
980
1153
|
|
|
981
1154
|
// Configure the port before initializing UDP
|
|
982
1155
|
const configuredPort = self.configurePort();
|
|
983
1156
|
if (configuredPort) {
|
|
984
1157
|
self._conf['net_udp_port'] = configuredPort;
|
|
985
|
-
Logger.print('WHATAP-
|
|
1158
|
+
Logger.print('WHATAP-055', `Using configured port: ${configuredPort}`, false);
|
|
986
1159
|
}
|
|
987
1160
|
|
|
988
1161
|
// Initialize the UDP session with updated config
|
|
@@ -991,27 +1164,11 @@ NodeAgent.prototype.initUdp = function() {
|
|
|
991
1164
|
// Initialize the async sender
|
|
992
1165
|
AsyncSender.startWhatapThread();
|
|
993
1166
|
|
|
994
|
-
Logger.print('WHATAP-
|
|
1167
|
+
Logger.print('WHATAP-056', 'UDP connection initialized', false);
|
|
995
1168
|
};
|
|
996
1169
|
|
|
997
1170
|
/**
|
|
998
|
-
*
|
|
999
|
-
* @param {string} target - Environment variable name to check
|
|
1000
|
-
* @returns {string|null} - Value of the environment variable or null
|
|
1001
|
-
*/
|
|
1002
|
-
NodeAgent.prototype.checkWhatapHome = function(target) {
|
|
1003
|
-
let whatapHome = process.env[target];
|
|
1004
|
-
if (!whatapHome) {
|
|
1005
|
-
whatapHome = this.findWhatapConf();
|
|
1006
|
-
}
|
|
1007
|
-
if (!whatapHome) {
|
|
1008
|
-
Logger.print("WHATAP-HOME", `${target} is empty`, true);
|
|
1009
|
-
}
|
|
1010
|
-
return whatapHome;
|
|
1011
|
-
};
|
|
1012
|
-
|
|
1013
|
-
/**
|
|
1014
|
-
* Initialize configuration with default values - similar to Python's init_config
|
|
1171
|
+
* Initialize configuration with default values
|
|
1015
1172
|
* @param {string} home - Environment variable name for home directory
|
|
1016
1173
|
* @returns {boolean} - True if successful, false otherwise
|
|
1017
1174
|
*/
|
|
@@ -1026,9 +1183,7 @@ NodeAgent.prototype.initConfig = function(home) {
|
|
|
1026
1183
|
whatapHome = process.cwd();
|
|
1027
1184
|
process.env[home] = whatapHome;
|
|
1028
1185
|
|
|
1029
|
-
Logger.print("WHATAP-
|
|
1030
|
-
Logger.print("WHATAP-HOME", "WHATAP_HOME set default CURRENT_WORKING_DIRECTORY value", true);
|
|
1031
|
-
Logger.print("WHATAP-HOME", `CURRENT_WORKING_DIRECTORY is ${whatapHome}`, true);
|
|
1186
|
+
Logger.print("WHATAP-058", "WHATAP_HOME is empty", true);
|
|
1032
1187
|
}
|
|
1033
1188
|
}
|
|
1034
1189
|
|
|
@@ -1037,7 +1192,10 @@ NodeAgent.prototype.initConfig = function(home) {
|
|
|
1037
1192
|
}
|
|
1038
1193
|
|
|
1039
1194
|
process.env[home] = whatapHome;
|
|
1040
|
-
|
|
1195
|
+
|
|
1196
|
+
// Use WHATAP_CONF environment variable or default to 'whatap.conf'
|
|
1197
|
+
const configFileName = process.env.WHATAP_CONF || 'whatap.conf';
|
|
1198
|
+
const configFile = path.join(process.env[home], configFileName);
|
|
1041
1199
|
|
|
1042
1200
|
if (!fs.existsSync(configFile)) {
|
|
1043
1201
|
try {
|
|
@@ -1051,8 +1209,7 @@ NodeAgent.prototype.initConfig = function(home) {
|
|
|
1051
1209
|
fs.writeFileSync(configFile, '# WhaTap Node.js Agent Configuration\n');
|
|
1052
1210
|
}
|
|
1053
1211
|
} catch (e) {
|
|
1054
|
-
Logger.printError("WHATAP-
|
|
1055
|
-
Logger.print("WHATAP-CONFIG", 'Try to execute command: `sudo chmod -R 777 $WHATAP_HOME`', true);
|
|
1212
|
+
Logger.printError("WHATAP-059", "Permission error creating config file. Try to execute command: `sudo chmod -R 777 $WHATAP_HOME`", e, false);
|
|
1056
1213
|
return false;
|
|
1057
1214
|
}
|
|
1058
1215
|
}
|