whatap 0.5.9 → 0.5.10

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.
@@ -271,7 +271,10 @@ var ConfigDefault = {
271
271
 
272
272
  "profile_graphql_enabled": bool("profile_graphql_enabled", true),
273
273
  "profile_graphql_variable_enabled": bool("profile_graphql_variable_enabled", false),
274
- "ignore_graphql_operation": str("ignore_graphql_operation", '')
274
+ "ignore_graphql_operation": str("ignore_graphql_operation", ''),
275
+
276
+ "prisma_read_func_name": str("prisma_read_func_name", "read"),
277
+ "prisma_database_url_name": str("prisma_database_url_name", "DATABASE_URL"),
275
278
  };
276
279
 
277
280
  ConfigDefault._hook_method_ignore_prefix = ConfigDefault.hook_method_ignore_prefixes.split(',');
@@ -25,6 +25,12 @@ const DateUtil = require("../util/dateutil");
25
25
  const TraceSQL = require("../trace/trace-sql");
26
26
  const shimmer = require("../core/shimmer");
27
27
 
28
+ var prisma_read_func_name = conf.getProperty('prisma_read_func_name', 'read');
29
+ var prisma_database_url_name = conf.getProperty('prisma_database_url_name', 'DATABASE_URL')
30
+ conf.on('prisma_database_url_name', function (newProps) {
31
+ prisma_database_url_name = newProps;
32
+ })
33
+
28
34
  var PrismaObserver = function(agent) {
29
35
  this.agent = agent;
30
36
  this.packages = ["@prisma/client"];
@@ -58,6 +64,12 @@ PrismaObserver.prototype.inject = function(mod, moduleName) {
58
64
  // 이 시점에서 instance가 생성된 Prisma 클라이언트 인스턴스
59
65
  self.patchPrismaInstance(instance);
60
66
 
67
+ if(!instance[prisma_read_func_name]){
68
+ instance[prisma_read_func_name] = function() {
69
+ return this;
70
+ }
71
+ }
72
+
61
73
  return instance;
62
74
  };
63
75
  });
