whatap 0.5.0 → 0.5.1

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.
@@ -264,6 +264,8 @@ var ConfigDefault = {
264
264
  "grpc_profile_stream_client_enabled": bool("grpc_profile_stream_client_enabled", true),
265
265
  "grpc_profile_stream_server_enabled": bool("grpc_profile_stream_server_enabled", true),
266
266
  "grpc_profile_ignore_method": bool("grpc_profile_ignore_method", true),
267
+
268
+ "oname_port_postfix_enabled": bool("oname_port_postfix_enabled", false),
267
269
  };
268
270
 
269
271
  ConfigDefault._hook_method_ignore_prefix = ConfigDefault.hook_method_ignore_prefixes.split(',');
@@ -105,7 +105,7 @@ var SecurityMaster = {
105
105
  }
106
106
 
107
107
  //OidUtil.setCmd(Configuration.getProperty("sun.java.command"));
108
- this.ONAME = OidUtil.mkOname(Configuration.getProperty("whatap.name", name_pattern));
108
+ this.ONAME = OidUtil.mkOname(Configuration.getProperty("whatap.name", name_pattern), port);
109
109
  this.OID = OidUtil.mkOid(this.ONAME);
110
110
 
111
111
  if (lastOid != this.OID) {
@@ -15,12 +15,20 @@ const KeyGen = require("../util/keygen");
15
15
  const HashUtil = require("../util/hashutil");
16
16
  const DataTextAgent = require("../data/datatext-agent");
17
17
  const shimmer = require('../core/shimmer');
18
+ const StatError = require("../stat/stat-error");
19
+ const TextTypes = require("../lang/text-types");
20
+ const URLPatternDetector = require('../trace/serviceurl-pattern-detector').Detector;
18
21
 
19
22
  var GlobalObserver = function (agent) {
20
23
  this.agent = agent;
21
24
  this.packages = ['global'];
22
25
  }
23
26
 
27
+ var transaction_status_error_enable = conf.getProperty('transaction_status_error_enable', true);
28
+ conf.on('transaction_status_error_enable', function (newProps) {
29
+ transaction_status_error_enable = newProps;
30
+ })
31
+
24
32
  GlobalObserver.prototype.inject = function (mod, moduleName) {
25
33
  var self = this;
26
34
 
@@ -37,7 +45,7 @@ GlobalObserver.prototype.inject = function (mod, moduleName) {
37
45
  });
38
46
 
39
47
  shimmer.wrap(mod, 'fetch', function(original) {
40
- return function(...args) {
48
+ return async function(...args) {
41
49
  var info = args[1] ? args[1] : {};
42
50
  var ctx = TraceContextManager._asyncLocalStorage.getStore();
43
51
 
@@ -45,51 +53,103 @@ GlobalObserver.prototype.inject = function (mod, moduleName) {
45
53
  interTxTraceAutoOn(ctx);
46
54
 
47
55
  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
- }
56
+ addTraceHeaders(info, ctx);
61
57
  args[1] = info;
62
58
  }
63
59
  }
64
60
 
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;
61
+ try {
62
+ const response = await original.apply(this, args);
63
+ handleResponse(ctx, args, response);
64
+ return response;
65
+ } catch (e) {
66
+ handleError(ctx, args, e);
67
+ throw e;
68
+ }
89
69
  };
90
70
  });
91
71
  };
92
72
 
