whatap 0.5.19 → 0.5.21
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 +7 -0
- package/lib/control/control-handler.js +21 -12
- package/lib/core/agent.js +2 -0
- package/lib/error/error-handler.js +437 -0
- package/lib/observers/apollo-server-observer.js +10 -2
- package/lib/observers/global-observer.js +17 -7
- package/lib/observers/grpc-observer.js +9 -9
- package/lib/observers/http-observer.js +145 -15
- package/lib/observers/maria-observer.js +0 -1
- package/lib/observers/mongodb-observer.js +4 -1
- package/lib/observers/mongoose-observer.js +414 -114
- package/lib/observers/mssql-observer.js +2 -0
- package/lib/observers/mysql-observer.js +5 -2
- package/lib/observers/mysql2-observer.js +703 -0
- package/lib/observers/oracle-observer.js +4 -1
- package/lib/observers/pgsql-observer.js +2 -0
- package/lib/observers/prisma-observer.js +3 -2
- package/lib/service/tx-record.js +92 -54
- package/lib/trace/trace-context.js +2 -0
- package/package.json +2 -2
|
@@ -126,6 +126,23 @@ conf.on('ignore_build_file_enabled', function (newProps) {
|
|
|
126
126
|
conf.on('ignore_build_file_path', function (newProps) {
|
|
127
127
|
ignore_build_file_path = newProps;
|
|
128
128
|
})
|
|
129
|
+
|
|
130
|
+
let _trace_mtrace_traceparent_key = conf.getProperty('trace_mtrace_traceparent_key', 'traceparent');
|
|
131
|
+
let custom_trace_header_enabled = conf.getProperty('custom_trace_header_enabled', false);
|
|
132
|
+
let custom_trace_header_key = conf.getProperty('custom_trace_header_key', null);
|
|
133
|
+
|
|
134
|
+
// conf 리스너 추가
|
|
135
|
+
conf.on('trace_mtrace_traceparent_key', function(newProperty) {
|
|
136
|
+
_trace_mtrace_traceparent_key = newProperty;
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
conf.on('custom_trace_header_enabled', function(newProperty) {
|
|
140
|
+
custom_trace_header_enabled = newProperty;
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
conf.on('custom_trace_header_key', function(newProperty) {
|
|
144
|
+
custom_trace_header_key = newProperty;
|
|
145
|
+
});
|
|
129
146
|
var staticConents = function (newProps) {
|
|
130
147
|
var x=new Set();
|
|
131
148
|
var words = !newProps?[]:newProps.split(',');
|
|
@@ -379,26 +396,69 @@ function initCtx(req, res) {
|
|
|
379
396
|
/* Multi Server Transaction Trace */
|
|
380
397
|
/************************************/
|
|
381
398
|
if(conf.getProperty('mtrace_enabled', false)) {
|
|
382
|
-
|
|
399
|
+
// traceparent 헤더 처리 (W3C Trace Context 표준)
|
|
400
|
+
const traceparentKey = req.headers[conf._trace_mtrace_traceparent_key];
|
|
401
|
+
let hasTraceparentKey = false;
|
|
402
|
+
let traceparentStepId = 0;
|
|
403
|
+
|
|
404
|
+
if (traceparentKey) {
|
|
405
|
+
hasTraceparentKey = true;
|
|
406
|
+
const parts = traceparentKey.trim().split('-');
|
|
407
|
+
|
|
408
|
+
if (parts.length >= 4) {
|
|
409
|
+
// parts[0]: version (00)
|
|
410
|
+
// parts[1]: 32자리 16진수 trace ID
|
|
411
|
+
// parts[2]: 16자리 16진수 parent ID (span ID)
|
|
412
|
+
// parts[3]: 2자리 16진수 trace flags
|
|
413
|
+
|
|
414
|
+
const mcallerTraceIdValue = parts[1];
|
|
415
|
+
ctx.mcallerTraceparentValue = mcallerTraceIdValue;
|
|
416
|
+
|
|
417
|
+
try {
|
|
418
|
+
// trace ID의 뒤 16자리를 가져와서 long으로 변환
|
|
419
|
+
const mtidHex = mcallerTraceIdValue.substring(16);
|
|
420
|
+
const mtidLong = Long.fromString(mtidHex, true, 16);
|
|
421
|
+
ctx.mtid = mtidLong;
|
|
422
|
+
|
|
423
|
+
if (!ctx.mtid.isZero()) {
|
|
424
|
+
ctx.mtid_build_checked = true;
|
|
425
|
+
}
|
|
426
|
+
} catch (e) {
|
|
427
|
+
Logger.printError('WHATAP-851', 'traceparent parse error', e, true);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
try {
|
|
431
|
+
// parent span ID 추출
|
|
432
|
+
const parentSpanId = Long.fromString(parts[2], true, 16);
|
|
433
|
+
ctx.mcaller_stepId = parentSpanId;
|
|
434
|
+
traceparentStepId = parentSpanId;
|
|
435
|
+
} catch (e) {
|
|
436
|
+
Logger.printError('WHATAP-851', 'traceparent span id parse error', e, true);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// WhaTap 고유 헤더 처리
|
|
442
|
+
const poid = req.headers['x-wtap-po'];
|
|
383
443
|
if (poid != null) {
|
|
384
444
|
ctx.setCallerPOID(poid);
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
445
|
+
|
|
446
|
+
try {
|
|
447
|
+
const mt_caller = req.headers[conf._trace_mtrace_caller_key];
|
|
448
|
+
if(mt_caller) {
|
|
449
|
+
const x = mt_caller.indexOf(',');
|
|
389
450
|
if (x > 0) {
|
|
390
451
|
ctx.mtid = Hexa32.toLong32(mt_caller.substring(0, x));
|
|
391
452
|
ctx.mtid_build_checked = true;
|
|
392
|
-
|
|
453
|
+
const y = mt_caller.indexOf(',', x + 1);
|
|
393
454
|
if (y > 0) {
|
|
394
455
|
ctx.mdepth = parseInt(mt_caller.substring(x + 1, y));
|
|
395
|
-
|
|
456
|
+
const z = mt_caller.indexOf(',', y + 1);
|
|
396
457
|
if (z < 0) {
|
|
397
458
|
ctx.mcaller_txid = Hexa32.toLong32(mt_caller.substring(y + 1));
|
|
398
459
|
} else {
|
|
399
460
|
ctx.mcaller_txid = Hexa32.toLong32(mt_caller.substring(y + 1, z));
|
|
400
|
-
|
|
401
|
-
var z2 = mt_caller.indexOf(',', z + 1);
|
|
461
|
+
const z2 = mt_caller.indexOf(',', z + 1);
|
|
402
462
|
if (z2 < 0) {
|
|
403
463
|
ctx.mcaller_stepId = Hexa32.toLong32(mt_caller.substring(z + 1));
|
|
404
464
|
} else {
|
|
@@ -408,18 +468,69 @@ function initCtx(req, res) {
|
|
|
408
468
|
}
|
|
409
469
|
}
|
|
410
470
|
}
|
|
471
|
+
|
|
411
472
|
if (conf.stat_mtrace_enabled) {
|
|
412
|
-
|
|
413
|
-
if(inf != null && inf.length > 0){
|
|
414
|
-
|
|
415
|
-
ctx.mcaller_spec =
|
|
473
|
+
const inf = req.headers[conf._trace_mtrace_spec_key1];
|
|
474
|
+
if(inf != null && inf.length > 0) {
|
|
475
|
+
const px = inf.indexOf(',');
|
|
476
|
+
ctx.mcaller_spec = inf.substring(0, px);
|
|
416
477
|
ctx.mcaller_url = inf.substring(px + 1);
|
|
417
478
|
}
|
|
418
479
|
}
|
|
419
480
|
} catch(e) {
|
|
420
|
-
Logger.printError('WHATAP-850', 'Multi Server Transaction
|
|
481
|
+
Logger.printError('WHATAP-850', 'Multi Server Transaction', e, true);
|
|
421
482
|
}
|
|
422
483
|
}
|
|
484
|
+
|
|
485
|
+
// Gateway가 header를 그대로 전달하는 경우 처리
|
|
486
|
+
if (hasTraceparentKey) {
|
|
487
|
+
if (!traceparentStepId.equals(ctx.mcaller_stepId)) {
|
|
488
|
+
ctx.mcaller_stepId = traceparentStepId;
|
|
489
|
+
ctx.mcaller_txid = Long.ZERO;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
var poid=req.headers['x-wtap-po'];
|
|
495
|
+
if (poid != null) {
|
|
496
|
+
ctx.setCallerPOID(poid);
|
|
497
|
+
try{
|
|
498
|
+
var mt_caller=req.headers[conf._trace_mtrace_caller_key];
|
|
499
|
+
if(mt_caller){
|
|
500
|
+
var x = mt_caller.indexOf(',');
|
|
501
|
+
if (x > 0) {
|
|
502
|
+
ctx.mtid = Hexa32.toLong32(mt_caller.substring(0, x));
|
|
503
|
+
ctx.mtid_build_checked = true;
|
|
504
|
+
var y = mt_caller.indexOf(',', x + 1);
|
|
505
|
+
if (y > 0) {
|
|
506
|
+
ctx.mdepth = parseInt(mt_caller.substring(x + 1, y));
|
|
507
|
+
var z = mt_caller.indexOf(',', y + 1);
|
|
508
|
+
if (z < 0) {
|
|
509
|
+
ctx.mcaller_txid = Hexa32.toLong32(mt_caller.substring(y + 1));
|
|
510
|
+
} else {
|
|
511
|
+
ctx.mcaller_txid = Hexa32.toLong32(mt_caller.substring(y + 1, z));
|
|
512
|
+
|
|
513
|
+
var z2 = mt_caller.indexOf(',', z + 1);
|
|
514
|
+
if (z2 < 0) {
|
|
515
|
+
ctx.mcaller_stepId = Hexa32.toLong32(mt_caller.substring(z + 1));
|
|
516
|
+
} else {
|
|
517
|
+
ctx.mcaller_stepId = Hexa32.toLong32(mt_caller.substring(z + 1, z2));
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
if (conf.stat_mtrace_enabled) {
|
|
524
|
+
var inf=req.headers[conf._trace_mtrace_spec_key1];
|
|
525
|
+
if(inf != null && inf.length > 0){
|
|
526
|
+
var px = inf.indexOf(',');
|
|
527
|
+
ctx.mcaller_spec = inf.substring(0, px);
|
|
528
|
+
ctx.mcaller_url = inf.substring(px + 1);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
} catch(e) {
|
|
532
|
+
Logger.printError('WHATAP-850', 'Multi Server Transaction ', e, true);
|
|
533
|
+
}
|
|
423
534
|
}
|
|
424
535
|
|
|
425
536
|
return ctx;
|
|
@@ -543,6 +654,15 @@ HttpObserver.prototype.__endTransaction = function(error, ctx, req, res) {
|
|
|
543
654
|
wtx.mcaller_okind = ctx.mcaller_okind;
|
|
544
655
|
wtx.mcaller_oid = ctx.mcaller_oid;
|
|
545
656
|
|
|
657
|
+
wtx.appctx = "";
|
|
658
|
+
wtx.txName = ctx.service_name;
|
|
659
|
+
if(ctx.error_class) wtx.error_class = ctx.error_class;
|
|
660
|
+
if(ctx.error_message) wtx.error_message = ctx.error_message;
|
|
661
|
+
|
|
662
|
+
if(conf.getProperty('txtext_txname_enabled', true)){
|
|
663
|
+
wtx.txName = ctx.service_name;
|
|
664
|
+
}
|
|
665
|
+
|
|
546
666
|
MeterService.add(wtx.service, wtx.elapsed,
|
|
547
667
|
wtx.errorLevel, ctx.mcaller_pcode, ctx.mcaller_okind, ctx.mcaller_oid);
|
|
548
668
|
|
|
@@ -780,7 +900,8 @@ HttpObserver.prototype.inject = function( mod, moduleName ) {
|
|
|
780
900
|
if (ctx.error.isZero()) {
|
|
781
901
|
ctx.error = step.error;
|
|
782
902
|
ctx.statusCode = err.code;
|
|
783
|
-
ctx.statusMessage = err.message;
|
|
903
|
+
ctx.statusMessage = ctx.error_message = err.message;
|
|
904
|
+
|
|
784
905
|
}
|
|
785
906
|
}
|
|
786
907
|
|
|
@@ -893,4 +1014,13 @@ var toParamBytes = function (p, crc) {
|
|
|
893
1014
|
}
|
|
894
1015
|
};
|
|
895
1016
|
|
|
1017
|
+
function createMtraceId(userAgentString) {
|
|
1018
|
+
// MTraceHelper.createId 구현
|
|
1019
|
+
if (userAgentString) {
|
|
1020
|
+
// userAgent 기반으로 ID 생성
|
|
1021
|
+
return KeyGen.next();
|
|
1022
|
+
}
|
|
1023
|
+
return KeyGen.next();
|
|
1024
|
+
}
|
|
1025
|
+
|
|
896
1026
|
exports.HttpObserver = HttpObserver;
|
|
@@ -20,7 +20,6 @@ var TraceContextManager = require('../trace/trace-context-manager'),
|
|
|
20
20
|
TextTypes = require('../lang/text-types'),
|
|
21
21
|
ParamSecurity = require('../util/paramsecurity'),
|
|
22
22
|
Logger = require('../logger'),
|
|
23
|
-
conf = require('../conf/configure'),
|
|
24
23
|
DateUtil = require('../util/dateutil'),
|
|
25
24
|
Buffer = require('buffer').Buffer,
|
|
26
25
|
shimmer = require('../core/shimmer'),
|
|
@@ -161,8 +161,11 @@ MongodbObserver.prototype.inject = function( mod, moduleName ) {
|
|
|
161
161
|
request.step.elapsed = event.duration;
|
|
162
162
|
request.ctx.sql_time += request.step.elapsed;
|
|
163
163
|
|
|
164
|
+
request.ctx.error_class = event.failure.name || (event.failure.constructor && event.failure.constructor.name) || 'MongoDBError';
|
|
165
|
+
request.ctx.error_message = event.failure.message || 'MongoDB error';
|
|
166
|
+
|
|
164
167
|
var msgObj = { 'class': event.failure.message, 'msg': event.failure.message };
|
|
165
|
-
request.step.error = StatError.addError("
|
|
168
|
+
request.step.error = StatError.addError("mongodb", event.failure.message,
|
|
166
169
|
request.ctx.service_hash, TextTypes.SQL, request.step.hash);
|
|
167
170
|
if (request.ctx.error.isZero()) {
|
|
168
171
|
request.ctx.error = request.step.error;
|