whatap 0.4.97 → 0.5.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.
Files changed (39) hide show
  1. package/lib/conf/config-default.js +11 -3
  2. package/lib/conf/configure.js +32 -19
  3. package/lib/conf/log-config-default.js +37 -0
  4. package/lib/control/control-handler.js +19 -6
  5. package/lib/core/agent.js +12 -9
  6. package/lib/core/shimmer.js +98 -0
  7. package/lib/counter/task/agentinfo.js +1 -1
  8. package/lib/data/datapack-sender.js +22 -0
  9. package/lib/data/dataprofile-agent.js +17 -1
  10. package/lib/data/zipprofile.js +2 -2
  11. package/lib/logger.js +25 -1
  12. package/lib/logsink/line-log-util.js +87 -0
  13. package/lib/logsink/line-log.js +12 -0
  14. package/lib/logsink/log-sender.js +78 -0
  15. package/lib/logsink/log-tracer.js +40 -0
  16. package/lib/logsink/sender-util.js +51 -0
  17. package/lib/logsink/zip/zip-send.js +177 -0
  18. package/lib/net/paramdef.js +1 -0
  19. package/lib/net/security-master.js +10 -5
  20. package/lib/observers/global-observer.js +140 -0
  21. package/lib/observers/grpc-observer.js +339 -0
  22. package/lib/observers/http-observer.js +7 -7
  23. package/lib/observers/process-observer.js +57 -8
  24. package/lib/observers/redis-observer.js +69 -11
  25. package/lib/observers/websocket-observer.js +1 -1
  26. package/lib/pack/event-pack.js +1 -1
  27. package/lib/pack/log-sink-pack.js +139 -0
  28. package/lib/pack/packenum.js +3 -1
  29. package/lib/pack/zip-pack.js +0 -1
  30. package/lib/stat/{stat-remoteip.js → stat-remote-ip.js} +8 -8
  31. package/lib/stat/stat-remote-ipurl.js +88 -0
  32. package/lib/stat/timingsender.js +4 -1
  33. package/lib/topology/link.js +63 -0
  34. package/lib/topology/nodeinfo.js +123 -0
  35. package/lib/topology/status-detector.js +111 -0
  36. package/lib/util/compare-util.js +131 -0
  37. package/lib/util/kube-util.js +3 -3
  38. package/lib/util/linkedset.js +278 -0
  39. package/package.json +2 -2