73
+ function addTraceHeaders(info, ctx) {
74
+ if (info.headers) {
75
+ info.headers['x-wtap-po'] = transferPOID(ctx);
76
+ } else {
77
+ info.headers = {
78
+ 'x-wtap-po': transferPOID(ctx)
79
+ };
80
+ }
81
+ if (conf.stat_mtrace_enabled) {
82
+ info.headers[conf._trace_mtrace_spec_key1] = transferSPEC_URL(ctx);
83
+ }
84
+ if (conf.mtid_mtrace_enabled && ctx.mtid.isZero() === false) {
85
+ info.headers[conf._trace_mtrace_caller_key] = transferMTID_CALLERTX(ctx);
86
+ }
87
+ }
88
+
89
+ function handleResponse(ctx, args, response) {
90
+ if (!ctx || !args[0]) return;
91
+
92
+ const url = new URL(args[0]);
93
+ setupContext(ctx, url);
94
+
95
+ var step = createStep(ctx, url);
96
+
97
+ if (!response.ok && transaction_status_error_enable) {
98
+ recordError(ctx, step, response);
99
+ }
100
+
101
+ ctx.profile.push(step);
102
+ }
103
+
104
+ function handleError(ctx, args, error) {
105
+ if (!ctx || !args[0]) return;
106
+
107
+ const url = new URL(args[0]);
108
+ setupContext(ctx, url);
109
+
110
+ var step = createStep(ctx, url);
111
+
112
+ if (transaction_status_error_enable) {
113
+ recordError(ctx, step, error);
114
+ }
115
+
116
+ ctx.profile.push(step);
117
+ }
118
+
119
+ function setupContext(ctx, url) {
120
+ ctx.httpc_host = url.hostname;
121
+ ctx.httpc_url = url.pathname;
122
+ ctx.httpc_port = url.port || (url.protocol === 'https:' ? 443 : 80);
123
+ }
124
+
125
+ function createStep(ctx, url) {
126
+ var step = new HttpStepX();
127
+ step.start_time = ctx.getElapsedTime();
128
+ step.url = HashUtil.hashFromString(ctx.httpc_url);
129
+ DataTextAgent.HTTPC_URL.add(step.url, ctx.httpc_url);
130
+ step.host = HashUtil.hashFromString(ctx.httpc_host);
131
+ DataTextAgent.HTTPC_HOST.add(step.host, ctx.httpc_host);
132
+ step.port = ctx.httpc_port;
133
+ return step;
134
+ }
135
+
136
+ function recordError(ctx, step, response) {
137
+ if (step.error.isZero()) {
138
+ var cleanUrl = ctx.httpc_url.split('?')[0];
139
+ ctx.service_name = URLPatternDetector.normalize(cleanUrl);
140
+ ctx.service_hash = HashUtil.hashFromString(ctx.service_name);
141
+
142
+ const errorMessage = response.statusText || (response.cause ? response.cause.message : '') || response.message || 'Unknown error';
143
+ step.error = StatError.addError(response.status || null, errorMessage, ctx.service_hash, TextTypes.HTTPC_URL, step.url);
144
+
145
+ if (ctx.error.isZero()) {
146
+ ctx.error = step.error;
147
+ ctx.statusCode = response.status || null;
148
+ ctx.statusMessage = errorMessage;
149
+ }
150
+ }
151
+ }
152
+
93
153
  var transfer_poid;
