whatap 0.5.14 → 0.5.16

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.
@@ -1,10 +1,10 @@
1
1
  'use strict'
2
2
 
3
- function isFunction (funktion) {
3
+ function isFunction(funktion) {
4
4
  return typeof funktion === 'function'
5
5
  }
6
6
 
7
- function defineProperty (obj, name, value) {
7
+ function defineProperty(obj, name, value) {
8
8
  var enumerable = !!obj[name] && obj.propertyIsEnumerable(name)
9
9
  Object.defineProperty(obj, name, {
10
10
  configurable: true,
@@ -14,10 +14,28 @@ function defineProperty (obj, name, value) {
14
14
  })
15
15
  }
16
16
 
17
- var shimmer = function () {
18
- }
17
+ var shimmer = function() {}
18
+
19
+ /**
20
+ * Wrap a single method or multiple methods with the provided wrapper function
21
+ *
22
+ * @param {Object} nodule - The object containing methods to wrap
23
+ * @param {string|Array<string>} name - Method name or array of method names to wrap
24
+ * @param {Function} wrapper - The wrapper function
25
+ * @returns {Function|Array<Function>} - The wrapped function(s)
26
+ */
27
+ var wrap = function(nodule, name, wrapper) {
28
+ // If name is an array, recursively call wrap for each name in the array
29
+ if (Array.isArray(name)) {
30
+ var wrapped = [];
31
+ name.forEach(function(methodName) {
32
+ var result = wrap(nodule, methodName, wrapper);
33
+ if (result) wrapped.push(result);
34
+ });
35
+ return wrapped.length > 0 ? wrapped : undefined;
36
+ }
19
37
 
20
- var wrap = function (nodule, name, wrapper) {
38
+ // Standard single method wrap logic
21
39
  if (!nodule || !nodule[name]) {
22
40
  return;
23
41
  }
@@ -27,67 +45,95 @@ var wrap = function (nodule, name, wrapper) {
27
45
  }
28
46
 
29
47
  if (!isFunction(nodule[name]) || !isFunction(wrapper)) {
30
- return
48
+ return;
31
49
  }
32
50
 
33
- var original = nodule[name]
34
- var wrapped = wrapper(original, name)
51
+ var original = nodule[name];
52
+ var wrapped = wrapper(original, name);
35
53
 
36
- defineProperty(wrapped, '__original', original)
37
- defineProperty(wrapped, '__unwrap', function () {
38
- if (nodule[name] === wrapped) defineProperty(nodule, name, original)
39
- })
40
- defineProperty(wrapped, '__wrapped', true)
54
+ defineProperty(wrapped, '__original', original);
55
+ defineProperty(wrapped, '__unwrap', function() {
56
+ if (nodule[name] === wrapped) defineProperty(nodule, name, original);
57
+ });
58
+ defineProperty(wrapped, '__wrapped', true);
41
59
 
42
- defineProperty(nodule, name, wrapped)
43
- return wrapped
60
+ defineProperty(nodule, name, wrapped);
61
+ return wrapped;
44
62
  }
45
63
 
46
- function unwrap (nodule, name) {
64
+ /**
65
+ * Unwrap a single method or multiple methods
66
+ *
67
+ * @param {Object} nodule - The object containing wrapped methods
68
+ * @param {string|Array<string>} name - Method name or array of method names to unwrap
69
+ */
70
+ function unwrap(nodule, name) {
71
+ // If name is an array, recursively call unwrap for each name in the array
72
+ if (Array.isArray(name)) {
73
+ name.forEach(function(methodName) {
74
+ unwrap(nodule, methodName);
75
+ });
76
+ return;
77
+ }
78
+
47
79
  if (!nodule || !nodule[name]) {
48
- return
80
+ return;
49
81
  }
50
82
 
51
83
  if (!nodule[name].__unwrap) {
84
+ // Method is not wrapped
52
85
  } else {
53
- return nodule[name].__unwrap()
86
+ return nodule[name].__unwrap();
54
87
  }
55
88
  }
56
89
 
57
- function massWrap (nodules, names, wrapper) {
90
+ /**
91
+ * Wrap multiple methods of multiple modules with the same wrapper
92
+ *
93
+ * @param {Object|Array<Object>} nodules - Module or array of modules with methods to wrap
94
+ * @param {Array<string>} names - Array of method names to wrap
95
+ * @param {Function} wrapper - The wrapper function to apply
96
+ */
97
+ function massWrap(nodules, names, wrapper) {
58
98
  if (!nodules) {
59
- return
99
+ return;
60
100
  } else if (!Array.isArray(nodules)) {
61
- nodules = [nodules]
101
+ nodules = [nodules];
62
102
  }
63
103
 
64
104
  if (!(names && Array.isArray(names))) {
65
- return
105
+ return;
66
106
  }
67
107
 
68
- nodules.forEach(function (nodule) {
69
- names.forEach(function (name) {
70
- wrap(nodule, name, wrapper)
71
- })
72
- })
108
+ nodules.forEach(function(nodule) {
109
+ names.forEach(function(name) {
110
+ wrap(nodule, name, wrapper);
111
+ });
112
+ });
73
113
  }
74
114
 
75
- function massUnwrap (nodules, names) {
115
+ /**
116
+ * Unwrap multiple methods of multiple modules
117
+ *
118
+ * @param {Object|Array<Object>} nodules - Module or array of modules with wrapped methods
119
+ * @param {Array<string>} names - Array of method names to unwrap
120
+ */
121
+ function massUnwrap(nodules, names) {
76
122
  if (!nodules) {
77
- return
123
+ return;
78
124
  } else if (!Array.isArray(nodules)) {
79
- nodules = [nodules]
125
+ nodules = [nodules];
80
126
  }
81
127
 
82
128
  if (!(names && Array.isArray(names))) {
83
- return
129
+ return;
84
130
  }
85
131
 
86
- nodules.forEach(function (nodule) {
87
- names.forEach(function (name) {
88
- unwrap(nodule, name)
89
- })
90
- })
132
+ nodules.forEach(function(nodule) {
133
+ names.forEach(function(name) {
134
+ unwrap(nodule, name);
135
+ });
136
+ });
91
137
  }
92
138
 
93
139
  shimmer.wrap = wrap;
@@ -17,7 +17,7 @@ var CounterPack = require('../pack/counter-pack'),
17
17
  GCStat = require('./task/gcstat'),
18
18
  Sql = require('./task/sql'),
19
19
  HttpC = require('./task/httpc'),
20
- // MeteringInfo = require('./task/metering-info'),
20
+ MeteringInfo = require('./task/metering-info'),
21
21
  StatError = require('../stat/stat-error'),
22
22
  TagCounterPack = require('../pack/tagcount-pack'),
23
23
  TraceContextManager = require('../trace/trace-context-manager'),
@@ -55,7 +55,7 @@ CounterManager.prototype.run = function () {
55
55
  tasks.push(new HttpC());
56
56
 
57
57
  // metering
58
- // tasks.push(new MeteringInfo());
58
+ tasks.push(new MeteringInfo());
59
59
  self.intervalIndex = setInterval(function(){
60
60
  self.process(tasks);
61
61
  },5000);
@@ -12,7 +12,8 @@ var CounterTask = require('./counter-task'),
12
12
  fs = require('fs'),
13
13
  TagCountPack = require('../../pack/tagcount-pack'),
14
14
  OType = require('../../pack/otype'),
15
- APEnum = require('../../pack/apenum')
15
+ APEnum = require('../../pack/apenum'),
16
+ Util = require('../../util/index');
16
17
 
17
18
  function MeteringInfo() {
18
19
  CounterTask.call(this);
@@ -47,6 +48,10 @@ MeteringInfo.prototype.process = function (p) {
47
48
  };
48
49
 
49
50
  MeteringInfo.prototype.doProcess = function (p) {
51
+ const host_uuid = this.getHostUUID(this.hostUUIDFileName);
52
+ if(!host_uuid)
53
+ return;
54
+
50
55
  const pk = new TagCountPack();
51
56
  pk.category = 'metering';
52
57
  pk.time = DateUtil.currentTime() / 300000 * 300000;
@@ -54,18 +59,15 @@ MeteringInfo.prototype.doProcess = function (p) {
54
59
  pk.putTagInt('otype', OType.AP);
55
60
  pk.putTagInt('subtype', APEnum.AP_NODE);
56
61
  pk.putTagInt('ip', p.host_ip);
57
-
58
- const host_uuid = this.getHostUUID(this.hostUUIDFileName);
59
- if (host_uuid) {
60
- pk.putTagString('host_uuid', host_uuid);
61
- }
62
+ pk.putTagString('host_uuid', host_uuid);
63
+ pk.putTagString('_no_5m_hour_', "");
62
64
 
63
65
  const csp = this.getCsp();
64
66
  if (csp) {
65
67
  pk.putTagString('csp', csp)
66
68
  }
67
69
 
68
- pk.putTagFloat(p.metering)
70
+ pk.putTagFloat('mcore', p.metering)
69
71
 
70
72
  DataPackSender.sendTagCounterPack(pk);
71
73
  };
@@ -88,21 +90,19 @@ MeteringInfo.prototype.getHostUUID = function (fileName) {
88
90
  const hasHostUUIDFile = this.hasHostUUID(fileName);
89
91
  if (hasHostUUIDFile) {
90
92
  try {
91
- const data = fs.readFileSync(fileName);
92
-
93
+ const data = fs.readFileSync(fileName, 'utf8').trim();
93
94
  if (data && data.length > 0) {
94
- this.hostUUID = data.toString().trim();
95
+ this.hostUUID = data;
95
96
  return this.hostUUID;
96
97
  } else {
97
- Logger.print('WHATAP-082', 'cannot read /sys/class/dmi/id/product_uuid', false);
98
+ Logger.print('WHATAP-082', `cannot read ${fileName}`, false);
98
99
  }
99
100
  } catch (error) {
100
- Logger.printError('WHATAP-083', 'error reading /sys/class/dmi/id/product_uuid ', error, false);
101
+ Logger.printError('WHATAP-083', `error reading ${fileName}`, error, false);
101
102
  }
102
103
  } else {
103
- Logger.print('WHATAP-084', 'cannot find /sys/class/dmi/id/product_uuid', false);
104
+ Logger.print('WHATAP-084', `cannot find ${fileName}`, false);
104
105
  }
105
-
106
106
  return null;
107
107
  };
108
108
 
@@ -111,7 +111,14 @@ MeteringInfo.prototype.getHostUUIDValue = function () {
111
111
  };
112
112
 
113
113
  MeteringInfo.prototype.getCsp = function () {
114
-
114
+ if(process.env["ECS_CONTAINER_METADATA_URI"]) {
115
+ this.csp = "aws";
116
+ return this.csp;
117
+ }
118
+ if(Util.cloudPlatformCheck()) {
119
+ this.csp = "kic";
120
+ return this.csp;
121
+ }
115
122
  return null;
116
123
  };
117
124
 
@@ -44,8 +44,18 @@ var sendTagCounterPack = function(p){
44
44
 
45
45
  p.pcode = secuMaster.PCODE;
46
46
  p.oid = secuMaster.OID;
47
- p.okind=secuMaster.OKIND;
48
- p.onode=secuMaster.ONODE;
47
+ p.putTagString("oname", secuMaster.ONAME);
48
+ // p.okind=secuMaster.OKIND;
49
+ // p.onode=secuMaster.ONODE;
50
+
51
+ if(conf.OKIND){
52
+ p.okind = conf.OKIND;
53
+ p.putTagString("okindName", conf.OKIND_NAME);
54
+ }
55
+ if(conf.ONODE){
56
+ p.okind = conf.ONODE;
57
+ p.putTagString("onodeName", conf.ONODE_NAME);
58
+ }
49
59
 
50
60
  switch (conf.encrypt_level || 2) {
51
61
  case 1:
@@ -124,12 +124,10 @@ PgSqlObserver.prototype.inject = function (mod, moduleName) {
124
124
  dbc_step = null;
125
125
 
126
126
  var sql_step = new SqlStepX();
127
- sql_step.start_time = ctx.getElapsedTime();
127
+ sql_step.start_time = Date.now();
128
128
  ctx.profile.push(sql_step);
129
129
  ctx.footprint('PgSql Query Start');
130
130
 
131
- ctx.vvv++;
132
-
133
131
  let sql = arguments[0];
134
132
  let psql = null;
135
133
  if (typeof sql === 'string' && sql.length > 0) {
@@ -178,7 +176,7 @@ PgSqlObserver.prototype.inject = function (mod, moduleName) {
178
176
  return result.then(res => {
179
177
  if(res.command && res.command === 'SELECT'){
180
178
  var result_step = new ResultSetStep();
181
- result_step.start_time = ctx.getElapsedTime();
179
+ result_step.start_time = Date.now();
182
180
  result_step.elapsed = 0;
183
181
  result_step.fetch = res.rowCount;
184
182
  result_step.sqlhash = psql.sql;
@@ -196,16 +194,6 @@ PgSqlObserver.prototype.inject = function (mod, moduleName) {
196
194
  return res;
197
195
  }).catch(err => {
198
196
  self._handleError(ctx, sql_step, err)
199
- if (conf.trace_sql_error_stack && conf.trace_sql_error_depth) {
200
- var traceDepth = conf.trace_sql_error_depth;
201
-
202
- var errorStack = err.stack.split("\n");
203
- if (errorStack.length > traceDepth) {
204
- errorStack = errorStack.slice(0, traceDepth + 1);
205
- }
206
- ctx.error_message = errorStack.join("\n");
207
- sql_step.error = ctx.error = StatError.addError('pgsql -' + err.code, err.message, ctx.service_hash, TextTypes.SQL, null);
208
- }
209
197
  throw err;
210
198
  });
211
199
  } else {
@@ -231,7 +219,7 @@ PgSqlObserver.prototype.inject = function (mod, moduleName) {
231
219
  };
232
220
 
233
221
  PgSqlObserver.prototype._finishQuery = function (ctx, sql_step) {
234
- sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
222
+ sql_step.elapsed = Date.now() - sql_step.start_time;
235
223
  TraceSQL.isSlowSQL(ctx);
236
224
 
237
225
  MeterSql.add(sql_step.hash, sql_step.elapsed, false);
@@ -239,7 +227,28 @@ PgSqlObserver.prototype._finishQuery = function (ctx, sql_step) {
239
227
  };
240
228
 
241
229
  PgSqlObserver.prototype._handleError = function (ctx, sql_step, err) {
242
- sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
230
+ sql_step.elapsed = Date.now() - sql_step.start_time;
231
+
232
+ try {
233
+ sql_step.error = StatError.addError("pgsql-" + (err.code || "unknown"), err.message, ctx.service_hash, TextTypes.SQL, sql_step.hash);
234
+
235
+ if (ctx.error.isZero()) {
236
+ ctx.error = sql_step.error;
237
+ }
238
+
239
+ if (conf.trace_sql_error_stack && conf.trace_sql_error_depth) {
240
+ var traceDepth = conf.trace_sql_error_depth;
241
+ var errorStack = err.stack.split("\n");
242
+
243
+ if (errorStack.length > traceDepth) {
244
+ errorStack = errorStack.slice(0, traceDepth + 1);
245
+ }
246
+ ctx.error_message = errorStack.join("\n");
247
+ }
248
+ } catch (e) {
249
+ Logger.printError("WHATAP-309", "Error handling failed", e, false);
250
+ }
251
+
243
252
  TraceSQL.isSlowSQL(ctx);
244
253
 
245
254
  MeterSql.add(sql_step.hash, sql_step.elapsed, false);
@@ -95,20 +95,9 @@ PrismaObserver.prototype.patchPrismaInstance = function(prismaInstance) {
95
95
  }
96
96
  prismaInstance.__whatap_observe__ = true;
97
97
 
98
- // 모든 DB 연결 정보 추출 및 초기화
99
98
  this.setupConnectionInfo(prismaInstance);
100
99
 
101
- // $connect 후킹
102
- // this.hookConnect(prismaInstance);
103
-
104
- // Raw 쿼리 메서드 후킹
105
- // this.hookRawQueryMethods(prismaInstance);
106
-
107
- // $use 미들웨어 후킹 (모델 메서드 추적)
108
100
  this.hookUseMiddleware(prismaInstance);
109
-
110
- // 각 모델에 대한 직접 메서드 후킹 (더 안정적인 추적을 위해)
111
- // this.hookModelMethods(prismaInstance);
112
101
  };
113
102
 
114
103
  // 연결 정보 설정
@@ -148,196 +137,9 @@ PrismaObserver.prototype.setupConnectionInfo = function(prismaInstance) {
148
137
  }
149
138
  };
150
139
 
151
- // Connect 메서드 후킹
152
- // PrismaObserver.prototype.hookConnect = function(prismaInstance) {
153
- // const self = this;
154
- //
155
- // shimmer.wrap(prismaInstance, "$connect", function(original) {
156
- // return async function() {
157
- // const ctx = TraceContextManager.getCurrentContext();
158
- // if (!ctx || ctx.db_opening) {
159
- // return original.apply(this, arguments);
160
- // }
161
- //
162
- // ctx.db_opening = true;
163
- // ctx.footprint("Prisma Connecting Start");
164
- //
165
- // const dbc_step = new DBCStep();
166
- // dbc_step.start_time = ctx.getElapsedTime();
167
- //
168
- // try {
169
- // const result = await original.apply(this, arguments);
170
- //
171
- // dbc_step.hash = dbc_hash;
172
- // dbc_step.elapsed = ctx.getElapsedTime() - dbc_step.start_time;
173
- //
174
- // ctx.db_opening = false;
175
- // ctx.footprint("Prisma Connecting Done");
176
- // ctx.profile.push(dbc_step);
177
- //
178
- // return result;
179
- // } catch (err) {
180
- // ctx.db_opening = false;
181
- //
182
- // dbc_step.hash = dbc_hash;
183
- // dbc_step.elapsed = ctx.getElapsedTime() - dbc_step.start_time;
184
- // dbc_step.error = StatError.addError("prisma-connection", err.message, ctx.service_hash);
185
- //
186
- // if (ctx.error.isZero()) {
187
- // ctx.error = dbc_step.error;
188
- // }
189
- //
190
- // ctx.profile.push(dbc_step);
191
- // Logger.printError("WHATAP-302", "Connection Error", err);
192
- // throw err;
193
- // }
194
- // };
195
- // });
196
- // };
197
-
198
- // Raw 쿼리 메서드 후킹
199
- // PrismaObserver.prototype.hookRawQueryMethods = function(prismaInstance) {
200
- // const self = this;
201
- // const queryMethods = ["$queryRaw", "$executeRaw", "$queryRawUnsafe", "$executeRawUnsafe"];
202
- //
203
- // queryMethods.forEach(method => {
204
- // if (typeof prismaInstance[method] === 'function') {
205
- // shimmer.wrap(prismaInstance, method, function(original) {
206
- // return async function() {
207
- // const ctx = TraceContextManager.getCurrentContext();
208
- // if (!ctx) {
209
- // return original.apply(this, arguments);
210
- // }
211
- //
212
- // const sql_step = new SqlStepX();
213
- // sql_step.start_time = ctx.getElapsedTime();
214
- // ctx.profile.push(sql_step);
215
- // ctx.footprint(`Prisma ${method} Start`);
216
- //
217
- // ctx.sql_count = (ctx.sql_count || 0) + 1;
218
- //
219
- // // SQL 쿼리 추출
220
- // let sql = "";
221
- // let psql = null;
222
- //
223
- // if (arguments.length > 0) {
224
- // if (typeof arguments[0] === "object" && arguments[0].sql) {
225
- // // Tagged template으로 전달된 경우
226
- // sql = arguments[0].sql;
227
- // } else if (typeof arguments[0] === "string") {
228
- // // Raw string으로 전달된 경우
229
- // sql = arguments[0];
230
- // }
231
- // }
232
- //
233
- // // SQL 파싱
234
- // if (sql && sql.length > 0) {
235
- // try {
236
- // psql = escapeLiteral(sql);
237
- // } catch (e) {
238
- // Logger.printError("WHATAP-303", "escapeliteral error", e, false);
239
- // }
240
- // } else {
241
- // sql = "";
242
- // psql = escapeLiteral(sql);
243
- // }
244
- //
245
- // if (psql != null) {
246
- // sql_step.hash = psql.sql;
247
- // }
248
- // sql_step.dbc = dbc_hash;
249
- //
250
- // var els = new EscapeLiteralSQL(sql);
251
- // els.process();
252
- //
253
- // ctx.active_sqlhash = sql_step.hash;
254
- // ctx.active_dbc = sql_step.dbc;
255
- //
256
- // // 파라미터 정보 추출
257
- // if (conf.profile_sql_param_enabled) {
258
- // var params = Array.from(arguments).slice(1);
259
- // sql_step.setTrue(1);
260
- // var crc = { value: 0 };
261
- // sql_step.p1 = toParamBytes(psql.param, crc);
262
- //
263
- // if (params.length > 0) {
264
- // const result = params.map((param) => {
265
- // if (typeof param === "string") {
266
- // return `'${param}'`;
267
- // }
268
- // return param;
269
- // }).toString();
270
- // sql_step.p2 = toParamBytes(result, crc);
271
- // }
272
- //
273
- // sql_step.pcrc = crc.value;
274
- // }
275
- //
276
- // try {
277
- // const result = await original.apply(this, arguments);
278
- //
279
- // // SELECT 쿼리의 결과셋 처리
280
- // if (method === "$queryRaw" || method === "$queryRawUnsafe") {
281
- // if (Array.isArray(result)) {
282
- // var result_step = new ResultSetStep();
283
- // result_step.start_time = ctx.getElapsedTime();
284
- // result_step.elapsed = 0;
285
- // result_step.fetch = result.length;
286
- // result_step.sqlhash = psql.sql;
287
- // result_step.dbc = dbc_hash;
288
- // ctx.profile.push(result_step);
289
- //
290
- // ctx.rs_count = ctx.rs_count ? ctx.rs_count + result.length : result.length;
291
- // ctx.rs_time = ctx.rs_time ? ctx.rs_time + sql_step.elapsed : sql_step.elapsed;
292
- //
293
- // MeterSql.addFetch(result_step.dbc, result_step.fetch, 0);
294
- // StatSql.addFetch(result_step.dbc, result_step.sqlhash, result_step.fetch, 0);
295
- //
296
- // TraceSQL.isTooManyRecords(sql_step, result_step.fetch, ctx);
297
- // }
298
- // }
299
- //
300
- // // UPDATE/INSERT/DELETE 쿼리 결과 처리
301
- // if ((method === "$executeRaw" || method === "$executeRawUnsafe") && typeof result === "number") {
302
- // sql_step.updated = result;
303
- // }
304
- //
305
- // self._finishQuery(ctx, sql_step);
306
- // return result;
307
- // } catch (err) {
308
- // Logger.printError("WHATAP-304", `${method} error: ${err.message}`, err);
309
- //
310
- // self._handleError(ctx, sql_step, err);
311
- //
312
- // if (conf.trace_sql_error_stack && conf.trace_sql_error_depth) {
313
- // var traceDepth = conf.trace_sql_error_depth;
314
- // var errorStack = err.stack.split("\n");
315
- //
316
- // if (errorStack.length > traceDepth) {
317
- // errorStack = errorStack.slice(0, traceDepth + 1);
318
- // }
319
- //
320
- // ctx.error_message = errorStack.join("\n");
321
- // sql_step.error = ctx.error = StatError.addError("prisma-" + (err.code || "unknown"), err.message, ctx.service_hash, TextTypes.SQL, null);
322
- // }
323
- //
324
- // throw err;
325
- // }
326
- // };
327
- // });
328
- // }
329
- // });
330
- // };
331
-
332
140
  PrismaObserver.prototype.hookUseMiddleware = function(prismaInstance) {
333
- const self = this;
334
-
335
- // 원본 $use 함수를 저장
336
141
  const originalUse = prismaInstance.$use;
337
-
338
- // 우리만의 미들웨어 추가
339
142
  if (typeof originalUse === 'function') {
340
- // 간단한 미들웨어 추가 (모든 쿼리를 추적)
341
143
  prismaInstance.$use(async (params, next) => {
342
144
  var result;
343
145
  const ctx = TraceContextManager.getCurrentContext();
@@ -511,13 +313,7 @@ PrismaObserver.prototype.hookUseMiddleware = function(prismaInstance) {
511
313
  sql_step.updated = 1; // upsert는 항상 1개의 레코드에 영향을 미침
512
314
  }
513
315
 
514
- sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
515
- ctx.sql_time = (ctx.sql_time || 0) + sql_step.elapsed;
516
-
517
- TraceSQL.isSlowSQL(ctx);
518
-
519
- MeterSql.add(dbc_hash, sql_step.elapsed, false);
520
- StatSql.addSqlTime(ctx.service_hash, sql_step.dbc, sql_step.hash, sql_step.elapsed, false, 0);
316
+ this._finishQuery(ctx, sql_step);
521
317
 
522
318
  ctx.footprint(`Prisma ${modelName}.${action} Done`);
523
319
 
@@ -525,36 +321,7 @@ PrismaObserver.prototype.hookUseMiddleware = function(prismaInstance) {
525
321
  } catch (err) {
526
322
  Logger.printError("WHATAP-308", `Middleware error in ${modelName}.${action}: ${err.message}`, err, false);
527
323
 
528
- sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
529
- ctx.sql_time = (ctx.sql_time || 0) + sql_step.elapsed;
530
-
531
- TraceSQL.isSlowSQL(ctx);
532
-
533
- MeterSql.add(dbc_hash, sql_step.elapsed, true);
534
- StatSql.addSqlTime(ctx.service_hash, sql_step.dbc, sql_step.hash, sql_step.elapsed, true, 0);
535
-
536
- // 에러 처리
537
- try {
538
- sql_step.error = StatError.addError("prisma-" + (err.code || "unknown"), err.message, ctx.service_hash, TextTypes.SQL, sql_step.hash);
539
-
540
- if (ctx.error.isZero()) {
541
- ctx.error = sql_step.error;
542
- }
543
-
544
- if (conf.trace_sql_error_stack && conf.trace_sql_error_depth) {
545
- var traceDepth = conf.trace_sql_error_depth;
546
- var errorStack = err.stack.split("\n");
547
-
548
- if (errorStack.length > traceDepth) {
549
- errorStack = errorStack.slice(0, traceDepth + 1);
550
- }
551
-
552
- ctx.error_message = errorStack.join("\n");
553
- }
554
- } catch (e) {
555
- Logger.printError("WHATAP-309", "Error handling failed", e, false);
556
- }
557
-
324
+ this._handleError(ctx, sql_step, err);
558
325
  ctx.footprint(`Prisma ${modelName}.${action} Error`);
559
326
  throw err;
560
327
  }
@@ -562,174 +329,8 @@ PrismaObserver.prototype.hookUseMiddleware = function(prismaInstance) {
562
329
  }
563
330
  };
564
331
 
565
- // 모델 메서드 직접 후킹
566
- // PrismaObserver.prototype.hookModelMethods = function(prismaInstance) {
567
- // const self = this;
568
- //
569
- // // Prisma에서 모든 모델 가져오기
570
- // let models = [];
571
- // try {
572
- // // DMMF를 통해 모델 이름 얻기
573
- // if (prismaInstance._baseDmmf && prismaInstance._baseDmmf.modelMap) {
574
- // models = Object.keys(prismaInstance._baseDmmf.modelMap);
575
- // } else if (prismaInstance._dmmf && prismaInstance._dmmf.modelMap) {
576
- // models = Object.keys(prismaInstance._dmmf.modelMap);
577
- // }
578
- // } catch (e) {
579
- // Logger.printError("WHATAP-PRISMA", "Failed to get models", e, false);
580
- // }
581
- //
582
- // // 모델 메서드 목록
583
- // const methods = [
584
- // "findUnique", "findFirst", "findMany",
585
- // "create", "createMany",
586
- // "update", "updateMany",
587
- // "upsert",
588
- // "delete", "deleteMany",
589
- // "count", "aggregate", "groupBy"
590
- // ];
591
- //
592
- // Logger.print("WHATAP-PRISMA", `Found models: ${models.join(', ')}`, false);
593
- //
594
- // // 각 모델에 대해 메서드 후킹
595
- // models.forEach(model => {
596
- // if (prismaInstance[model]) {
597
- // methods.forEach(method => {
598
- // if (typeof prismaInstance[model][method] === 'function') {
599
- // shimmer.wrap(prismaInstance[model], method, function(original) {
600
- // return async function() {
601
- // const ctx = TraceContextManager.getCurrentContext();
602
- // if (!ctx) {
603
- // return original.apply(this, arguments);
604
- // }
605
- //
606
- // Logger.print("WHATAP-PRISMA", `Direct model method called: ${model}.${method}`, false);
607
- //
608
- // const sql_step = new SqlStepX();
609
- // sql_step.start_time = ctx.getElapsedTime();
610
- // ctx.profile.push(sql_step);
611
- // ctx.footprint(`Prisma ${model}.${method} Start (Direct)`);
612
- //
613
- // ctx.sql_count = (ctx.sql_count || 0) + 1;
614
- //
615
- // // 쿼리 정보
616
- // const queryInfo = `${method.toUpperCase()} ${model}`;
617
- // const queryHash = HashUtil.hashFromString(queryInfo);
618
- //
619
- // DataTextAgent.SQL.add(queryHash, queryInfo);
620
- // sql_step.hash = queryHash;
621
- // sql_step.dbc = dbc_hash;
622
- //
623
- // ctx.active_sqlhash = sql_step.hash;
624
- // ctx.active_dbc = sql_step.dbc;
625
- //
626
- // // 쿼리 파라미터
627
- // if (conf.profile_sql_param_enabled) {
628
- // const argsString = JSON.stringify(arguments[0] || {});
629
- // sql_step.setTrue(1);
630
- // var crc = { value: 0 };
631
- // sql_step.p1 = toParamBytes(argsString, crc);
632
- // sql_step.pcrc = crc.value;
633
- // }
634
- //
635
- // try {
636
- // const result = await original.apply(this, arguments);
637
- //
638
- // // 결과셋 처리
639
- // if (["findMany", "findFirst", "findUnique"].includes(method)) {
640
- // let recordCount = 0;
641
- //
642
- // if (Array.isArray(result)) {
643
- // recordCount = result.length;
644
- // } else if (result && typeof result === "object") {
645
- // recordCount = 1;
646
- // }
647
- //
648
- // if (recordCount > 0) {
649
- // var result_step = new ResultSetStep();
650
- // result_step.start_time = ctx.getElapsedTime();
651
- // result_step.elapsed = 0;
652
- // result_step.fetch = recordCount;
653
- // result_step.sqlhash = queryHash;
654
- // result_step.dbc = dbc_hash;
655
- // ctx.profile.push(result_step);
656
- //
657
- // ctx.rs_count = ctx.rs_count ? ctx.rs_count + recordCount : recordCount;
658
- // ctx.rs_time = ctx.rs_time ? ctx.rs_time + sql_step.elapsed : sql_step.elapsed;
659
- //
660
- // MeterSql.addFetch(result_step.dbc, result_step.fetch, 0);
661
- // StatSql.addFetch(result_step.dbc, result_step.sqlhash, result_step.fetch, 0);
662
- //
663
- // TraceSQL.isTooManyRecords(sql_step, result_step.fetch, ctx);
664
- // }
665
- // }
666
- //
667
- // // 수정된 레코드 처리
668
- // if (["create", "createMany", "update", "updateMany", "delete", "deleteMany"].includes(method)) {
669
- // if (result && result.count !== undefined) {
670
- // sql_step.updated = result.count;
671
- // } else if (result && typeof result === "object") {
672
- // sql_step.updated = 1;
673
- // }
674
- // }
675
- //
676
- // sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
677
- // ctx.sql_time = (ctx.sql_time || 0) + sql_step.elapsed;
678
- //
679
- // TraceSQL.isSlowSQL(ctx);
680
- //
681
- // MeterSql.add(dbc_hash, sql_step.elapsed, false);
682
- // StatSql.addSqlTime(ctx.service_hash, sql_step.dbc, sql_step.hash, sql_step.elapsed, false, 0);
683
- //
684
- // ctx.footprint(`Prisma ${model}.${method} Done (Direct)`);
685
- // Logger.print("WHATAP-PRISMA", `Direct model method completed: ${model}.${method}`, false);
686
- //
687
- // return result;
688
- // } catch (err) {
689
- // Logger.printError("WHATAP-PRISMA", `Direct model method error in ${model}.${method}: ${err.message}`, err);
690
- //
691
- // sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
692
- // ctx.sql_time = (ctx.sql_time || 0) + sql_step.elapsed;
693
- //
694
- // TraceSQL.isSlowSQL(ctx);
695
- //
696
- // MeterSql.add(dbc_hash, sql_step.elapsed, true);
697
- // StatSql.addSqlTime(ctx.service_hash, sql_step.dbc, sql_step.hash, sql_step.elapsed, true, 0);
698
- //
699
- // try {
700
- // sql_step.error = StatError.addError("prisma-" + (err.code || "unknown"), err.message, ctx.service_hash, TextTypes.SQL, sql_step.hash);
701
- //
702
- // if (ctx.error.isZero()) {
703
- // ctx.error = sql_step.error;
704
- // }
705
- //
706
- // if (conf.trace_sql_error_stack && conf.trace_sql_error_depth) {
707
- // var traceDepth = conf.trace_sql_error_depth;
708
- // var errorStack = err.stack.split("\n");
709
- //
710
- // if (errorStack.length > traceDepth) {
711
- // errorStack = errorStack.slice(0, traceDepth + 1);
712
- // }
713
- //
714
- // ctx.error_message = errorStack.join("\n");
715
- // }
716
- // } catch (e) {
717
- // Logger.printError("WHATAP-PRISMA", "Error handling failed", e, false);
718
- // }
719
- //
720
- // ctx.footprint(`Prisma ${model}.${method} Error (Direct)`);
721
- // throw err;
722
- // }
723
- // };
724
- // });
725
- // }
726
- // });
727
- // }
728
- // });
729
- // };
730
-
731
332
  PrismaObserver.prototype._finishQuery = function(ctx, sql_step) {
732
- sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
333
+ sql_step.elapsed = Date.now() - sql_step.start_time;
733
334
  ctx.sql_time = (ctx.sql_time || 0) + sql_step.elapsed;
734
335
 
735
336
  TraceSQL.isSlowSQL(ctx);
@@ -741,7 +342,7 @@ PrismaObserver.prototype._finishQuery = function(ctx, sql_step) {
741
342
  };
742
343
 
743
344
  PrismaObserver.prototype._handleError = function(ctx, sql_step, err) {
744
- sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
345
+ sql_step.elapsed = Date.now() - sql_step.start_time;
745
346
  ctx.sql_time = (ctx.sql_time || 0) + sql_step.elapsed;
746
347
 
747
348
  TraceSQL.isSlowSQL(ctx);
@@ -755,8 +356,18 @@ PrismaObserver.prototype._handleError = function(ctx, sql_step, err) {
755
356
  if (ctx.error.isZero()) {
756
357
  ctx.error = sql_step.error;
757
358
  }
359
+
360
+ if (conf.trace_sql_error_stack && conf.trace_sql_error_depth) {
361
+ var traceDepth = conf.trace_sql_error_depth;
362
+ var errorStack = err.stack.split("\n");
363
+
364
+ if (errorStack.length > traceDepth) {
365
+ errorStack = errorStack.slice(0, traceDepth + 1);
366
+ }
367
+ ctx.error_message = errorStack.join("\n");
368
+ }
758
369
  } catch (e) {
759
- Logger.printError("WHATAP-310", "Error handling failed", e, false);
370
+ Logger.printError("WHATAP-309", "Error handling failed", e, false);
760
371
  }
761
372
 
762
373
  ctx.footprint("Prisma Query Error");
@@ -2,219 +2,217 @@ var TraceContextManager = require('../trace/trace-context-manager'),
2
2
  DataTextAgent = require('../data/datatext-agent'),
3
3
  SqlStepX = require('../step/sql-stepx'),
4
4
  DBCStep = require('../step/dbc-step'),
5
- TextTypes = require('../lang/text-types'),
6
5
  HashUtil = require('../util/hashutil'),
7
- Long = require('long'),
8
- Logger = require('../logger');
6
+ Logger = require('../logger'),
7
+ conf = require('../conf/configure'),
8
+ ParamSecurity = require('../util/paramsecurity');
9
9
  const shimmer = require('../core/shimmer');
10
+ const {Buffer} = require("buffer");
10
11
 
11
12
  var RedisObserver = function (agent) {
12
13
  this.agent = agent;
13
- this.aop = agent.aop;
14
14
  this.packages = ['redis', 'ioredis'];
15
15
  };
16
16
 
17
17
  RedisObserver.prototype.inject = function (mod, modName) {
18
-
19
18
  if (mod.__whatap_observe__) {
20
19
  return;
21
20
  }
22
21
  mod.__whatap_observe__ = true;
23
22
  Logger.initPrint("RedisObserver");
24
- var self = this;
25
23
 
24
+ if (modName === 'redis') {
25
+ this._injectRedis(mod);
26
+ } else if (modName === 'ioredis') {
27
+ this._injectIORedis(mod);
28
+ }
29
+ };
30
+
31
+ RedisObserver.prototype._injectRedis = function (mod) {
26
32
  var dbc_hash = 0;
27
- var dbc;
28
- var dbc_time;
29
- self.aop.both(mod, 'createClient',
30
- function (obj, args, lctx) {
33
+ var dbc = '';
34
+
35
+ const selectCommand = new Set(['get', 'hGet', 'hmGet']);
36
+ const insertCommand = new Set(['set', 'hSet', 'hset', 'hmSet', 'hmset', 'zAdd', 'zadd', 'lSet', 'lset']);
37
+ const updateCommand = new Set(['set', 'lSet', 'lset', 'hSet', 'hset', 'zAdd', 'zadd']);
38
+ const deleteCommand = new Set(['del', 'lRem', 'sRem', 'srem', 'hDel', 'hdel', 'zRem', 'zrem']);
39
+ const commands = new Set([...selectCommand, ...insertCommand, ...updateCommand, ...deleteCommand]);
40
+
41
+ shimmer.wrap(mod, 'createClient', function (original) {
42
+ return function wrappedCreateClient() {
31
43
  if (dbc_hash === 0) {
32
- if (args.length > 0) {
33
- var info = (args[0] || {});
34
- dbc = 'redis://';
35
- dbc += info.host || '';
36
- dbc += ':';
37
- dbc += info.port || '';
44
+ if (arguments.length > 0) {
45
+ var info = (arguments[0] || {});
46
+ dbc = info.url || '';
38
47
  dbc_hash = HashUtil.hashFromString(dbc);
48
+
49
+ DataTextAgent.DBC.add(dbc_hash, dbc);
50
+ DataTextAgent.METHOD.add(dbc_hash, dbc);
51
+ DataTextAgent.ERROR.add(dbc_hash, dbc);
39
52
  }
40
53
  }
41
- },
42
- function (obj, args, ret, lctx) {
43
- var selectCommand = new Set(['get', 'hGet', 'hmGet']);
44
- var insertCommand = new Set(['set', 'hSet', 'hset', 'hmSet', 'hmset', 'zAdd', 'zadd', 'lSet', 'lset']);
45
- var updateCommand = new Set(['set', 'lSet', 'lset', 'hSet', 'hset', 'zAdd', 'zadd']);
46
- var deleteCommand = new Set(['del', 'lRem', 'sRem', 'srem', 'hDel', 'hdel', 'zRem', 'zrem']);
47
- var commands = new Set([...selectCommand, ...insertCommand, ...updateCommand, ...deleteCommand]);
48
- commands.forEach(function (command) {
49
- self.aop.after(ret, command,
50
- function (obj, args, ret, lctx) {
51
- var ctx = TraceContextManager.getCurrentContext();
52
- if (ctx == null) {
53
- return;
54
- }
55
54
 
56
- var dbc_step = new DBCStep();
57
- dbc_step.hash = dbc_hash;
58
- dbc_step.start_time = dbc_time;
59
- dbc_step.elapsed = ctx.getElapsedTime() - dbc_step.start_time;
60
- ctx.profile.push(dbc_step);
61
-
62
- var sql_step;
63
- try {
64
- sql_step = new SqlStepX();
65
- const key = args[0];
66
- const values = [];
67
- for (let i = 1; i < args.length; i++)
68
- values.push(args[i]);
69
-
70
- var sql = 'Redis ' + command + ': ' + JSON.stringify([key]);
71
- // if (values.length > 0)
72
- // sql += ' ' + JSON.stringify(values);
73
- sql_step.hash = HashUtil.hashFromString(sql);
74
- sql_step.start_time = ctx.getElapsedTime();
75
- //sql_step.crud = 'I'.charCodeAt(0);
76
- // DataTextAgent.SQL.add(sql_step.hash, sql);
77
- ctx.profile.push(sql_step);
78
- } catch (e) {
79
- Logger.printError("WHATAP-605", "Redis CRUD error", e, false);
80
- sql_step = null;
81
- }
82
- })
83
- })
55
+ var client = original.apply(this, arguments);
84
56
 
85
- var dbc_step = lctx.step,
86
- ctx = lctx.context;
57
+ const commandsArray = Array.from(commands);
58
+ commandsArray.forEach(cmdName => {
59
+ shimmer.wrap(client, cmdName, function (originalMethod) {
60
+ const wrappedFunction = function wrappedSendCommand() {
61
+ try{
62
+ var ctx = TraceContextManager.getCurrentContext();
63
+ if (!ctx) {
64
+ return originalMethod.apply(this, arguments);
65
+ }
87
66
 
88
- if (ctx == null) {
89
- return;
90
- }
67
+ var dbc_step = new DBCStep();
68
+ dbc_step.hash = dbc_hash;
69
+ ctx.profile.push(dbc_step);
91
70
 
92
- var client = ret;
93
- var method = client.internal_send_command
94
- ? "internal_send_command"
95
- : "send_command";
71
+ ctx.footprint('Redis Command Start');
96
72
 
97
- var address = 'redis://'
98
- address += (client.address || (client.host + ':' + client.port)) || '';
99
- dbc_step.elapsed = ctx.getElapsedTime() - dbc_step.start_time;
100
- dbc_step.hash = HashUtil.hashFromString(address);
101
- DataTextAgent.DBC.add(dbc_step.hash, address);
73
+ var command = wrappedFunction._commandName || 'unknown';
74
+ var sql = `${command.toUpperCase()}`;
75
+ var sql_step = new SqlStepX();
76
+ sql_step.start_time = ctx.getElapsedTime();
77
+ sql_step.dbc = dbc_hash;
78
+
79
+ if(conf.getProperty('profile_redis_param_enabled', false)){
80
+ if (arguments[0] && typeof arguments[0] === 'string')
81
+ sql += ' ' + arguments[0];
82
+ else if (arguments[0] && Array.isArray(arguments[0]))
83
+ sql += ' ' + JSON.stringify(arguments[0]);
84
+ else if (arguments[0] && typeof arguments[0] === 'object'){
85
+ sql += ' ' + JSON.stringify(Object.keys(arguments[0]))
86
+ }
87
+
88
+ if(arguments[1] && arguments[1].length > 0){
89
+ var args = Array.isArray(arguments[1]) ? arguments[1] : [arguments[1]];
90
+ sql_step.setTrue(1);
91
+ var crc = {value: 0};
92
+ const result = args.map((arg) => {
93
+ if (typeof arg === 'string') {
94
+ return `'${arg}'`
95
+ }
96
+ return arg
97
+ }).toString()
98
+ sql_step.p2 = toParamBytes(result, crc);
99
+ sql_step.pcrc = crc.value;
100
+ }
101
+ }
102
+ sql_step.hash = HashUtil.hashFromString(sql);
103
+ ctx.profile.push(sql_step);
102
104
 
103
- ctx.profile.push(dbc_step);
105
+ DataTextAgent.SQL.add(sql_step.hash, sql);
104
106
 
105
- self.aop.before(client, method, function (obj, args) {
106
- var command, params;
107
- try {
108
- if (typeof (args[0]) === 'string') {
109
- command = args[0];
110
- params = args[1];
111
- } else {
112
- command = args[0].command;
113
- params = args[0].args;
114
- }
115
- } catch (e) {
116
- command = '';
117
- params = '';
118
- }
107
+ var result = originalMethod.apply(this, arguments);
108
+ sql_step.elapsed = ctx.getElapsedTime();
119
109
 
120
- var sql = command + ' ' + params;
121
- var sql_step = new SqlStepX();
122
- sql_step.start_time = ctx.getElapsedTime();
123
- sql_step.hash = HashUtil.hashFromString(sql);
124
- sql_step.dbc = dbc_step.hash;
125
- //sql_step.crud = 'S'.charCodeAt(0);
126
- ctx.profile.push(sql_step);
127
-
128
- DataTextAgent.SQL.add(sql_step.hash, sql);
129
-
130
- ctx.footprint('Redis Command Start');
131
- var hasCallback = self.aop.functionHook(args[1], -1, function (obj, args) {
132
-
133
- TraceContextManager.resume(ctx._id);
134
- if (args[0]) {
135
- //error
136
- sql_step.error = StatError.addError(
137
- 'redis',
138
- (args[0].message || 'redis error'),
139
- ctx.service_hash,
140
- TextTypes.SQL,
141
- sql_step.hash);
142
- if (ctx.error.isZero()) {
143
- ctx.error = sql_step.error;
110
+ ctx.footprint('Redis Command Done');
111
+ return result;
112
+ }catch (e) {
113
+ Logger.printError("WHATAP-605", "Redis CRUD error", e, false);
114
+ return originalMethod.apply(this, arguments);
144
115
  }
145
- }
146
- sql_step.elapsed = sql_step.start_time - ctx.getElapsedTime();
147
-
148
- ctx.footprint('Redis Command Done');
149
-
116
+ };
117
+ wrappedFunction._commandName = cmdName;
118
+ return wrappedFunction;
150
119
  });
151
-
152
- // if(hasCallback === false) {
153
- // ctx.footprint('Redis Command Done');
154
- // }
155
120
  });
156
- });
121
+ return client;
122
+ };
123
+ });
157
124
 
125
+ return this;
126
+ };
127
+
128
+ RedisObserver.prototype._injectIORedis = function (mod) {
158
129
  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
130
+ var ioredis_dbc = '';
131
+
132
+ const selectCommand = new Set(['get', 'hget', 'hmget', 'zrange', 'smembers', 'lrange']);
133
+ const insertCommand = new Set(['set', 'hset', 'hmset', 'zadd', 'lset', 'sadd', 'lpush', 'rpush', 'evalsha']);
134
+ const updateCommand = new Set(['set', 'lset', 'hset', 'zadd']);
135
+ const deleteCommand = new Set(['del', 'lrem', 'srem', 'hdel', 'zrem']);
136
+ const commands = new Set([...selectCommand, ...insertCommand, ...updateCommand, ...deleteCommand]);
137
+
138
+ shimmer.wrap(mod.prototype, 'sendCommand', function (original) {
139
+ return function wrappedSendCommand(command) {
140
+ // Get trace context
141
+ var ctx = TraceContextManager.getCurrentContext();
142
+ if (!ctx) {
143
+ return original.apply(this, arguments);
144
+ }
145
+
146
+ if (ioredis_dbc_hash === 0 && this.options) {
164
147
  ioredis_dbc = 'redis://';
165
- ioredis_dbc += info.host || '';
148
+ ioredis_dbc += this.options.host || '';
166
149
  ioredis_dbc += ':';
167
- ioredis_dbc += info.port || '';
150
+ ioredis_dbc += this.options.port || '';
168
151
  ioredis_dbc_hash = HashUtil.hashFromString(ioredis_dbc);
152
+ DataTextAgent.DBC.add(ioredis_dbc_hash, ioredis_dbc);
169
153
  }
170
- }
171
- }, function (obj, args, ret, lctx) {
172
- var ctx = lctx.context;
173
- if (!ctx) {
174
- return;
175
- }
176
-
177
- var selectCommand = new Set(['get', 'hget', 'hmget', 'zrange', 'smembers', 'lrange']);
178
- var insertCommand = new Set(['set', 'hset', 'hmset', 'zadd', 'lset', 'sadd', 'lpush', 'rpush', 'evalsha']);
179
- var updateCommand = new Set(['set', 'lset', 'hset', 'zadd']);
180
- var deleteCommand = new Set(['del', 'lrem', 'srem', 'hdel', 'zrem']);
181
- var commands = new Set([...selectCommand, ...insertCommand, ...updateCommand, ...deleteCommand]);
182
-
183
- if(!args[0] || (args[0] && !args[0].name)){
184
- return;
185
- }
186
- var command = args[0].name;
187
- if(commands.has(command.toLowerCase())){
188
- // var ctx = TraceContextManager.getCurrentContext();
189
- // if (ctx == null) {
190
- // return;
191
- // }
192
-
193
- var dbc_step = new DBCStep();
194
- dbc_step.hash = ioredis_dbc_hash;
195
- dbc_step.start_time = ctx.getElapsedTime();
196
- DataTextAgent.DBC.add(ioredis_dbc_hash, ioredis_dbc);
197
- ctx.profile.push(dbc_step);
198
-
199
- var sql_step;
200
- var args = args[0].args;
201
- try {
202
- sql_step = new SqlStepX();
203
- let key = args[0];
204
- if(typeof key === 'string')
205
- key = [key];
206
-
207
- var sql = 'Redis ' + command + ': ' + JSON.stringify(key);
208
- sql_step.hash = HashUtil.hashFromString(sql);
209
- sql_step.start_time = ctx.getElapsedTime();
210
- DataTextAgent.SQL.add(sql_step.hash, sql);
211
- ctx.profile.push(sql_step);
212
- } catch (e) {
213
- Logger.printError("WHATAP-605", "Redis CRUD error", e, false);
214
- sql_step = null;
154
+
155
+ if (command && command.name && commands.has(command.name.toLowerCase())) {
156
+ var dbc_step = new DBCStep();
157
+ dbc_step.hash = ioredis_dbc_hash;
158
+ dbc_step.start_time = ctx.getElapsedTime();
159
+ ctx.profile.push(dbc_step);
160
+
161
+ try {
162
+ var sql_step = new SqlStepX();
163
+ var sql = command.name.toUpperCase();
164
+ if(conf.getProperty('profile_redis_param_enabled', false)){
165
+ var args = command.args;
166
+ var key = args.shift();
167
+ if (key && typeof key === 'string')
168
+ sql += ' ' + key;
169
+
170
+ if(args && args.length > 0){
171
+ sql_step.setTrue(1);
172
+ var crc = {value: 0};
173
+ const result = args.map((arg) => {
174
+ if (typeof arg === 'string') {
175
+ return `'${arg}'`
176
+ }
177
+ return arg;
178
+ }).toString()
179
+ sql_step.p2 = toParamBytes(result, crc);
180
+ sql_step.pcrc = crc.value;
181
+ }
182
+ }
183
+
184
+ sql_step.hash = HashUtil.hashFromString(sql);
185
+ sql_step.start_time = ctx.getElapsedTime();
186
+ DataTextAgent.SQL.add(sql_step.hash, sql);
187
+ ctx.profile.push(sql_step);
188
+
189
+ var originalPromise = original.apply(this, arguments);
190
+ return originalPromise.finally(function () {
191
+ dbc_step.elapsed = ctx.getElapsedTime() - dbc_step.start_time;
192
+ sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
193
+ });
194
+ } catch (e) {
195
+ Logger.printError("WHATAP-605", "ioredis CRUD error", e, false);
196
+ return original.apply(this, arguments);
197
+ }
215
198
  }
216
- }
217
- })
199
+
200
+ return original.apply(this, arguments);
201
+ };
202
+ });
203
+
204
+ return this;
205
+ };
206
+
207
+ var toParamBytes = function (p, crc) {
208
+ if (p == null || p.length === 0) {
209
+ return null;
210
+ }
211
+ try {
212
+ return ParamSecurity.encrypt(Buffer.from(p, 'utf8'), crc);
213
+ } catch (e) {
214
+ return null;
215
+ }
218
216
  };
219
217
 
220
218
  exports.RedisObserver = RedisObserver;
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.14",
5
- "releaseDate": "20250404",
4
+ "version": "0.5.16",
5
+ "releaseDate": "20250414",
6
6
  "description": "Monitoring and Profiling Service",
7
7
  "main": "index.js",
8
8
  "scripts": {},