@@ -0,0 +1,87 @@
1
+ const conf = require('../conf/configure');
2
+ const EventPack = require('../pack/event-pack');
3
+ const DataPackSender = require('../data/datapack-sender');
4
+ const Logger = require('../logger');
5
+ const EventLevel = require('../data/event-level');
6
+
7
+ class LineLogUtil {
8
+ constructor() {
9
+ this.last_log = Date.now();
10
+ this.last_alert = Date.now();
11
+ }
12
+
13
+ static getInstance() {
14
+ if (!LineLogUtil.instance) {
15
+ LineLogUtil.instance = new LineLogUtil();
16
+ }
17
+ return LineLogUtil.instance;
18
+ }
19
+
20
+ checkLogContent(lineLog, orgContent) {
21
+ if (!orgContent) {
22
+ return;
23
+ }
24
+
25
+ const len = orgContent.length;
26
+ let maxLength = conf.getProperty('logsink_limit_content_length', 10000);
27
+ if(maxLength > 10000){
28
+ maxLength = 10000;
29
+ }
30
+
31
+ if ((conf.getProperty('logsink_limit_content_enabled', true) && len > maxLength) || len > 10000) {
32
+ lineLog.content = orgContent.substring(0, maxLength) + " ...(truncated)";
33
+ lineLog.truncated = true;
34
+
35
+ this.addTruncateTag(lineLog);
36
+
37
+ const alertMessage = lineLog.category + " truncated (len=" + len + ")";
38
+ this.logAndAlert(alertMessage);
39
+ } else {
40
+ lineLog.content = orgContent;
41
+ }
42
+ }
43
+
44
+ log(message) {
45
+ if (!conf.getProperty('logsink_max_content_log_enabled', true)) {
46
+ return;
47
+ }
48
+
49
+ const now = Date.now();
50
+ if (now - this.last_log < conf.getProperty('logsink_max_content_log_silent_time', 60000)) {
51
+ return;
52
+ }
53
+ this.last_log = now;
54
+ Logger.print('WHATAP-101', message, false);
55
+ }
56
+
57
+ alertOverflow(message) {
58
+ if (!conf.getProperty('logsink_max_content_alert_enabled', false)) {
59
+ return;
60
+ }
61
+
62
+ const now = Date.now();
63
+ if (now - this.last_alert < conf.getProperty('logsink_max_content_alert_silent_time', 60000)) {
64
+ return;
65
+ }
66
+ this.last_alert = now;
67
+
68
+ const eventPack = new EventPack();
69
+ eventPack.level = EventLevel.FATAL;
70
+ eventPack.title = "LOG_TRUNCATED";
71
+ eventPack.message = "Too big Log: " + message;
72
+ DataPackSender.sendEventPack(eventPack);
73
+ }
74
+
75
+ logAndAlert(alertMessage) {
76
+ this.log(alertMessage);
77
+ this.alertOverflow(alertMessage);
78
+ }
79
+
80
+ addTruncateTag(lineLog) {
81
+ lineLog.tags.putString("truncated", "true");
82
+ }
83
+ }
84
+
85
+ LineLogUtil.instance = null;
86
+
87
+ module.exports = LineLogUtil;
@@ -0,0 +1,12 @@
1
+ const MapValue = require('../value/map-value');
2
+
3
+ var LineLog = function () {
4
+ this.truncated;
5
+ this.time;
6
+ this.category;
7
+ this.tags = new MapValue();
8
+ this.fields = new MapValue();
9
+ this.content;
10
+ }
11
+
12
+ module.exports = LineLog;
@@ -0,0 +1,78 @@
1
+ var Configure = require('../conf/configure');
2
+ var RequestQueue = require('../util/request-queue');
3
+ var Logger = require('../logger');
4
+ var SenderUtil = require('./sender-util');
5
+ var conf = require("../conf/configure");
6
+
7
+ var logsink_enabled = Configure.getProperty('logsink_enabled', false);
8
+ var logsink_queue_size = Configure.getProperty('logsink_queue_size', 1000);
9
+ conf.on('logsink_enabled', function(newProperty) {
10
+ logsink_enabled = newProperty;
11
+ if (logsink_enabled) {
12
+ LogSender.getInstance().startProcessQueue();
13
+ } else {
14
+ LogSender.getInstance().stopProcessQueue();
15
+ LogSender.resetInstance();
16
+ }
17
+ });
18
+
19
+ class LogSender {
20
+ constructor() {
21
+ if (LogSender.instance) {
22
+ return LogSender.instance;
23
+ }
24
+ this.queue = new RequestQueue(logsink_queue_size);
25
+ this.isProcessing = false;
26
+ LogSender.instance = this;
27
+
28
+ if (logsink_enabled) {
29
+ this.startProcessQueue();
30
+ }
31
+ }
32
+
33
+ static getInstance() {
34
+ if (!LogSender.instance) {
35
+ LogSender.instance = new LogSender();
36
+ }
37
+ return LogSender.instance;
38
+ }
39
+
40
+ static resetInstance() {
41
+ if(LogSender.instance){
42
+ LogSender.instance = null;
43
+ }
44
+ }
45
+
46
+ add(log) {
47
+ this.queue.put(log);
48
+ }
49
+
50
+ async processQueue() {
51
+ this.isProcessing = true;
52
+
53
+ while (this.isProcessing) {
54
+ var log = await this.queue.get();
55
+ if(log){
56
+ try {
57
+ var sendUtil = new SenderUtil();
58
+ sendUtil.send(log);
59
+ } catch (error) {
60
+ Logger.printError('WHATAP-702', 'Error occurred during send LogSinkPack.' + error, false);
61
+ }
62
+ }
63
+ await new Promise(resolve => setTimeout(resolve, 100));
64
+ }
65
+ }
66
+
67
+ startProcessQueue() {
68
+ if (!this.isProcessing) {
69
+ this.processQueue();
70
+ }
71
+ }
72
+
73
+ stopProcessQueue() {
74
+ this.isProcessing = false;
75
+ }
76
+ }
77
+
78
+ module.exports = LogSender;
@@ -0,0 +1,40 @@
1
+ var conf = require('../conf/configure');
2
+ var LineLog = require('./line-log');
3
+ var LineLogUtil = require('./line-log-util');
4
+ var LogSender = require('./log-sender');
5
+ var TraceContextManager = require('../trace/trace-context-manager');
6
+
7
+ var LogTracer = function () {
8
+ this.logSender = LogSender.getInstance();
9
+ }
10
+
11
+ LogTracer.prototype.addStdWrite = function (content, category) {
12
+ var lineLog = new LineLog();
13
+ lineLog.category = category
14
+
15
+ var lineLogUtil = LineLogUtil.getInstance();
16
+ lineLogUtil.checkLogContent(lineLog, content);
17
+
18
+ if(lineLog.content){
19
+ this.addTxTag(lineLog);
20
+ this.logSender.add(lineLog)
21
+ }
22
+ }
23
+
24
+ LogTracer.prototype.addTxTag = function (lineLog) {
25
+ if(!lineLog){
26
+ return;
27
+ }
28
+
29
+ var ctx = TraceContextManager.getCurrentContext();
30
+ if(ctx){
31
+ if(conf.getProperty('logsink_trace_txid_enabled', true) && !ctx.txid.isZero()){
32
+ lineLog.fields.putLong('@txid', ctx.txid);
33
+ }
34
+ if(conf.getProperty('logsink_trace_mtid_enabled', true) && !ctx.mtid.isZero()){
35
+ lineLog.fields.putLong('@mtid', ctx.mtid);
36
+ }
37
+ }
38
+ }
39
+
40
+ module.exports = LogTracer;
@@ -0,0 +1,51 @@
1
+ var conf = require('../conf/configure');
2
+ var SecurityMaster = require('../net/security-master');
3
+ var LogSinkPack = require('../pack/log-sink-pack');
4
+ var DataPackSender = require('../data/datapack-sender');
5
+ var DateUtil = require('../util/dateutil')
6
+ var ZipSend = require('./zip/zip-send');
7
+
8
+ function SenderUtil() {
9
+ this.conf = conf;
10
+ this.secu = SecurityMaster;
11
+ }
12
+
13
+ SenderUtil.prototype.send = function (log) {
14
+ const p = new LogSinkPack();
15
+ p.time = log.time;
16
+ if (!p.time) {
17
+ p.time = DateUtil.currentTime();
18
+ }
19
+ p.category = log.category;
20
+
21
+ if (this.secu.ONAME) {
22
+ p.tags.putString('oname', this.secu.ONAME);
23
+ }
24
+ if (this.conf.OKIND) {
25
+ p.tags.putString('okindName', this.conf.OKIND_NAME);
26
+ }
27
+ if (this.conf.ONODE) {
28
+ p.tags.putString('onodeName', this.conf.ONODE_NAME);
29
+ }
30
+
31
+ if (log.tags != null) {
32
+ p.tags.putAllMapValue(log.tags);
33
+ }
34
+ if (log.fields != null) {
35
+ if (p.fields == null) {
36
+ p.fields = log.fields;
37
+ } else {
38
+ p.fields.putAllMapValue(log.fields);
39
+ }
40
+ }
41
+
42
+ p.content = log.content;
43
+
44
+ if(conf.getProperty('logsink_zip_enabled', false)){
45
+ ZipSend.getInstance().add(p);
46
+ }else{
47
+ DataPackSender.sendLogSinkPack(p)
48
+ }
49
+ };
50
+
51
+ module.exports = SenderUtil;
@@ -0,0 +1,177 @@
1
+ /**
2
+ * Copyright 2016 the WHATAP project authors. All rights reserved.
3
+ * Use of this source code is governed by a license that
4
+ * can be found in the LICENSE file.
5
+ */
6
+
7
+ var conf = require('../../conf/configure'),
8
+ DateUtil = require('../../util/dateutil'),
9
+ RequestQueue = require('../../util/request-queue'),
10
+ DataPackSender = require('../../data/datapack-sender'),
11
+ DataOutputX = require('../../io/data-outputx'),
12
+ ZipPack = require('../../pack/zip-pack'),
13
+ Logger = require('../../logger');
14
+ var zlib = require('zlib');
15
+
16
+ var logsink_enabled = conf.getProperty('logsink_enabled', false);
17
+ var logsink_zip_enabled = conf.getProperty('logsink_zip_enabled', false);
18
+ var logsink_max_buffer_size = conf.getProperty('logsink_max_buffer_size', 1024*64);
19
+ var profile_zip_min_size = conf.getProperty('profile_zip_min_size', 100)
20
+ var logsink_queue_size = conf.getProperty('logsink_queue_size', 500);
21
+ var logsink_max_wait_time = conf.getProperty('logsink_max_wait_time', 2000);
22
+ conf.on('logsink_enabled', function(newProperty) {
23
+ logsink_enabled = newProperty;
24
+ if (logsink_enabled && logsink_zip_enabled) {
25
+ ZipSend.getInstance().startProcessQueue();
26
+ } else {
27
+ ZipSend.getInstance().stopProcessQueue();
28
+ ZipSend.resetInstance();
29
+ }
30
+ });
31
+ conf.on('logsink_zip_enabled', function(newProperty) {
32
+ logsink_zip_enabled = newProperty;
33
+ if (logsink_enabled && logsink_zip_enabled) {
34
+ ZipSend.getInstance().startProcessQueue();
35
+ } else {
36
+ ZipSend.getInstance().stopProcessQueue();
37
+ ZipSend.resetInstance();
38
+ }
39
+ });
40
+
41
+ class ZipSend {
42
+ constructor() {
43
+ if (ZipSend.instance) {
44
+ return ZipSend.instance;
45
+ }
46
+ this.queue = new RequestQueue(logsink_queue_size);
47
+ this.buffer = Buffer.alloc(0);
48
+ this.packCount = 0;
49
+ this.first_time = null;
50
+ this.isProcessing = false;
51
+ ZipSend.instance = this;
52
+
53
+ if (logsink_enabled && logsink_zip_enabled) {
54
+ this.startProcessQueue();
55
+ }
56
+ }
57
+
58
+ static getInstance() {
59
+ if (!ZipSend.instance) {
60
+ ZipSend.instance = new ZipSend();
61
+ }
62
+ return ZipSend.instance;
63
+ }
64
+
65
+ static resetInstance() {
66
+ if(ZipSend.instance){
67
+ ZipSend.instance = null;
68
+ }
69
+ }
70
+
71
+ add(p){
72
+ var ok = this.queue.put(p);
73
+ if(!ok){
74
+ DataPackSender.sendLogSinkPack(p);
75
+ }
76
+ }
77
+
78
+ // async addWait(p, waitTimeForFull) {
79
+ // var ok = this.queue.put(p);
80
+ // if (ok === false){
81
+ // if(waitTimeForFull > 0){
82
+ // while(this.queue.put(p) === false){
83
+ // await new Promise(resolve => setTimeout(resolve, waitTimeForFull));
84
+ // }
85
+ // }
86
+ // }
87
+ // }
88
+
89
+ async processQueue() {
90
+ this.isProcessing = true;
91
+ while (this.isProcessing) {
92
+ if(!logsink_enabled || !logsink_zip_enabled) {
93
+ this.isProcessing = false;
94
+ break;
95
+ }
96
+
97
+ const p = await this.queue.getByTimeout(logsink_max_wait_time);
98
+ if(p) {
99
+ await this.append(p);
100
+ }else{
101
+ await this.sendAndClear();
102
+ }
103
+ await new Promise(resolve => setTimeout(resolve, 100));
104
+ }
105
+ }
106
+
107
+ async append(p) {
108
+ var b = DataOutputX.toBytesPack(p);
109
+ this.packCount++;
110
+ this.buffer = Buffer.concat([this.buffer, b]);
111
+
112
+ if(!this.first_time){
113
+ this.first_time = p.time;
114
+ if (this.buffer.length >= logsink_max_buffer_size) {
115
+ await this.sendAndClear();
116
+ }
117
+ }else{
118
+ if(this.buffer.length >= logsink_max_buffer_size || (p.time - this.first_time) >= conf.getProperty('logsink_max_wait_time', 2000)){
119
+ await this.sendAndClear();
120
+ }
121
+ }
122
+ }
123
+
124
+ async sendAndClear() {
125
+ if(this.buffer.length === 0){ return; }
126
+
127
+ var p = new ZipPack();
128
+ p.time = DateUtil.currentTime();
129
+ p.recordCount = this.packCount;
130
+ p.records = this.buffer;
131
+
132
+ await this.doZip(p);
133
+ if(conf.getProperty('debug_logsink_zip_enabled', false)){
134
+ Logger.print('WHATAP-703', `zip status=${p.status} records=${p.recordCount} | ${this.buffer.length} => ${p.records.length}`);
135
+ }
136
+ DataPackSender.sendLogSinkPack(p);
137
+
138
+ this.buffer = Buffer.alloc(0);
139
+ this.first_time = 0;
140
+ this.packCount = 0;
141
+ }
142
+
143
+ async doZip(p){
144
+ if(p.status !== 0){ return; }
145
+ if(p.records.length < profile_zip_min_size){ return; }
146
+ p.status = 1;
147
+
148
+ try{
149
+ p.records = await this._doZip(p.records);
150
+ }catch (error) {
151
+ Logger.print('WHATAP-701', 'Error occurred during compression.' + error, false);
152
+ }
153
+ }
154
+
155
+ _doZip(data) {
156
+ return new Promise((resolve, reject) => {
157
+ zlib.gzip(data, (err, buffer) => {
158
+ if (err) {
159
+ reject(err);
160
+ } else {
161
+ resolve(buffer);
162
+ }
163
+ });
164
+ });
165
+ }
166
+
167
+ startProcessQueue() {
168
+ if (!this.isProcessing) {
169
+ this.processQueue()
170
+ }
171
+ }
172
+ stopProcessQueue() {
173
+ this.isProcessing = false;
174
+ }
175
+ }
176
+
177
+ module.exports = ZipSend;
@@ -34,6 +34,7 @@ exports.AGENT_LOG_READ = 23;
34
34
 