94
154
  function transferPOID(ctx) {
95
155
  if (transfer_poid)
@@ -51,13 +51,10 @@ const types = {
51
51
  bidi: 'bidi'
52
52
  };
53
53
 
54
- var _module;
55
-
56
54
  GRpcObserver.prototype.inject = function(mod, moduleName) {
57
55
  if (mod.__whatap_observe__) {
58
56
  return;
59
57
  }
60
- _module = mod;
61
58
  mod.__whatap_observe__ = true;
62
59
  Logger.initPrint("GRpcObserver");
63
60
 
@@ -244,6 +244,9 @@ function initCtx(req, res) {
244
244
  if (ignore_build_file_enabled && ignore_build_file_path && ignore_build_file_path.split(',').some(path => req.url.startsWith(path))) {
245
245
  return null;
246
246
  }
247
+ if( conf.getProperty('profile_enabled', true) === false ) {
248
+ return null;
249
+ }
247
250
 
248
251
  var ctx = TraceContextManager.start();
249
252
  if(ctx == null) { return null; }
@@ -649,7 +652,7 @@ HttpObserver.prototype.inject = function( mod, moduleName ) {
649
652
  if(mod.__whatap_observe__) { return; }
650
653
  mod.__whatap_observe__ = true;
651
654
  Logger.initPrint("HttpObserver");
652
- if( conf.profile_enabled === false ) { return; }
655
+ if( conf.getProperty('profile_enabled', true) === false ) { return; }
653
656
 
654
657
  aop.after(mod, 'createServer', function (obj, args, ret) {
655
658
  aop.before(ret, 'listen', function (obj, args) {
@@ -41,7 +41,6 @@ ProcessObserver.prototype._hookNextTick = function (mod) {
41
41
  ProcessObserver.prototype._hookStdOutWrite = function () {
42
42
  this.agent.aop.after(process.stdout, 'write', (obj, args) => {
43
43
  if (conf.getProperty('logsink_enabled', false) && args[0]) {
44
- return;
45
44
  let content = typeof args[0] === 'string' ? args[0] : (args[0].message || '');
46
45
  try {
47
46
  const parsedContent = JSON.parse(content);
@@ -58,7 +57,6 @@ ProcessObserver.prototype._hookStdOutWrite = function () {
58
57
  ProcessObserver.prototype._hookStdErrWrite = function () {
59
58
  this.agent.aop.after(process.stderr, 'write', (obj, args) => {
60
59
  if (conf.getProperty('logsink_enabled', false) && args[0]) {
61
- return;
62
60
  let content = typeof args[0] === 'string' ? args[0] : (args[0].message || '');
63
61
  try {
64
62
  const parsedContent = JSON.parse(content);
@@ -169,8 +169,13 @@ RedisObserver.prototype.inject = function (mod, modName) {
169
169
  }
170
170
  }
171
171
  }, function (obj, args, ret, lctx) {
172
+ var ctx = lctx.context;
173
+ if (!ctx) {
174
+ return;
175
+ }
176
+
172
177
  var selectCommand = new Set(['get', 'hget', 'hmget', 'zrange', 'smembers', 'lrange']);
173
- var insertCommand = new Set(['set', 'hset', 'hmset', 'zadd', 'lset', 'sadd', 'lpush', 'rpush']);
178
+ var insertCommand = new Set(['set', 'hset', 'hmset', 'zadd', 'lset', 'sadd', 'lpush', 'rpush', 'evalsha']);
174
179
  var updateCommand = new Set(['set', 'lset', 'hset', 'zadd']);
175
180
  var deleteCommand = new Set(['del', 'lrem', 'srem', 'hdel', 'zrem']);
176
181
  var commands = new Set([...selectCommand, ...insertCommand, ...updateCommand, ...deleteCommand]);
@@ -180,10 +185,10 @@ RedisObserver.prototype.inject = function (mod, modName) {
180
185
  }
181
186
  var command = args[0].name;
182
187
  if(commands.has(command.toLowerCase())){
183
- var ctx = TraceContextManager.getCurrentContext();
184
- if (ctx == null) {
185
- return;
186
- }
188
+ // var ctx = TraceContextManager.getCurrentContext();
189
+ // if (ctx == null) {
190
+ // return;
191
+ // }
187
192
 
188
193
  var dbc_step = new DBCStep();
189
194
  dbc_step.hash = ioredis_dbc_hash;
@@ -4,27 +4,24 @@
4
4
  * can be found in the LICENSE file.
5
5
  */
6
6
 
7
- var MeterSocketio = require('../counter/meter/meter-socket.io'),
8
- TraceContextManager = require('../trace/trace-context-manager'),
7
+ var TraceContextManager = require('../trace/trace-context-manager'),
9
8
  SocketStep = require('../step/socket-step'),
10
9
  conf = require('../conf/configure'),
11
10
  IPUtil = require('../util/iputil'),
12
11
  Logger = require('../logger');
13
- const {Detector: URLPatternDetector} = require("whatap/lib/trace/serviceurl-pattern-detector");
14
- const HashUtil = require("whatap/lib/util/hashutil");
15
- const DataTextAgent = require("whatap/lib/data/datatext-agent");
16
- const ResourceProfile = require("whatap/lib/util/resourceprofile");
12
+ const {Detector: URLPatternDetector} = require("../trace/serviceurl-pattern-detector");
13
+ const DataTextAgent = require("../data/datatext-agent");
14
+ const ResourceProfile = require("../util/resourceprofile");
17
15
  const ProfilePack = require('../pack/profile-pack');
18
16
  const TxRecord = require('../service/tx-record');
19
17
  const DateUtil = require('../util/dateutil');
20
18
  const SecurityMaster = require('../net/security-master');
21
19
  const DataProfileAgent = require('../data/dataprofile-agent');
22
- const MessageStep = require("whatap/lib/step/message-step");
23
- const MeterUsers = require("whatap/lib/counter/meter/meter-users");
24
- const DataPackSender = require("whatap/lib/data/datapack-sender");
20
+ const MeterUsers = require("../counter/meter/meter-users");
25
21
  const MeterService = require('../counter/meter/meter-service').MeterService;
22
+ const shimmer = require('../core/shimmer');
26
23
 
27
- var trace_background_socket_enabled = conf.getProperty('trace_background_socket_enabled', false);
24
+ var trace_background_socket_enabled = conf.getProperty('trace_background_socket_enabled', true);
28
25
  conf.on('trace_background_socket_enabled', function (newProps) {
29
26
  trace_background_socket_enabled = newProps;
30
27
  })
@@ -55,66 +52,78 @@ SocketIOObserver.prototype.inject = function (mod, moduleName) {
55
52
  Logger.initPrint("SocketIOObserver");
56
53
 
57
54
  var self = this;
58
- var aop = self.agent.aop;
59
55
 
60
- aop.after(mod.Server.prototype, 'on', function (obj, args, ret, lctx) {
61
- aop.after(mod.Socket.prototype, 'emit', function (_obj, _args, _ret, _lctx) {
62
- if(!trace_background_socket_enabled) {
63
- return;
56
+ shimmer.wrap(mod.prototype, 'on', function (original) {
57
+ return function (event, listener) {
58
+ if (event === 'connection') {
59
+ return original.call(this, event, function (socket) {
60
+ shimmer.wrap(socket, 'emit', function (origEmit) {
61
+ return function (emitEvent, ...args) {
62
+ if (trace_background_socket_enabled) {
63
+ self.__handleSocketEmitEvent(socket, emitEvent, args);
64
+ }
65
+
66
+ return origEmit.apply(this, [emitEvent, ...args]);
67
+ };
68
+ });
69
+
70
+ return listener.apply(this, [socket]);
71
+ });
64
72
  }
65
- if(trace_sampling_enabled){
66
- var now = Date.now();
67
- if(!socket_count.start_time) {
68
- socket_count.start_time = now;
69
- }
70
-
71
- if ((now - socket_count.start_time) > 5000) {
72
- socket_count.start_time = now;
73
- socket_count.count = 0;
74
- }
75
-
76
- socket_count.count++;
77
- if(socket_count.count > trace_sampling_tps) {
78
- MeterService.add(0, 1, 0, 0, 0, 0);
79
- return;
80
- }
73
+
74
+ return original.call(this, event, listener);
75
+ };
76
+ });
77
+ };
78
+
79
+ SocketIOObserver.prototype.__handleSocketEmitEvent = function(socket, event, args) {
80
+ if (trace_sampling_enabled) {
81
+ var now = Date.now();
82
+ if (!socket_count.start_time) {
83
+ socket_count.start_time = now;
84
+ }
85
+
86
+ if ((now - socket_count.start_time) > 5000) {
87
+ socket_count.start_time = now;
88
+ socket_count.count = 0;
89
+ }
90
+
91
+ socket_count.count++;
92
+ if (socket_count.count > trace_sampling_tps) {
93
+ MeterService.add(0, 1, 0, 0, 0, 0);
94
+ return;
95
+ }
96
+ }
97
+
98
+ TraceContextManager._asyncLocalStorage.run(initCtx(socket, args), () => {
99
+ try {
100
+ var ctx = TraceContextManager._asyncLocalStorage.getStore();
101
+ if (!ctx) return;
102
+
103
+ ctx.footprint('Socket Emit Event: ' + event);
104
+
105
+ var host;
106
+ if (socket.conn && socket.conn.remoteAddress && socket.conn.remoteAddress.includes(':')) {
107
+ host = socket.conn.remoteAddress.substring(socket.conn.remoteAddress.lastIndexOf(':') + 1);
81
108
  }
82
109
 
83
- TraceContextManager._asyncLocalStorage.run(initCtx(_obj, _args), () => {
84
- try{
85
- var ctx = TraceContextManager._asyncLocalStorage.getStore();
86
- if (!ctx) {
87
- return;
88
- }
89
-
90
- var socket = _obj;
91
- var host;
92
- if (socket.handshake && socket.handshake.address && socket.handshake.address.includes(':')) {
93
- host = socket.handshake.address.substring(socket.handshake.address.lastIndexOf(':') + 1);
94
- }
95
-
96
- ctx.socket_connecting = true;
97
- ctx.footprint('Socket Connecting: ' + host);
98
-
99
- var step = new SocketStep();
100
- step.start_time = ctx.getElapsedTime();
101
- step.ipaddr = Buffer.from(IPUtil.stringToBytes(host));
102
- // step.port = port;
103
-
104
- ctx.socket_connecting = false;
105
- step.elapsed = ctx.getElapsedTime() - step.start_time;
106
- ctx.profile.push(step);
107
-
108
- ctx.footprint('Socket Connecting Done');
109
-
110
- self.__endTransaction(null, ctx);
111
- return;
112
- }catch (e) {
113
- Logger.printError('WHATAP-616', 'socket.io transaction error..', e, false);
114
- return;
115
- }
116
- });
117
- });
110
+ ctx.socket_connecting = true;
111
+ ctx.footprint('Socket Connecting: ' + host);
112
+
113
+ var step = new SocketStep();
114
+ step.start_time = ctx.getElapsedTime();
115
+ step.ipaddr = Buffer.from(IPUtil.stringToBytes(host));
116
+ // step.port = port;
117
+
118
+ ctx.socket_connecting = false;
119
+ step.elapsed = ctx.getElapsedTime() - step.start_time;
120
+ ctx.profile.push(step)
121
+
122
+ this.__endTransaction(null, ctx);
123
+
124
+ } catch (e) {
125
+ Logger.printError('WHATAP-616', 'socket.io emit transaction error..', e, false);
126
+ }
118
127
  });
119
128
  };
120
129
 
@@ -163,7 +172,7 @@ function initCtx(socket, args) {
163
172
  if (!ctx) {return;}
164
173
 
165
174
  var remote_addr;
166
- const address = socket.handshake.address;
175
+ const address = socket.conn.remoteAddress;
167
176
  if(address && address.includes(':')){
168
177
  remote_addr = address.substring(address.lastIndexOf(':')+1);
169
178
  }
@@ -54,7 +54,7 @@ var OidUtil = {
54
54
  mkOid: function(oname){
55
55
  return HashUtil.hash(Buffer.from(oname));
56
56
  },
57
- mkOname: function(pattern){
57
+ mkOname: function(pattern, port){
58
58
  var conf = require('./../conf/configure');
59
59
  var startBrace = "{";
60
60
  var endBrace = "}";
@@ -83,6 +83,9 @@ var OidUtil = {
83
83
  pattern = pattern.replace(keyFull, key);
84
84
  }
85
85
  };
86
+ if(conf.getProperty('oname_port_postfix_enabled', false) && port){
87
+ pattern = pattern + '-' + port;
88
+ }
86
89
  return pattern;
87
90
  },
88
91
  toString: function(){
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "whatap",
3
3
  "homepage": "http://www.whatap.io",
4
- "version": "0.5.0",
5
- "releaseDate": "20240812",
4
+ "version": "0.5.1",
5
+ "releaseDate": "20240828",
6
6
  "description": "Monitoring and Profiling Service",
7
7
  "main": "index.js",
8
8
  "scripts": {},