@@ -75,7 +87,7 @@ PrismaObserver.prototype.patchPrismaInstance = function(prismaInstance) {
75
87
  this.setupConnectionInfo(prismaInstance);
76
88
 
77
89
  // $connect 후킹
78
- this.hookConnect(prismaInstance);
90
+ // this.hookConnect(prismaInstance);
79
91
 
80
92
  // Raw 쿼리 메서드 후킹
81
93
  // this.hookRawQueryMethods(prismaInstance);
@@ -91,12 +103,12 @@ PrismaObserver.prototype.patchPrismaInstance = function(prismaInstance) {
91
103
  PrismaObserver.prototype.setupConnectionInfo = function(prismaInstance) {
92
104
  try {
93
105
  // 연결 정보 가져오기 시도
94
- const url = prismaInstance._engineConfig?.datasources?.db?.url ||
95
- prismaInstance._baseDmmf?.datamodel?.datasources?.[0]?.url?.value ||
96
- process.env.DATABASE_URL ||
106
+ const url = prismaInstance._engineConfig?.overrideDatasources?.db?.url ||
107
+ prismaInstance.env?.DATABASE_URL ||
108
+ process.env[prisma_database_url_name] ||
97
109
  'prisma:unknown';
98
110
 
99
- if (url && url !== "prisma:unknown") {
111
+ if (url && url !== "prisma:unknown" && !dbc_hash) {
100
112
  const dbUrl = new URL(url);
101
113
  const protocol = dbUrl.protocol.replace(':', '');
102
114
 
@@ -125,185 +137,185 @@ PrismaObserver.prototype.setupConnectionInfo = function(prismaInstance) {
125
137
  };
126
138
 
127
139
  // Connect 메서드 후킹
128
- PrismaObserver.prototype.hookConnect = function(prismaInstance) {
129
- const self = this;
130
-
131
- shimmer.wrap(prismaInstance, "$connect", function(original) {
132
- return async function() {
133
- const ctx = TraceContextManager.getCurrentContext();
134
- if (!ctx || ctx.db_opening) {
135
- return original.apply(this, arguments);
136
- }
137
-
138
- ctx.db_opening = true;
139
- ctx.footprint("Prisma Connecting Start");
140
-
141
- const dbc_step = new DBCStep();
142
- dbc_step.start_time = ctx.getElapsedTime();
143
-
144
- try {
145
- const result = await original.apply(this, arguments);
146
-
147
- dbc_step.hash = dbc_hash;
148
- dbc_step.elapsed = ctx.getElapsedTime() - dbc_step.start_time;
149
-
150
- ctx.db_opening = false;
151
- ctx.footprint("Prisma Connecting Done");
152
- ctx.profile.push(dbc_step);
153
-
154
- return result;
155
- } catch (err) {
156
- ctx.db_opening = false;
157
-
158
- dbc_step.hash = dbc_hash;
159
- dbc_step.elapsed = ctx.getElapsedTime() - dbc_step.start_time;
160
- dbc_step.error = StatError.addError("prisma-connection", err.message, ctx.service_hash);
161
-
162
- if (ctx.error.isZero()) {
163
- ctx.error = dbc_step.error;
164
- }
165
-
166
- ctx.profile.push(dbc_step);
167
- Logger.printError("WHATAP-302", "Connection Error", err);
168
- throw err;
169
- }
170
- };
171
- });
172
- };
140
+ // PrismaObserver.prototype.hookConnect = function(prismaInstance) {
141
+ // const self = this;
142
+ //
143
+ // shimmer.wrap(prismaInstance, "$connect", function(original) {
144
+ // return async function() {
145
+ // const ctx = TraceContextManager.getCurrentContext();
146
+ // if (!ctx || ctx.db_opening) {
147
+ // return original.apply(this, arguments);
148
+ // }
149
+ //
150
+ // ctx.db_opening = true;
151
+ // ctx.footprint("Prisma Connecting Start");
152
+ //
153
+ // const dbc_step = new DBCStep();
154
+ // dbc_step.start_time = ctx.getElapsedTime();
155
+ //
156
+ // try {
157
+ // const result = await original.apply(this, arguments);
158
+ //
159
+ // dbc_step.hash = dbc_hash;
160
+ // dbc_step.elapsed = ctx.getElapsedTime() - dbc_step.start_time;
161
+ //
162
+ // ctx.db_opening = false;
163
+ // ctx.footprint("Prisma Connecting Done");
164
+ // ctx.profile.push(dbc_step);
165
+ //
166
+ // return result;
167
+ // } catch (err) {
168
+ // ctx.db_opening = false;
169
+ //
170
+ // dbc_step.hash = dbc_hash;
171
+ // dbc_step.elapsed = ctx.getElapsedTime() - dbc_step.start_time;
172
+ // dbc_step.error = StatError.addError("prisma-connection", err.message, ctx.service_hash);
173
+ //
174
+ // if (ctx.error.isZero()) {
175
+ // ctx.error = dbc_step.error;
176
+ // }
177
+ //
178
+ // ctx.profile.push(dbc_step);
179
+ // Logger.printError("WHATAP-302", "Connection Error", err);
180
+ // throw err;
181
+ // }
182
+ // };
183
+ // });
184
+ // };
173
185
 
174
186
  // Raw 쿼리 메서드 후킹
175
- PrismaObserver.prototype.hookRawQueryMethods = function(prismaInstance) {
176
- const self = this;
177
- const queryMethods = ["$queryRaw", "$executeRaw", "$queryRawUnsafe", "$executeRawUnsafe"];
178
-
179
- queryMethods.forEach(method => {
180
- if (typeof prismaInstance[method] === 'function') {
181
- shimmer.wrap(prismaInstance, method, function(original) {
182
- return async function() {
183
- const ctx = TraceContextManager.getCurrentContext();
184
- if (!ctx) {
185
- return original.apply(this, arguments);
186
- }
187
-
188
- const sql_step = new SqlStepX();
189
- sql_step.start_time = ctx.getElapsedTime();
190
- ctx.profile.push(sql_step);
191
- ctx.footprint(`Prisma ${method} Start`);
192
-
193
- ctx.sql_count = (ctx.sql_count || 0) + 1;
194
-
195
- // SQL 쿼리 추출
196
- let sql = "";
197
- let psql = null;
198
-
199
- if (arguments.length > 0) {
200
- if (typeof arguments[0] === "object" && arguments[0].sql) {
201
- // Tagged template으로 전달된 경우
202
- sql = arguments[0].sql;
203
- } else if (typeof arguments[0] === "string") {
204
- // Raw string으로 전달된 경우
205
- sql = arguments[0];
206
- }
207
- }
208
-
209
- // SQL 파싱
210
- if (sql && sql.length > 0) {
211
- try {
212
- psql = escapeLiteral(sql);
213
- } catch (e) {
214
- Logger.printError("WHATAP-303", "escapeliteral error", e, false);
215
- }
216
- } else {
217
- sql = "";
218
- psql = escapeLiteral(sql);
219
- }
220
-
221
- if (psql != null) {
222
- sql_step.hash = psql.sql;
223
- }
224
- sql_step.dbc = dbc_hash;
225
-
226
- var els = new EscapeLiteralSQL(sql);
227
- els.process();
228
-
229
- ctx.active_sqlhash = sql_step.hash;
230
- ctx.active_dbc = sql_step.dbc;
231
-
232
- // 파라미터 정보 추출
233
- if (conf.profile_sql_param_enabled) {
234
- var params = Array.from(arguments).slice(1);
235
- sql_step.setTrue(1);
236
- var crc = { value: 0 };
237
- sql_step.p1 = toParamBytes(psql.param, crc);
238
-
239
- if (params.length > 0) {
240
- const result = params.map((param) => {
241
- if (typeof param === "string") {
242
- return `'${param}'`;
243
- }
244
- return param;
245
- }).toString();
246
- sql_step.p2 = toParamBytes(result, crc);
247
- }
248
-
249
- sql_step.pcrc = crc.value;
250
- }
251
-
252
- try {
253
- const result = await original.apply(this, arguments);
254
-
255
- // SELECT 쿼리의 결과셋 처리
256
- if (method === "$queryRaw" || method === "$queryRawUnsafe") {
257
- if (Array.isArray(result)) {
258
- var result_step = new ResultSetStep();
259
- result_step.start_time = ctx.getElapsedTime();
260
- result_step.elapsed = 0;
261
- result_step.fetch = result.length;
262
- result_step.sqlhash = psql.sql;
263
- result_step.dbc = dbc_hash;
264
- ctx.profile.push(result_step);
265
-
266
- ctx.rs_count = ctx.rs_count ? ctx.rs_count + result.length : result.length;
267
- ctx.rs_time = ctx.rs_time ? ctx.rs_time + sql_step.elapsed : sql_step.elapsed;
268
-
269
- MeterSql.addFetch(result_step.dbc, result_step.fetch, 0);
270
- StatSql.addFetch(result_step.dbc, result_step.sqlhash, result_step.fetch, 0);
271
-
272
- TraceSQL.isTooManyRecords(sql_step, result_step.fetch, ctx);
273
- }
274
- }
275
-
276
- // UPDATE/INSERT/DELETE 쿼리 결과 처리
277
- if ((method === "$executeRaw" || method === "$executeRawUnsafe") && typeof result === "number") {
278
- sql_step.updated = result;
279
- }
280
-
281
- self._finishQuery(ctx, sql_step);
282
- return result;
283
- } catch (err) {
284
- Logger.printError("WHATAP-304", `${method} error: ${err.message}`, err);
285
-
286
- self._handleError(ctx, sql_step, err);
287
-
288
- if (conf.trace_sql_error_stack && conf.trace_sql_error_depth) {
289
- var traceDepth = conf.trace_sql_error_depth;
290
- var errorStack = err.stack.split("\n");
291
-
292
- if (errorStack.length > traceDepth) {
293
- errorStack = errorStack.slice(0, traceDepth + 1);
294
- }
295
-
296
- ctx.error_message = errorStack.join("\n");
297
- sql_step.error = ctx.error = StatError.addError("prisma-" + (err.code || "unknown"), err.message, ctx.service_hash, TextTypes.SQL, null);
298
- }
299
-
300
- throw err;
301
- }
302
- };
303
- });
304
- }
305
- });
306
- };
187
+ // PrismaObserver.prototype.hookRawQueryMethods = function(prismaInstance) {
188
+ // const self = this;
189
+ // const queryMethods = ["$queryRaw", "$executeRaw", "$queryRawUnsafe", "$executeRawUnsafe"];
190
+ //
191
+ // queryMethods.forEach(method => {
192
+ // if (typeof prismaInstance[method] === 'function') {
193
+ // shimmer.wrap(prismaInstance, method, function(original) {
194
+ // return async function() {
195
+ // const ctx = TraceContextManager.getCurrentContext();
196
+ // if (!ctx) {
197
+ // return original.apply(this, arguments);
198
+ // }
199
+ //
200
+ // const sql_step = new SqlStepX();
201
+ // sql_step.start_time = ctx.getElapsedTime();
202
+ // ctx.profile.push(sql_step);
203
+ // ctx.footprint(`Prisma ${method} Start`);
204
+ //
205
+ // ctx.sql_count = (ctx.sql_count || 0) + 1;
206
+ //
207
+ // // SQL 쿼리 추출
208
+ // let sql = "";
209
+ // let psql = null;
210
+ //
211
+ // if (arguments.length > 0) {
212
+ // if (typeof arguments[0] === "object" && arguments[0].sql) {
213
+ // // Tagged template으로 전달된 경우
214
+ // sql = arguments[0].sql;
215
+ // } else if (typeof arguments[0] === "string") {
216
+ // // Raw string으로 전달된 경우
217
+ // sql = arguments[0];
218
+ // }
219
+ // }
220
+ //
221
+ // // SQL 파싱
222
+ // if (sql && sql.length > 0) {
223
+ // try {
224
+ // psql = escapeLiteral(sql);
225
+ // } catch (e) {
226
+ // Logger.printError("WHATAP-303", "escapeliteral error", e, false);
227
+ // }
228
+ // } else {
229
+ // sql = "";
230
+ // psql = escapeLiteral(sql);
231
+ // }
232
+ //
233
+ // if (psql != null) {
234
+ // sql_step.hash = psql.sql;
235
+ // }
236
+ // sql_step.dbc = dbc_hash;
237
+ //
238
+ // var els = new EscapeLiteralSQL(sql);
239
+ // els.process();
240
+ //
241
+ // ctx.active_sqlhash = sql_step.hash;
242
+ // ctx.active_dbc = sql_step.dbc;
243
+ //
244
+ // // 파라미터 정보 추출
245
+ // if (conf.profile_sql_param_enabled) {
246
+ // var params = Array.from(arguments).slice(1);
247
+ // sql_step.setTrue(1);
248
+ // var crc = { value: 0 };
249
+ // sql_step.p1 = toParamBytes(psql.param, crc);
250
+ //
251
+ // if (params.length > 0) {
252
+ // const result = params.map((param) => {
253
+ // if (typeof param === "string") {
254
+ // return `'${param}'`;
255
+ // }
256
+ // return param;
257
+ // }).toString();
258
+ // sql_step.p2 = toParamBytes(result, crc);
259
+ // }
260
+ //
261
+ // sql_step.pcrc = crc.value;
262
+ // }
263
+ //
264
+ // try {
265
+ // const result = await original.apply(this, arguments);
266
+ //
267
+ // // SELECT 쿼리의 결과셋 처리
268
+ // if (method === "$queryRaw" || method === "$queryRawUnsafe") {
269
+ // if (Array.isArray(result)) {
270
+ // var result_step = new ResultSetStep();
271
+ // result_step.start_time = ctx.getElapsedTime();
272
+ // result_step.elapsed = 0;
273
+ // result_step.fetch = result.length;
274
+ // result_step.sqlhash = psql.sql;
275
+ // result_step.dbc = dbc_hash;
276
+ // ctx.profile.push(result_step);
277
+ //
278
+ // ctx.rs_count = ctx.rs_count ? ctx.rs_count + result.length : result.length;
279
+ // ctx.rs_time = ctx.rs_time ? ctx.rs_time + sql_step.elapsed : sql_step.elapsed;
280
+ //
281
+ // MeterSql.addFetch(result_step.dbc, result_step.fetch, 0);
282
+ // StatSql.addFetch(result_step.dbc, result_step.sqlhash, result_step.fetch, 0);
283
+ //
284
+ // TraceSQL.isTooManyRecords(sql_step, result_step.fetch, ctx);
285
+ // }
286
+ // }
287
+ //
288
+ // // UPDATE/INSERT/DELETE 쿼리 결과 처리
289
+ // if ((method === "$executeRaw" || method === "$executeRawUnsafe") && typeof result === "number") {
290
+ // sql_step.updated = result;
291
+ // }
292
+ //
293
+ // self._finishQuery(ctx, sql_step);
294
+ // return result;
295
+ // } catch (err) {
296
+ // Logger.printError("WHATAP-304", `${method} error: ${err.message}`, err);
297
+ //
298
+ // self._handleError(ctx, sql_step, err);
299
+ //
300
+ // if (conf.trace_sql_error_stack && conf.trace_sql_error_depth) {
301
+ // var traceDepth = conf.trace_sql_error_depth;
302
+ // var errorStack = err.stack.split("\n");
303
+ //
304
+ // if (errorStack.length > traceDepth) {
305
+ // errorStack = errorStack.slice(0, traceDepth + 1);
306
+ // }
307
+ //
308
+ // ctx.error_message = errorStack.join("\n");
309
+ // sql_step.error = ctx.error = StatError.addError("prisma-" + (err.code || "unknown"), err.message, ctx.service_hash, TextTypes.SQL, null);
310
+ // }
311
+ //
312
+ // throw err;
313
+ // }
314
+ // };
315
+ // });
316
+ // }
317
+ // });
318
+ // };
307
319
 
308
320
  PrismaObserver.prototype.hookUseMiddleware = function(prismaInstance) {
309
321
  const self = this;
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.9",
5
- "releaseDate": "20250305",
4
+ "version": "0.5.10",
5
+ "releaseDate": "20250310",
6
6
  "description": "Monitoring and Profiling Service",
7
7
  "main": "index.js",
8
8
  "scripts": {},