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.
@@ -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
- var poid=req.headers['x-wtap-po'];
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
- try{
386
- var mt_caller=req.headers[conf._trace_mtrace_caller_key];
387
- if(mt_caller){
388
- var x = mt_caller.indexOf(',');
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
- var y = mt_caller.indexOf(',', x + 1);
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
- var z = mt_caller.indexOf(',', y + 1);
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
- var inf=req.headers[conf._trace_mtrace_spec_key1];
413
- if(inf != null && inf.length > 0){
414
- var px = inf.indexOf(',');
415
- ctx.mcaller_spec = inf.substring(0, px);
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 ', e, true);
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("mogodb", event.failure.message,
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;