35
35
  exports.GET_ACTIVE_TRANSACTION_LIST = 25;
36
36
  exports.GET_ACTIVE_TRANSACTION_DETAIL = 26;
37
+ exports.GET_TOPOLOGY = 27
37
38
 
38
39
  exports.NODE_MODULE_DEPENDENCY = 101;
39
40
 
@@ -90,9 +90,11 @@ var SecurityMaster = {
90
90
  this.OKIND_NAME=null;
91
91
  }
92
92
 
93
- if(Configuration.getProperty('whatap_micro_enabled', false) === false || process.env.WHATAP_MICRO_ENABLED === "true") {
94
- var onodeStr= process.env.WHATAP_ONODE || Configuration.getProperty('whatap.onode');
95
- console.log(onodeStr)
93
+ const whatapMicroEnabledConfig = Configuration.getProperty('whatap_micro_enabled', false);
94
+ const whatapMicroEnabledEnv = process.env.WHATAP_MICRO_ENABLED;
95
+
96
+ if (!whatapMicroEnabledConfig || whatapMicroEnabledEnv === undefined || whatapMicroEnabledEnv === "false") {
97
+ var onodeStr= process.env.WHATAP_ONODE || process.env.NODE_NAME || Configuration.getProperty('whatap.onode', null);
96
98
  if(onodeStr && onodeStr.length>0){
97
99
  this.ONODE = HashUtil.hashFromString(onodeStr);
98
100
  this.ONODE_NAME=onodeStr;
@@ -140,8 +142,11 @@ var SecurityMaster = {
140
142
  this.OKIND_NAME=null;
141
143
  }
142
144
 
143
- if(Configuration.getProperty('whatap_micro_enabled', false) === false || process.env.WHATAP_MICRO_ENABLED === "true") {
144
- var onodeStr= process.env.WHATAP_ONODE || Configuration.getProperty('whatap.onode');
145
+ const whatapMicroEnabledConfig = Configuration.getProperty('whatap_micro_enabled', false);
146
+ const whatapMicroEnabledEnv = process.env.WHATAP_MICRO_ENABLED;
147
+
148
+ if (!whatapMicroEnabledConfig || whatapMicroEnabledEnv === undefined || whatapMicroEnabledEnv === "false") {
149
+ var onodeStr= process.env.WHATAP_ONODE || process.env.NODE_NAME || Configuration.getProperty('whatap.onode', null);
145
150
  if(onodeStr && onodeStr.length>0){
146
151
  this.ONODE = HashUtil.hashFromString(onodeStr);
147
152
  this.ONODE_NAME=onodeStr;
@@ -7,6 +7,15 @@
7
7
  var TraceContextManager = require('../trace/trace-context-manager'),
8
8
  Logger = require('../logger');
9
9
 
10
+ var HttpStepX = require('../step/http-stepx');
11
+ const Hexa32 = require("../util/hexa32");
12
+ const SecurityMaster = require("../net/security-master");
13
+ const conf = require("../conf/configure");
14
+ const KeyGen = require("../util/keygen");
15
+ const HashUtil = require("../util/hashutil");
16
+ const DataTextAgent = require("../data/datatext-agent");
17
+ const shimmer = require('../core/shimmer');
18
+
10
19
  var GlobalObserver = function (agent) {
11
20
  this.agent = agent;
12
21
  this.packages = ['global'];
@@ -26,6 +35,137 @@ GlobalObserver.prototype.inject = function (mod, moduleName) {
26
35
  });
27
36
  });
28
37
  });
38
+
39
+ shimmer.wrap(mod, 'fetch', function(original) {
40
+ return function(...args) {
41
+ var info = args[1] ? args[1] : {};
42
+ var ctx = TraceContextManager._asyncLocalStorage.getStore();
43
+
44
+ if (ctx) {
45
+ interTxTraceAutoOn(ctx);
46
+
47
+ if (conf.mtrace_enabled) {
48
+ if (info.headers) {
49
+ info.headers['x-wtap-po'] = transferPOID(ctx);
50
+ } else {
51
+ info.headers = {
52
+ 'x-wtap-po': transferPOID(ctx)
53
+ };
54
+ }
55
+ if (conf.stat_mtrace_enabled) {
56
+ info.headers[conf._trace_mtrace_spec_key1] = transferSPEC_URL(ctx);
57
+ }
58
+ if (conf.mtid_mtrace_enabled && ctx.mtid.isZero() === false) {
59
+ info.headers[conf._trace_mtrace_caller_key] = transferMTID_CALLERTX(ctx);
60
+ }
61
+ args[1] = info;
62
+ }
63
+ }
64
+
65
+ const promise = original.apply(this, args);
66
+
67
+ promise.then(response => {
68
+ var ctx = TraceContextManager._asyncLocalStorage.getStore();
69
+ if (ctx && args[0]) {
70
+ const url = new URL(args[0]);
71
+ ctx.httpc_host = url.hostname;
72
+ ctx.httpc_url = url.pathname;
73
+ ctx.httpc_port = url.port || (url.protocol === 'https:' ? 443 : 80);
74
+
75
+ var step = new HttpStepX();
76
+ step.start_time = ctx.getElapsedTime();
77
+ step.url = HashUtil.hashFromString(ctx.httpc_url);
78
+ DataTextAgent.HTTPC_URL.add(step.url, ctx.httpc_url);
79
+ step.host = HashUtil.hashFromString(ctx.httpc_host);
80
+ DataTextAgent.HTTPC_HOST.add(step.host, ctx.httpc_host);
81
+ step.port = ctx.httpc_port;
82
+
83
+ ctx.profile.push(step);
84
+ }
85
+ }).catch(e => {
86
+ Logger.printError("WHATAP-704", "Promise error occurred during fetch: " + e, false);
87
+ });
88
+ return promise;
89
+ };
90
+ });
29
91
  };
30
92
 
93
+ var transfer_poid;
94
+ function transferPOID(ctx) {
95
+ if (transfer_poid)
96
+ return transfer_poid;
97
+ transfer_poid = Hexa32.toString32(SecurityMaster.PCODE) + ','
98
+ + Hexa32.toString32(SecurityMaster.OKIND) + ',' + Hexa32.toString32(SecurityMaster.OID);
99
+ return transfer_poid;
100
+ }
101
+
102
+ function transferMTID_CALLERTX(ctx) {
103
+ if (ctx.transfer_id)
104
+ return ctx.transfer_id;
105
+ var x = Hexa32.toString32(ctx.mtid) + ',' + (ctx.mdepth + 1) + ',' + Hexa32.toString32(ctx.txid);
106
+ ctx.transfer_id = x;
107
+ return ctx.transfer_id;
108
+ }
109
+
110
+ function transferSPEC_URL(ctx) {
111
+ if (ctx.transfer_info)
112
+ return ctx.transfer_info;
113
+ var x = conf.mtrace_spec + ',' + ctx.service_hash;
114
+ ctx.transfer_info = x;
115
+ return ctx.transfer_info;
116
+ }
117
+
118
+ var check_seq = 1;
119
+ function interTxTraceAutoOn(ctx) {
120
+ if (conf.mtrace_enabled == false || ctx.httpc_checked || ctx.mtid.isZero() === false)
121
+ return;
122
+ ctx.httpc_checked = true;
123
+ if (conf.mtrace_rate >= 100) {
124
+ ctx.mtid = KeyGen.next();
125
+ return;
126
+ }
127
+ check_seq++;
128
+ switch (Math.floor(conf.mtrace_rate / 10)) {
129
+ case 10:
130
+ ctx.mtid = KeyGen.next();
131
+ break;
132
+ case 9:
133
+ if (check_seq % 10 !== 0)
134
+ ctx.mtid = KeyGen.next();
135
+ break;
136
+ case 8:
137
+ if (check_seq % 5 !== 0)
138
+ ctx.mtid = KeyGen.next();
139
+ break;
140
+ case 7:
141
+ if (check_seq % 4 !== 0)
142
+ ctx.mtid = KeyGen.next();
143
+ break;
144
+ case 6:
145
+ if (check_seq % 3 !== 0)
146
+ ctx.mtid = KeyGen.next();
147
+ break;
148
+ case 5:
149
+ if (check_seq % 2 === 0)
150
+ ctx.mtid = KeyGen.next();
151
+ break;
152
+ case 4:
153
+ if (check_seq % 3 === 0 || check_seq % 5 === 0)
154
+ ctx.mtid = KeyGen.next();
155
+ break;
156
+ case 3:
157
+ if (check_seq % 4 === 0 || check_seq % 5 === 0)
158
+ ctx.mtid = KeyGen.next();
159
+ break;
160
+ case 2:
161
+ if (check_seq % 5 === 0)
162
+ ctx.mtid = KeyGen.next();
163
+ break;
164
+ case 1:
165
+ if (check_seq % 10 === 0)
166
+ ctx.mtid = KeyGen.next();
167
+ break;
168
+ }
169
+ }
170
+
31
171
  exports.GlobalObserver = GlobalObserver;