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.
- package/lib/conf/config-default.js +11 -3
- package/lib/conf/configure.js +32 -19
- package/lib/conf/log-config-default.js +37 -0
- package/lib/control/control-handler.js +19 -6
- package/lib/core/agent.js +12 -9
- package/lib/core/shimmer.js +98 -0
- package/lib/counter/task/agentinfo.js +1 -1
- package/lib/data/datapack-sender.js +22 -0
- package/lib/data/dataprofile-agent.js +17 -1
- package/lib/data/zipprofile.js +2 -2
- package/lib/logger.js +25 -1
- package/lib/logsink/line-log-util.js +87 -0
- package/lib/logsink/line-log.js +12 -0
- package/lib/logsink/log-sender.js +78 -0
- package/lib/logsink/log-tracer.js +40 -0
- package/lib/logsink/sender-util.js +51 -0
- package/lib/logsink/zip/zip-send.js +177 -0
- package/lib/net/paramdef.js +1 -0
- package/lib/net/security-master.js +10 -5
- package/lib/observers/global-observer.js +140 -0
- package/lib/observers/grpc-observer.js +339 -0
- package/lib/observers/http-observer.js +7 -7
- package/lib/observers/process-observer.js +57 -8
- package/lib/observers/redis-observer.js +69 -11
- package/lib/observers/websocket-observer.js +1 -1
- package/lib/pack/event-pack.js +1 -1
- package/lib/pack/log-sink-pack.js +139 -0
- package/lib/pack/packenum.js +3 -1
- package/lib/pack/zip-pack.js +0 -1
- package/lib/stat/{stat-remoteip.js → stat-remote-ip.js} +8 -8
- package/lib/stat/stat-remote-ipurl.js +88 -0
- package/lib/stat/timingsender.js +4 -1
- package/lib/topology/link.js +63 -0
- package/lib/topology/nodeinfo.js +123 -0
- package/lib/topology/status-detector.js +111 -0
- package/lib/util/compare-util.js +131 -0
- package/lib/util/kube-util.js +3 -3
- package/lib/util/linkedset.js +278 -0
- package/package.json +2 -2
|
@@ -0,0 +1,339 @@
|
|
|
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 TraceContextManager = require('../trace/trace-context-manager'),
|
|
8
|
+
conf = require('../conf/configure'),
|
|
9
|
+
Logger = require('../logger');
|
|
10
|
+
const { Detector: URLPatternDetector } = require("../trace/serviceurl-pattern-detector");
|
|
11
|
+
const HashUtil = require("../util/hashutil");
|
|
12
|
+
const DataTextAgent = require("../data/datatext-agent");
|
|
13
|
+
const ResourceProfile = require("../util/resourceprofile");
|
|
14
|
+
const ProfilePack = require('../pack/profile-pack');
|
|
15
|
+
const TxRecord = require('../service/tx-record');
|
|
16
|
+
const DateUtil = require('../util/dateutil');
|
|
17
|
+
const SecurityMaster = require('../net/security-master');
|
|
18
|
+
const DataProfileAgent = require("../data/dataprofile-agent");
|
|
19
|
+
const MessageStep = require("../step/message-step");
|
|
20
|
+
const MeterService = require('../counter/meter/meter-service').MeterService;
|
|
21
|
+
|
|
22
|
+
const shimmer = require('../core/shimmer');
|
|
23
|
+
|
|
24
|
+
var grpc_profile_enabled = conf.getProperty('grpc_profile_enabled', true);
|
|
25
|
+
var grpc_profile_stream_client_enabled = conf.getProperty('grpc_profile_stream_client_enabled', true);
|
|
26
|
+
var grpc_profile_stream_server_enabled = conf.getProperty('grpc_profile_stream_server_enabled', true);
|
|
27
|
+
var grpc_profile_ignore_method = conf.getProperty('grpc_profile_ignore_method', '');
|
|
28
|
+
var ignore_method_set = null;
|
|
29
|
+
conf.on('grpc_profile_enabled', function(newProperty) {
|
|
30
|
+
grpc_profile_enabled = newProperty;
|
|
31
|
+
});
|
|
32
|
+
conf.on('grpc_profile_stream_client_enabled', function(newProperty) {
|
|
33
|
+
grpc_profile_stream_client_enabled = newProperty;
|
|
34
|
+
});
|
|
35
|
+
conf.on('grpc_profile_stream_server_enabled', function(newProperty) {
|
|
36
|
+
grpc_profile_stream_server_enabled = newProperty;
|
|
37
|
+
});
|
|
38
|
+
conf.on('grpc_profile_ignore_method', function(newProperty) {
|
|
39
|
+
grpc_profile_ignore_method = newProperty;
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
var GRpcObserver = function(agent) {
|
|
43
|
+
this.agent = agent;
|
|
44
|
+
this.packages = ['@grpc/grpc-js'];
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const types = {
|
|
48
|
+
unary: 'unary',
|
|
49
|
+
client_stream: 'clientStream',
|
|
50
|
+
server_stream: 'serverStream',
|
|
51
|
+
bidi: 'bidi'
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
var _module;
|
|
55
|
+
|
|
56
|
+
GRpcObserver.prototype.inject = function(mod, moduleName) {
|
|
57
|
+
if (mod.__whatap_observe__) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
_module = mod;
|
|
61
|
+
mod.__whatap_observe__ = true;
|
|
62
|
+
Logger.initPrint("GRpcObserver");
|
|
63
|
+
|
|
64
|
+
if (grpc_profile_enabled) {
|
|
65
|
+
shimmer.wrap(mod.Server.prototype, 'register', wrapRegister);
|
|
66
|
+
shimmer.wrap(mod.Client.prototype, 'register', wrapRegister);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
function checkIgnoreMethod(ignore_method, method_name){
|
|
71
|
+
try{
|
|
72
|
+
if (ignore_method) {
|
|
73
|
+
ignore_method_set = new Set(ignore_method.split(','));
|
|
74
|
+
} else {
|
|
75
|
+
ignore_method_set = null;
|
|
76
|
+
}
|
|
77
|
+
if (ignore_method_set && ignore_method_set.has(method_name)) {
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
}catch (e) {
|
|
81
|
+
Logger.printError('WHATAP-703', 'gRPC checkIgnoreMethod error: ' + e, false);
|
|
82
|
+
}
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function wrapHandler(handler, methodName, type) {
|
|
87
|
+
return function(call, callback) {
|
|
88
|
+
var method_name = methodName.includes('/') ? methodName.substring(methodName.lastIndexOf('/')+1, methodName.length) : methodName
|
|
89
|
+
if (!grpc_profile_enabled || checkIgnoreMethod(conf.getProperty('grpc_profile_ignore_method', ''), method_name)) {
|
|
90
|
+
return handler.call(this, call, callback);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
TraceContextManager._asyncLocalStorage.run(initCtx(), () => {
|
|
94
|
+
try {
|
|
95
|
+
var ctx = TraceContextManager._asyncLocalStorage.getStore();
|
|
96
|
+
if (!ctx) {
|
|
97
|
+
return handler.call(this, call, callback);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
ctx.service_name = methodName;
|
|
101
|
+
ctx.service_hash = HashUtil.hashFromString(methodName);
|
|
102
|
+
|
|
103
|
+
var step_type = new MessageStep();
|
|
104
|
+
step_type.hash = HashUtil.hashFromString('Type');
|
|
105
|
+
step_type.start_time = ctx.getElapsedTime();
|
|
106
|
+
step_type.desc = type;
|
|
107
|
+
DataTextAgent.MESSAGE.add(step_type.hash, "Type");
|
|
108
|
+
ctx.profile.push(step_type);
|
|
109
|
+
|
|
110
|
+
var step_method = new MessageStep();
|
|
111
|
+
step_method.hash = HashUtil.hashFromString('Method');
|
|
112
|
+
step_method.start_time = ctx.getElapsedTime();
|
|
113
|
+
step_method.desc = method_name;
|
|
114
|
+
DataTextAgent.MESSAGE.add(step_method.hash, "Method");
|
|
115
|
+
ctx.profile.push(step_method);
|
|
116
|
+
|
|
117
|
+
if(call.request && Object.keys(call.request).length > 0){
|
|
118
|
+
var step_param = new MessageStep();
|
|
119
|
+
step_param.hash = HashUtil.hashFromString('Parameter');
|
|
120
|
+
step_param.start_time = ctx.getElapsedTime();
|
|
121
|
+
step_param.desc = JSON.stringify(Object.keys(call.request));
|
|
122
|
+
DataTextAgent.MESSAGE.add(step_param.hash, "Parameter");
|
|
123
|
+
ctx.profile.push(step_param);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
console.log(call.pendingStatus)
|
|
127
|
+
|
|
128
|
+
ctx.grpc_method = method_name;
|
|
129
|
+
|
|
130
|
+
function wrappedCallback(err, response, ctx) {
|
|
131
|
+
|
|
132
|
+
if (err) {
|
|
133
|
+
ctx.error = err.stack;
|
|
134
|
+
ctx.statusCode = 500;
|
|
135
|
+
|
|
136
|
+
var step_error = new MessageStep();
|
|
137
|
+
step_error.hash = HashUtil.hashFromString("EXCEPTION");
|
|
138
|
+
step_error.start_time = ctx.getElapsedTime();
|
|
139
|
+
step_error.desc = err.stack;
|
|
140
|
+
DataTextAgent.MESSAGE.add(step_error.hash, "EXCEPTION");
|
|
141
|
+
ctx.profile.push(step_error);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
endTransaction(ctx);
|
|
145
|
+
|
|
146
|
+
if (typeof callback === 'function') {
|
|
147
|
+
return callback(err, response);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return handler.call(this, call, (err, response) => wrappedCallback(err, response, ctx));
|
|
152
|
+
// return handler.call(this, call, (err, response) => {
|
|
153
|
+
// if (!err) {
|
|
154
|
+
// err = new Error('Exception error occured');
|
|
155
|
+
// }
|
|
156
|
+
// wrappedCallback(err, response, ctx);
|
|
157
|
+
} catch (err) {
|
|
158
|
+
Logger.printError('WHATAP-701', 'gRPC wrapHandler error: ' + err, false);
|
|
159
|
+
|
|
160
|
+
ctx.error = err.stack;
|
|
161
|
+
|
|
162
|
+
var step_error = new MessageStep();
|
|
163
|
+
step_error.hash = HashUtil.hashFromString("EXCEPTION");
|
|
164
|
+
step_error.start_time = ctx.getElapsedTime();
|
|
165
|
+
step_error.desc = err.stack;
|
|
166
|
+
DataTextAgent.MESSAGE.add(step_error.hash, "EXCEPTION");
|
|
167
|
+
ctx.profile.push(step_error);
|
|
168
|
+
|
|
169
|
+
endTransaction(ctx);
|
|
170
|
+
|
|
171
|
+
return handler.call(this, call, callback);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function wrapStreamHandler(handler, methodName, type) {
|
|
178
|
+
return function(call, callback) {
|
|
179
|
+
var method_name = methodName.includes('/') ? methodName.substring(methodName.lastIndexOf('/')+1, methodName.length) : methodName
|
|
180
|
+
if (!grpc_profile_enabled || checkIgnoreMethod(conf.getProperty('grpc_profile_ignore_method', ''), method_name)) {
|
|
181
|
+
return handler.call(this, call, callback);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
switch (type) {
|
|
185
|
+
case 'server_stream':
|
|
186
|
+
if (!grpc_profile_stream_server_enabled) {
|
|
187
|
+
return handler.call(this, call, callback);
|
|
188
|
+
}
|
|
189
|
+
break;
|
|
190
|
+
case 'client_stream':
|
|
191
|
+
if (!grpc_profile_stream_client_enabled) {
|
|
192
|
+
return handler.call(this, call, callback);
|
|
193
|
+
}
|
|
194
|
+
break;
|
|
195
|
+
case 'bidi':
|
|
196
|
+
if (!grpc_profile_stream_server_enabled || !grpc_profile_stream_client_enabled) {
|
|
197
|
+
return handler.call(this, call, callback);
|
|
198
|
+
}
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
TraceContextManager._asyncLocalStorage.run(initCtx(), () => {
|
|
203
|
+
try {
|
|
204
|
+
var ctx = TraceContextManager._asyncLocalStorage.getStore();
|
|
205
|
+
if (!ctx) {
|
|
206
|
+
return handler.call(this, call, callback);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
ctx.service_name = methodName;
|
|
210
|
+
ctx.service_hash = HashUtil.hashFromString(methodName);
|
|
211
|
+
|
|
212
|
+
var step_type = new MessageStep();
|
|
213
|
+
step_type.hash = HashUtil.hashFromString('Type');
|
|
214
|
+
step_type.start_time = ctx.getElapsedTime();
|
|
215
|
+
step_type.desc = type;
|
|
216
|
+
DataTextAgent.MESSAGE.add(step_type.hash, "Type");
|
|
217
|
+
ctx.profile.push(step_type);
|
|
218
|
+
|
|
219
|
+
var step_method = new MessageStep();
|
|
220
|
+
step_method.hash = HashUtil.hashFromString('Method');
|
|
221
|
+
step_method.start_time = ctx.getElapsedTime();
|
|
222
|
+
step_method.desc = method_name;
|
|
223
|
+
DataTextAgent.MESSAGE.add(step_method.hash, "Method");
|
|
224
|
+
ctx.profile.push(step_method);
|
|
225
|
+
|
|
226
|
+
ctx.grpc_method = method_name;
|
|
227
|
+
|
|
228
|
+
const startTime = Date.now();
|
|
229
|
+
|
|
230
|
+
call.on('end', () => {
|
|
231
|
+
const duration = Date.now() - startTime;
|
|
232
|
+
endTransaction(ctx);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
call.once('cancelled', () => {
|
|
236
|
+
ctx.cancelled = true;
|
|
237
|
+
var step_cancel = new MessageStep();
|
|
238
|
+
step_cancel.hash = HashUtil.hashFromString("CANCELLED");
|
|
239
|
+
step_cancel.start_time = ctx.getElapsedTime();
|
|
240
|
+
step_cancel.desc = "Request cancelled";
|
|
241
|
+
DataTextAgent.MESSAGE.add(step_cancel.hash, "CANCELLED");
|
|
242
|
+
ctx.profile.push(step_cancel);
|
|
243
|
+
endTransaction(ctx);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
call.on('error', (err) => {
|
|
247
|
+
ctx.error = err.stack;
|
|
248
|
+
ctx.statusCode = err.code || grpc.status.INTERNAL;
|
|
249
|
+
|
|
250
|
+
var step_error = new MessageStep();
|
|
251
|
+
step_error.hash = HashUtil.hashFromString("EXCEPTION");
|
|
252
|
+
step_error.start_time = ctx.getElapsedTime();
|
|
253
|
+
step_error.desc = err.stack;
|
|
254
|
+
DataTextAgent.MESSAGE.add(step_error.hash, "EXCEPTION");
|
|
255
|
+
ctx.profile.push(step_error);
|
|
256
|
+
|
|
257
|
+
endTransaction(ctx);
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
return handler.call(this, call);
|
|
261
|
+
} catch (e) {
|
|
262
|
+
Logger.printError('WHATAP-702', 'gRPC wrapStreamHandler error: ' + e, false);
|
|
263
|
+
return handler.call(this, call);
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function wrapRegister(register) {
|
|
270
|
+
return function(name, handler, serialize, deserialize, type) {
|
|
271
|
+
if (typeof handler === 'function') {
|
|
272
|
+
switch (type) {
|
|
273
|
+
case types.client_stream:
|
|
274
|
+
handler = wrapStreamHandler(handler, name, 'clientStream');
|
|
275
|
+
break;
|
|
276
|
+
case types.server_stream:
|
|
277
|
+
handler = wrapStreamHandler(handler, name, 'serverStream');
|
|
278
|
+
break;
|
|
279
|
+
case types.bidi:
|
|
280
|
+
handler = wrapStreamHandler(handler, name, 'bidi');
|
|
281
|
+
break;
|
|
282
|
+
case types.unary:
|
|
283
|
+
default:
|
|
284
|
+
handler = wrapHandler(handler, name, 'unary');
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return register.call(this, name, handler, serialize, deserialize, type);
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function endTransaction(ctx) {
|
|
292
|
+
try {
|
|
293
|
+
var profile = new ProfilePack();
|
|
294
|
+
var wtx = new TxRecord();
|
|
295
|
+
wtx.endTime = DateUtil.currentTime();
|
|
296
|
+
profile.time = wtx.endTime;
|
|
297
|
+
wtx.elapsed = ctx.getElapsedTime();
|
|
298
|
+
|
|
299
|
+
DataTextAgent.SERVICE.add(ctx.service_hash, ctx.service_name);
|
|
300
|
+
|
|
301
|
+
wtx.seq = ctx.txid;
|
|
302
|
+
wtx.service = ctx.service_hash;
|
|
303
|
+
wtx.cpuTime = ResourceProfile.getCPUTime() - ctx.start_cpu;
|
|
304
|
+
wtx.malloc = ResourceProfile.getUsedHeapSize() - ctx.start_malloc;
|
|
305
|
+
if (wtx.malloc < 0) { wtx.malloc = 0; }
|
|
306
|
+
wtx.status = 2;
|
|
307
|
+
wtx.http_method = ctx.grpc_method;
|
|
308
|
+
|
|
309
|
+
wtx.ipaddr = ctx.remoteIp;
|
|
310
|
+
|
|
311
|
+
MeterService.add(wtx.service, wtx.elapsed,
|
|
312
|
+
wtx.errorLevel, ctx.mcaller_pcode, ctx.mcaller_okind, ctx.mcaller_oid);
|
|
313
|
+
|
|
314
|
+
profile.oid = SecurityMaster.OID;
|
|
315
|
+
profile.service = wtx;
|
|
316
|
+
|
|
317
|
+
TraceContextManager.end(ctx._id);
|
|
318
|
+
|
|
319
|
+
setTimeout(function() {
|
|
320
|
+
DataProfileAgent.sendProfile(ctx, profile, false);
|
|
321
|
+
ctx = null;
|
|
322
|
+
}, 100);
|
|
323
|
+
} catch (e) {
|
|
324
|
+
Logger.printError('WHATAP-615', 'Websocket end transaction error..', e, false);
|
|
325
|
+
TraceContextManager.end(ctx._id);
|
|
326
|
+
ctx = null;
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
function initCtx() {
|
|
331
|
+
const ctx = TraceContextManager.start();
|
|
332
|
+
if (!ctx) { return; }
|
|
333
|
+
|
|
334
|
+
ctx.start_malloc = ResourceProfile.getUsedHeapSize();
|
|
335
|
+
ctx.start_cpu = ResourceProfile.getCPUTime();
|
|
336
|
+
return ctx;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
exports.GRpcObserver = GRpcObserver;
|
|
@@ -59,8 +59,8 @@ var httpc_not_found_ignore_time = conf.getProperty('httpc_not_found_ignore_time'
|
|
|
59
59
|
var profile_http_header_ignore_keys = conf.getProperty('profile_http_header_ignore_keys', 'Cookie,cookie,accept,user-agent,referer');
|
|
60
60
|
var profile_http_parameter_enabled = conf.getProperty('profile_http_parameter_enabled', true);
|
|
61
61
|
var profile_http_parameter_keys = conf.getProperty('profile_http_parameter_keys', '');
|
|
62
|
-
var
|
|
63
|
-
var
|
|
62
|
+
var ignore_build_file_enabled = conf.getProperty('ignore_build_file_enabled', true);
|
|
63
|
+
var ignore_build_file_path = conf.getProperty('ignore_build_file_path', '/_next/');
|
|
64
64
|
conf.on('trace_http_client_ip_header_key', function(newProperty) {
|
|
65
65
|
configIpHeaderKey = newProperty;
|
|
66
66
|
});
|
|
@@ -118,11 +118,11 @@ conf.on('profile_http_parameter_enabled', function (newProps) {
|
|
|
118
118
|
conf.on('profile_http_parameter_keys', function (newProps) {
|
|
119
119
|
profile_http_parameter_keys = newProps;
|
|
120
120
|
})
|
|
121
|
-
conf.on('
|
|
122
|
-
|
|
121
|
+
conf.on('ignore_build_file_enabled', function (newProps) {
|
|
122
|
+
ignore_build_file_enabled = newProps;
|
|
123
123
|
})
|
|
124
|
-
conf.on('
|
|
125
|
-
|
|
124
|
+
conf.on('ignore_build_file_path', function (newProps) {
|
|
125
|
+
ignore_build_file_path = newProps;
|
|
126
126
|
})
|
|
127
127
|
var staticConents = function (newProps) {
|
|
128
128
|
var x=new Set();
|
|
@@ -241,7 +241,7 @@ function initCtx(req, res) {
|
|
|
241
241
|
/*url이 없으면 추적하지 않는다*/
|
|
242
242
|
if(!req.url) { return null; }
|
|
243
243
|
if(ignore_http_method && ignore_http_method.toUpperCase().split(',').includes(req.method)) { return null; }
|
|
244
|
-
if (
|
|
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
247
|
|
|
@@ -4,23 +4,72 @@
|
|
|
4
4
|
* can be found in the LICENSE file.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
const TraceContextManager = require('../trace/trace-context-manager');
|
|
8
|
+
const conf = require('../conf/configure');
|
|
9
|
+
const LogTracer = require('../logsink/log-tracer');
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
let logsink_enabled = conf.getProperty('logsink_enabled', false);
|
|
12
|
+
let logTracer = logsink_enabled ? new LogTracer() : null;
|
|
13
|
+
|
|
14
|
+
conf.on('logsink_enabled', function(newProperty) {
|
|
15
|
+
logsink_enabled = newProperty;
|
|
16
|
+
logTracer = logsink_enabled ? new LogTracer() : null;
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const ProcessObserver = function (agent) {
|
|
10
20
|
this.agent = agent;
|
|
11
21
|
this.packages = ['process'];
|
|
12
22
|
};
|
|
23
|
+
|
|
13
24
|
ProcessObserver.prototype.inject = function (mod, moduleName) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
25
|
+
this._hookNextTick(mod);
|
|
26
|
+
this._hookStdOutWrite();
|
|
27
|
+
this._hookStdErrWrite();
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
ProcessObserver.prototype._hookNextTick = function (mod) {
|
|
31
|
+
this.agent.aop.before(mod, 'nextTick', (obj, args) => {
|
|
32
|
+
const cached_id = TraceContextManager.getCurrentId();
|
|
33
|
+
this.agent.aop.functionHook(args, -1, (obj, args) => {
|
|
34
|
+
if (cached_id != null) {
|
|
19
35
|
TraceContextManager.resume(cached_id);
|
|
20
|
-
cached_id = null;
|
|
21
36
|
}
|
|
22
37
|
});
|
|
23
38
|
});
|
|
24
39
|
};
|
|
25
40
|
|
|
41
|
+
ProcessObserver.prototype._hookStdOutWrite = function () {
|
|
42
|
+
this.agent.aop.after(process.stdout, 'write', (obj, args) => {
|
|
43
|
+
if (conf.getProperty('logsink_enabled', false) && args[0]) {
|
|
44
|
+
return;
|
|
45
|
+
let content = typeof args[0] === 'string' ? args[0] : (args[0].message || '');
|
|
46
|
+
try {
|
|
47
|
+
const parsedContent = JSON.parse(content);
|
|
48
|
+
content = parsedContent.message ? parsedContent.message : JSON.stringify(parsedContent);
|
|
49
|
+
} catch (e) {
|
|
50
|
+
}
|
|
51
|
+
if (logTracer && content) {
|
|
52
|
+
logTracer.addStdWrite(content, conf.logsink_category_stdout);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
ProcessObserver.prototype._hookStdErrWrite = function () {
|
|
59
|
+
this.agent.aop.after(process.stderr, 'write', (obj, args) => {
|
|
60
|
+
if (conf.getProperty('logsink_enabled', false) && args[0]) {
|
|
61
|
+
return;
|
|
62
|
+
let content = typeof args[0] === 'string' ? args[0] : (args[0].message || '');
|
|
63
|
+
try {
|
|
64
|
+
const parsedContent = JSON.parse(content);
|
|
65
|
+
content = parsedContent.message ? parsedContent.message : JSON.stringify(parsedContent);
|
|
66
|
+
} catch (e) {
|
|
67
|
+
}
|
|
68
|
+
if (logTracer && content) {
|
|
69
|
+
logTracer.addStdWrite(content, conf.logsink_category_stderr);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
|
|
26
75
|
module.exports.ProcessObserver = ProcessObserver;
|
|
@@ -6,12 +6,12 @@ var TraceContextManager = require('../trace/trace-context-manager'),
|
|
|
6
6
|
HashUtil = require('../util/hashutil'),
|
|
7
7
|
Long = require('long'),
|
|
8
8
|
Logger = require('../logger');
|
|
9
|
-
|
|
9
|
+
const shimmer = require('../core/shimmer');
|
|
10
10
|
|
|
11
11
|
var RedisObserver = function (agent) {
|
|
12
12
|
this.agent = agent;
|
|
13
13
|
this.aop = agent.aop;
|
|
14
|
-
this.packages = ['redis'];
|
|
14
|
+
this.packages = ['redis', 'ioredis'];
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
RedisObserver.prototype.inject = function (mod, modName) {
|
|
@@ -23,13 +23,13 @@ RedisObserver.prototype.inject = function (mod, modName) {
|
|
|
23
23
|
Logger.initPrint("RedisObserver");
|
|
24
24
|
var self = this;
|
|
25
25
|
|
|
26
|
-
var dbc_hash= 0;
|
|
26
|
+
var dbc_hash = 0;
|
|
27
27
|
var dbc;
|
|
28
28
|
var dbc_time;
|
|
29
29
|
self.aop.both(mod, 'createClient',
|
|
30
30
|
function (obj, args, lctx) {
|
|
31
|
-
if(dbc_hash === 0){
|
|
32
|
-
if(args.length > 0) {
|
|
31
|
+
if (dbc_hash === 0) {
|
|
32
|
+
if (args.length > 0) {
|
|
33
33
|
var info = (args[0] || {});
|
|
34
34
|
dbc = 'redis://';
|
|
35
35
|
dbc += info.host || '';
|
|
@@ -43,13 +43,15 @@ RedisObserver.prototype.inject = function (mod, modName) {
|
|
|
43
43
|
var selectCommand = new Set(['get', 'hGet', 'hmGet']);
|
|
44
44
|
var insertCommand = new Set(['set', 'hSet', 'hset', 'hmSet', 'hmset', 'zAdd', 'zadd', 'lSet', 'lset']);
|
|
45
45
|
var updateCommand = new Set(['set', 'lSet', 'lset', 'hSet', 'hset', 'zAdd', 'zadd']);
|
|
46
|
-
var deleteCommand = new Set(['del', 'lRem', 'sRem', 'srem', 'hDel',
|
|
46
|
+
var deleteCommand = new Set(['del', 'lRem', 'sRem', 'srem', 'hDel', 'hdel', 'zRem', 'zrem']);
|
|
47
47
|
var commands = new Set([...selectCommand, ...insertCommand, ...updateCommand, ...deleteCommand]);
|
|
48
48
|
commands.forEach(function (command) {
|
|
49
49
|
self.aop.after(ret, command,
|
|
50
50
|
function (obj, args, ret, lctx) {
|
|
51
51
|
var ctx = TraceContextManager.getCurrentContext();
|
|
52
|
-
if(ctx == null) {
|
|
52
|
+
if (ctx == null) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
53
55
|
|
|
54
56
|
var dbc_step = new DBCStep();
|
|
55
57
|
dbc_step.hash = dbc_hash;
|
|
@@ -62,18 +64,18 @@ RedisObserver.prototype.inject = function (mod, modName) {
|
|
|
62
64
|
sql_step = new SqlStepX();
|
|
63
65
|
const key = args[0];
|
|
64
66
|
const values = [];
|
|
65
|
-
for(let i = 1; i < args.length; i++)
|
|
67
|
+
for (let i = 1; i < args.length; i++)
|
|
66
68
|
values.push(args[i]);
|
|
67
69
|
|
|
68
70
|
var sql = 'Redis ' + command + ': ' + JSON.stringify([key]);
|
|
69
|
-
if(values.length > 0)
|
|
70
|
-
|
|
71
|
+
// if (values.length > 0)
|
|
72
|
+
// sql += ' ' + JSON.stringify(values);
|
|
71
73
|
sql_step.hash = HashUtil.hashFromString(sql);
|
|
72
74
|
sql_step.start_time = ctx.getElapsedTime();
|
|
73
75
|
//sql_step.crud = 'I'.charCodeAt(0);
|
|
74
76
|
// DataTextAgent.SQL.add(sql_step.hash, sql);
|
|
75
77
|
ctx.profile.push(sql_step);
|
|
76
|
-
} catch(e) {
|
|
78
|
+
} catch (e) {
|
|
77
79
|
Logger.printError("WHATAP-605", "Redis CRUD error", e, false);
|
|
78
80
|
sql_step = null;
|
|
79
81
|
}
|
|
@@ -152,6 +154,62 @@ RedisObserver.prototype.inject = function (mod, modName) {
|
|
|
152
154
|
// }
|
|
153
155
|
});
|
|
154
156
|
});
|
|
157
|
+
|
|
158
|
+
var ioredis_dbc_hash = 0;
|
|
159
|
+
var ioredis_dbc;
|
|
160
|
+
self.aop.both(mod.prototype, 'sendCommand', function (obj, args, lctx) {
|
|
161
|
+
if (ioredis_dbc_hash === 0) {
|
|
162
|
+
if (obj && Object.keys(obj.options).length > 0) {
|
|
163
|
+
var info = obj.options
|
|
164
|
+
ioredis_dbc = 'redis://';
|
|
165
|
+
ioredis_dbc += info.host || '';
|
|
166
|
+
ioredis_dbc += ':';
|
|
167
|
+
ioredis_dbc += info.port || '';
|
|
168
|
+
ioredis_dbc_hash = HashUtil.hashFromString(ioredis_dbc);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}, function (obj, args, ret, lctx) {
|
|
172
|
+
var selectCommand = new Set(['get', 'hget', 'hmget', 'zrange', 'smembers', 'lrange']);
|
|
173
|
+
var insertCommand = new Set(['set', 'hset', 'hmset', 'zadd', 'lset', 'sadd', 'lpush', 'rpush']);
|
|
174
|
+
var updateCommand = new Set(['set', 'lset', 'hset', 'zadd']);
|
|
175
|
+
var deleteCommand = new Set(['del', 'lrem', 'srem', 'hdel', 'zrem']);
|
|
176
|
+
var commands = new Set([...selectCommand, ...insertCommand, ...updateCommand, ...deleteCommand]);
|
|
177
|
+
|
|
178
|
+
if(!args[0] || (args[0] && !args[0].name)){
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
var command = args[0].name;
|
|
182
|
+
if(commands.has(command.toLowerCase())){
|
|
183
|
+
var ctx = TraceContextManager.getCurrentContext();
|
|
184
|
+
if (ctx == null) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
var dbc_step = new DBCStep();
|
|
189
|
+
dbc_step.hash = ioredis_dbc_hash;
|
|
190
|
+
dbc_step.start_time = ctx.getElapsedTime();
|
|
191
|
+
DataTextAgent.DBC.add(ioredis_dbc_hash, ioredis_dbc);
|
|
192
|
+
ctx.profile.push(dbc_step);
|
|
193
|
+
|
|
194
|
+
var sql_step;
|
|
195
|
+
var args = args[0].args;
|
|
196
|
+
try {
|
|
197
|
+
sql_step = new SqlStepX();
|
|
198
|
+
let key = args[0];
|
|
199
|
+
if(typeof key === 'string')
|
|
200
|
+
key = [key];
|
|
201
|
+
|
|
202
|
+
var sql = 'Redis ' + command + ': ' + JSON.stringify(key);
|
|
203
|
+
sql_step.hash = HashUtil.hashFromString(sql);
|
|
204
|
+
sql_step.start_time = ctx.getElapsedTime();
|
|
205
|
+
DataTextAgent.SQL.add(sql_step.hash, sql);
|
|
206
|
+
ctx.profile.push(sql_step);
|
|
207
|
+
} catch (e) {
|
|
208
|
+
Logger.printError("WHATAP-605", "Redis CRUD error", e, false);
|
|
209
|
+
sql_step = null;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
})
|
|
155
213
|
};
|
|
156
214
|
|
|
157
215
|
exports.RedisObserver = RedisObserver;
|
|
@@ -24,7 +24,7 @@ const MeterUsers = require("whatap/lib/counter/meter/meter-users");
|
|
|
24
24
|
const DataPackSender = require("whatap/lib/data/datapack-sender");
|
|
25
25
|
const MeterService = require('../counter/meter/meter-service').MeterService;
|
|
26
26
|
|
|
27
|
-
var trace_background_socket_enabled = conf.getProperty('trace_background_socket_enabled',
|
|
27
|
+
var trace_background_socket_enabled = conf.getProperty('trace_background_socket_enabled', true);
|
|
28
28
|
conf.on('trace_background_socket_enabled', function (newProps) {
|
|
29
29
|
trace_background_socket_enabled = newProps;
|
|
30
30
|
})
|
package/lib/pack/event-pack.js
CHANGED