whatap 0.5.19 → 0.5.21

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
-
2
1
  var TraceContextManager = require('../trace/trace-context-manager'),
3
2
  SqlStepX = require('../step/sql-stepx'),
4
3
  DataTextAgent = require('../data/datatext-agent'),
5
4
  HashUtil = require('../util/hashutil');
6
- const DBCStep = require("whatap/lib/step/dbc-step");
7
- const Logger = require("whatap/lib/logger");
5
+ const DBCStep = require("../step/dbc-step");
6
+ const Logger = require("../logger");
7
+ const shimmer = require('../core/shimmer');
8
8
 
9
9
  var MongooseObserver = function (agent) {
10
10
  this.agent = agent;
@@ -12,8 +12,8 @@ var MongooseObserver = function (agent) {
12
12
  };
13
13
 
14
14
  var dbc_step, dbc, conn_dbc_hash;
15
- MongooseObserver.prototype.inject = function (mod, modName) {
16
15
 
16
+ MongooseObserver.prototype.inject = function (mod, modName) {
17
17
  var self = this;
18
18
  var hookCommand = [
19
19
  "create", // Create: Create a new document
@@ -34,133 +34,433 @@ MongooseObserver.prototype.inject = function (mod, modName) {
34
34
  "findByIdAndDelete" // Delete: Find a document by its ID and delete it
35
35
  ];
36
36
 
37
- self.agent.aop.after(mod, ['connect'] ,function (obj, args, ret) {
38
- if(!args[0]) { return; }
39
- if(dbc) { return; }
40
- dbc = args[0];
41
- conn_dbc_hash = HashUtil.hashFromString(dbc);
42
-
43
- ret.then(data => {
44
- self.agent.aop.both(data.Model, 'aggregate', function (_obj, _args, _lctx) {
45
- var ctx = TraceContextManager.getCurrentContext();
46
- if(!ctx) {return;}
47
-
48
- if(dbc && conn_dbc_hash){
49
- DataTextAgent.DBC.add(conn_dbc_hash, dbc);
50
- DataTextAgent.METHOD.add(conn_dbc_hash, dbc);
51
- DataTextAgent.ERROR.add(conn_dbc_hash, dbc);
37
+ // mongoose.connect 함수를 shimmer로 래핑
38
+ shimmer.wrap(mod, 'connect', function(original) {
39
+ return function wrappedConnect() {
40
+ var args = Array.prototype.slice.call(arguments);
41
+
42
+ if(!args[0]) {
43
+ return original.apply(this, arguments);
44
+ }
45
+
46
+ if(dbc) {
47
+ return original.apply(this, arguments);
48
+ }
49
+
50
+ dbc = args[0];
51
+ conn_dbc_hash = HashUtil.hashFromString(dbc);
52
+
53
+ var result = original.apply(this, arguments);
54
+
55
+ // Promise 체인으로 연결 성공 후 Model을 hook
56
+ result.then(connection => {
57
+ // Model 생성 시점을 intercept하기 위해 mongoose.model을 hook
58
+ self.hookModelCreation(mod);
59
+
60
+ }).catch(e => {
61
+ Logger.printError("WHATAP-612", "Mongodb connection error", e, false);
62
+ });
63
+
64
+ return result;
65
+ };
66
+ });
67
+
68
+ // 이미 생성된 모델들도 처리하기 위해 mongoose.model 함수를 hook
69
+ this.hookModelCreation(mod);
70
+ };
71
+
72
+ // Model 생성을 intercept하여 각 Model에 hook을 적용
73
+ MongooseObserver.prototype.hookModelCreation = function(mongoose) {
74
+ var self = this;
75
+
76
+ // mongoose.model 함수를 wrap하여 새로 생성되는 모델들을 intercept
77
+ if (!mongoose._whatapHooked) {
78
+ shimmer.wrap(mongoose, 'model', function(original) {
79
+ return function wrappedModel() {
80
+ var result = original.apply(this, arguments);
81
+
82
+ // 새로 생성된 Model에 hook 적용
83
+ if (result && typeof result === 'function') {
84
+ self.wrapModelMethods(result);
85
+ }
86
+
87
+ return result;
88
+ };
89
+ });
90
+ mongoose._whatapHooked = true;
91
+ }
92
+
93
+ // 이미 존재하는 모델들에도 hook 적용
94
+ var modelNames = mongoose.modelNames();
95
+ modelNames.forEach(function(modelName) {
96
+ var Model = mongoose.model(modelName);
97
+ self.wrapModelMethods(Model);
98
+ });
99
+ };
100
+
101
+ // Model의 메서드들을 wrap
102
+ MongooseObserver.prototype.wrapModelMethods = function(Model) {
103
+ var self = this;
104
+
105
+ if (Model._whatapHooked) {
106
+ return; // 이미 hook된 경우 스킵
107
+ }
108
+
109
+ // aggregate 메서드 hook (Model에 직접 정의됨)
110
+ if (typeof Model.aggregate === 'function') {
111
+ shimmer.wrap(Model, 'aggregate', function(original) {
112
+ return function wrappedAggregate() {
113
+ return self.wrapAggregateExecution(original, this, arguments);
114
+ };
115
+ });
116
+ }
117
+
118
+ // CRUD 메서드들 hook (대부분 Model에 직접 정의됨)
119
+ var hookCommand = [
120
+ "create", "insertMany", "find", "findById", "findOne",
121
+ "countDocuments", "distinct", "updateMany", "updateOne",
122
+ "replaceOne", "findOneAndUpdate", "findByIdAndUpdate",
123
+ "deleteOne", "deleteMany", "findOneAndDelete", "findByIdAndDelete"
124
+ ];
125
+
126
+ hookCommand.forEach(function(methodName) {
127
+ if (typeof Model[methodName] === 'function') {
128
+ shimmer.wrap(Model, methodName, function(original) {
129
+ return function wrappedMethod() {
130
+ return self.wrapMethodExecution(original, this, arguments, methodName);
131
+ };
132
+ });
133
+ }
134
+ });
135
+
136
+ Model._whatapHooked = true;
137
+ };
138
+
139
+ // aggregate 실행을 wrap하는 함수
140
+ MongooseObserver.prototype.wrapAggregateExecution = function(original, thisArg, args) {
141
+ var argsArray = Array.prototype.slice.call(args);
142
+ var ctx = TraceContextManager.getCurrentContext();
143
+
144
+ if(!ctx) {
145
+ return original.apply(thisArg, argsArray);
146
+ }
147
+
148
+ // DBC 정보 등록
149
+ if(dbc && conn_dbc_hash){
150
+ DataTextAgent.DBC.add(conn_dbc_hash, dbc);
151
+ DataTextAgent.METHOD.add(conn_dbc_hash, dbc);
152
+ DataTextAgent.ERROR.add(conn_dbc_hash, dbc);
153
+ }
154
+
155
+ // DBC Step 생성
156
+ var dbc_step = new DBCStep();
157
+ dbc_step.hash = conn_dbc_hash;
158
+ dbc_step.start_time = ctx.getElapsedTime();
159
+
160
+ // SQL Step 생성
161
+ var sql_step = new SqlStepX();
162
+ sql_step.start_time = ctx.getElapsedTime();
163
+
164
+ var result;
165
+ var hasError = false;
166
+
167
+ try {
168
+ // 원본 함수 실행
169
+ result = original.apply(thisArg, argsArray);
170
+
171
+ // Query 객체인 경우 exec 메서드를 wrap하여 실행 시점의 에러를 캐치
172
+ if (result && typeof result.exec === 'function') {
173
+ // Query 객체의 exec 메서드를 wrap
174
+ var originalExec = result.exec;
175
+ result.exec = function(callback) {
176
+ var execResult = originalExec.call(this, callback);
177
+
178
+ // Promise 체인에 catch 추가
179
+ if (execResult && typeof execResult.catch === 'function') {
180
+ execResult = execResult.catch(function(error) {
181
+ // 에러 정보를 컨텍스트에 설정
182
+ ctx.error_message = error.message || error.toString();
183
+ ctx.error_class = error.name || error.constructor?.name || 'MongooseAggregateError';
184
+
185
+ // 에러 정보를 DataTextAgent에도 추가
186
+ if (conn_dbc_hash) {
187
+ DataTextAgent.ERROR.add(conn_dbc_hash, ctx.error_message);
188
+ }
189
+
190
+ Logger.printError("WHATAP-611", "Mongodb aggregate execution error", error, false);
191
+ throw error; // 에러를 다시 던져서 원래 동작 유지
192
+ });
52
193
  }
53
194
 
54
- var dbc_step = new DBCStep();
55
- dbc_step.hash = conn_dbc_hash;
56
- dbc_step.start_time = ctx.getElapsedTime();
57
-
58
- _lctx.dbc_step = dbc_step;
59
-
60
- var sql_step = new SqlStepX();
61
- sql_step.start_time = ctx.getElapsedTime();
62
- _lctx.sql_step = sql_step;
63
- }, function (_obj, _args, _ret, _lctx) {
64
- var ctx = _lctx.context;
65
- var dbc_step = _lctx.dbc_step;
66
- var sql_step = _lctx.sql_step;
67
- if(!ctx || !dbc_step || !sql_step) {return null;}
68
-
69
- dbc_step.elapsed = ctx.getElapsedTime() - dbc_step.start_time;
70
- ctx.profile.push(dbc_step);
71
-
72
- ctx.footprint('Mongodb Command Start: ' + _ret.op );
73
-
74
- const mongooseCollection = _ret._model;
75
- try {
76
- var sql = mongooseCollection.modelName + ' aggregate';
77
- var param = "";
78
- if(Array.isArray(_args[0])) {
79
- _args[0].forEach(function (val, i) {
80
- if(i > 0 && param.length > 0) {
81
- param += ",";
82
- }
83
- if(val.hasOwnProperty('$match')) {
84
- var keys = Object.keys(val['$match']);
85
- param += keys;
86
- }
87
-
88
- if(val.hasOwnProperty('$group')) {
89
- var keys = Object.keys(val['$group']);
90
- param += keys;
91
- }
92
- })
93
- }
94
- sql += ' field=['+param+']';
95
-
96
- sql_step.hash = HashUtil.hashFromString(sql);
97
- sql_step.start_time = ctx.getElapsedTime();
98
- sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
99
- DataTextAgent.SQL.add(sql_step.hash, sql);
100
- ctx.profile.push(sql_step);
101
- } catch(e) {
102
- Logger.printError("WHATAP-611", "Mongodb query error", e, false);
103
- sql_step = null;
195
+ return execResult;
196
+ };
197
+
198
+ // then 메서드도 wrap (Promise 체인 사용 시)
199
+ var originalThen = result.then;
200
+ if (originalThen) {
201
+ result.then = function(onResolve, onReject) {
202
+ return originalThen.call(this, onResolve, function(error) {
203
+ // 에러 정보를 컨텍스트에 설정
204
+ ctx.error_message = error.message || error.toString();
205
+ ctx.error_class = error.name || error.constructor?.name || 'MongooseAggregateError';
206
+
207
+ // 에러 정보를 DataTextAgent에도 추가
208
+ if (conn_dbc_hash) {
209
+ DataTextAgent.ERROR.add(conn_dbc_hash, ctx.error_message);
210
+ }
211
+
212
+ Logger.printError("WHATAP-611", "Mongodb aggregate execution error", error, false);
213
+
214
+ // 원래 reject 핸들러가 있으면 호출, 없으면 에러를 다시 던짐
215
+ if (onReject) {
216
+ return onReject(error);
217
+ } else {
218
+ throw error;
219
+ }
220
+ });
221
+ };
222
+ }
223
+ }
224
+
225
+ // Promise인 경우 에러 처리를 위해 catch 추가 (직접 Promise를 반환하는 경우)
226
+ else if (result && typeof result.then === 'function') {
227
+ result = result.catch(function(error) {
228
+ // 에러 정보를 컨텍스트에 설정
229
+ ctx.error_message = error.message || error.toString();
230
+ ctx.error_class = error.name || error.constructor?.name || 'MongooseAggregateError';
231
+
232
+ // 에러 정보를 DataTextAgent에도 추가
233
+ if (conn_dbc_hash) {
234
+ DataTextAgent.ERROR.add(conn_dbc_hash, ctx.error_message);
104
235
  }
236
+
237
+ Logger.printError("WHATAP-611", "Mongodb aggregate execution error", error, false);
238
+ throw error; // 에러를 다시 던져서 원래 동작 유지
105
239
  });
240
+ }
241
+
242
+ } catch(error) {
243
+ hasError = true;
244
+ // 동기 에러 처리
245
+ ctx.error_message = error.message || error.toString();
246
+ ctx.error_class = error.name || error.constructor?.name || 'MongooseAggregateError';
247
+
248
+ // 에러 정보를 DataTextAgent에도 추가
249
+ if (conn_dbc_hash) {
250
+ DataTextAgent.ERROR.add(conn_dbc_hash, ctx.error_message);
251
+ }
252
+
253
+ Logger.printError("WHATAP-611", "Mongodb aggregate execution error", error, false);
254
+ throw error; // 에러를 다시 던져서 원래 동작 유지
255
+ }
256
+
257
+ // 결과 처리
258
+ try {
259
+ dbc_step.elapsed = ctx.getElapsedTime() - dbc_step.start_time;
260
+ ctx.profile.push(dbc_step);
261
+
262
+ // aggregate의 경우 op 속성이 없을 수 있음
263
+ var operation = result && result.op ? result.op : 'aggregate';
264
+ ctx.footprint('Mongodb Command Start: ' + operation);
106
265
 
107
- self.agent.aop.both(data.Model, hookCommand, function (_obj, _args, _lctx) {
108
- if(_args[0] && typeof _args[0] !== "object") { return; }
109
- const ctx = TraceContextManager.getCurrentContext();
110
- if(!ctx) { return; }
111
- if(dbc && conn_dbc_hash){
112
- DataTextAgent.DBC.add(conn_dbc_hash, dbc);
113
- DataTextAgent.METHOD.add(conn_dbc_hash, dbc);
114
- DataTextAgent.ERROR.add(conn_dbc_hash, dbc);
266
+ // Model 이름 가져오기
267
+ var modelName = thisArg.modelName || 'Unknown';
268
+
269
+ var sql = modelName + ' aggregate';
270
+ var param = "";
271
+
272
+ if(Array.isArray(argsArray[0])) {
273
+ argsArray[0].forEach(function (val, i) {
274
+ if(i > 0 && param.length > 0) {
275
+ param += ",";
276
+ }
277
+ if(val && val.hasOwnProperty('$match')) {
278
+ var keys = Object.keys(val['$match']);
279
+ param += keys.join(',');
115
280
  }
281
+ if(val && val.hasOwnProperty('$group')) {
282
+ var keys = Object.keys(val['$group']);
283
+ param += keys.join(',');
284
+ }
285
+ });
286
+ }
287
+ sql += ' field=['+param+']';
288
+
289
+ sql_step.hash = HashUtil.hashFromString(sql);
290
+ sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
291
+ DataTextAgent.SQL.add(sql_step.hash, sql);
292
+ ctx.profile.push(sql_step);
293
+
294
+ } catch(e) {
295
+ Logger.printError("WHATAP-611", "Mongodb aggregate query processing error", e, false);
296
+ }
297
+
298
+ return result;
299
+ };
300
+
301
+ // 일반 CRUD 메서드 실행을 wrap하는 함수
302
+ MongooseObserver.prototype.wrapMethodExecution = function(original, thisArg, args, methodName) {
303
+ var argsArray = Array.prototype.slice.call(args);
304
+
305
+ // 첫 번째 인자가 객체가 아니면 무시 (일부 메서드 제외)
306
+ if(argsArray[0] && typeof argsArray[0] !== "object" &&
307
+ !['findById', 'findByIdAndUpdate', 'findByIdAndDelete'].includes(methodName)) {
308
+ return original.apply(thisArg, argsArray);
309
+ }
116
310
 
117
- var dbc_step = new DBCStep();
118
- dbc_step.hash = conn_dbc_hash;
119
- dbc_step.start_time = ctx.getElapsedTime();
311
+ var ctx = TraceContextManager.getCurrentContext();
312
+ if(!ctx) {
313
+ return original.apply(thisArg, argsArray);
314
+ }
120
315
 
121
- _lctx.dbc_step = dbc_step;
316
+ // DBC 정보 등록
317
+ if(dbc && conn_dbc_hash){
318
+ DataTextAgent.DBC.add(conn_dbc_hash, dbc);
319
+ DataTextAgent.METHOD.add(conn_dbc_hash, dbc);
320
+ DataTextAgent.ERROR.add(conn_dbc_hash, dbc);
321
+ }
122
322
 
123
- var sql_step = new SqlStepX();
124
- sql_step.start_time = ctx.getElapsedTime();
125
- _lctx.sql_step = sql_step;
126
- }, function (_obj, _args, _ret, _lctx) {
127
- var ctx = _lctx.context;
128
- var dbc_step = _lctx.dbc_step;
129
- var sql_step = _lctx.sql_step;
130
- if(!ctx || !dbc_step || !sql_step) {return null;}
323
+ // DBC Step 생성
324
+ var dbc_step = new DBCStep();
325
+ dbc_step.hash = conn_dbc_hash;
326
+ dbc_step.start_time = ctx.getElapsedTime();
131
327
 
132
- dbc_step.elapsed = ctx.getElapsedTime() - dbc_step.start_time;
133
- ctx.profile.push(dbc_step);
328
+ // SQL Step 생성
329
+ var sql_step = new SqlStepX();
330
+ sql_step.start_time = ctx.getElapsedTime();
134
331
 
135
- ctx.footprint('Mongodb Command Start: ' + _ret.op );
332
+ var result;
333
+ var hasError = false;
136
334
 
137
- const mongooseCollection = _ret.mongooseCollection;
138
- try {
139
- if(mongooseCollection && mongooseCollection.modelName){
140
- var sql = mongooseCollection.modelName + ' ' + _ret.op;//+ ': ' + JSON.stringify(Object.keys(args[0]));
141
- if (_args[0]) {
142
- sql += ' field=' + JSON.stringify(Object.keys(_args[0]));
335
+ try {
336
+ // 원본 함수 실행
337
+ result = original.apply(thisArg, argsArray);
338
+
339
+ // Query 객체인 경우 exec 메서드를 wrap하여 실행 시점의 에러를 캐치
340
+ if (result && typeof result.exec === 'function') {
341
+ // Query 객체의 exec 메서드를 wrap
342
+ var originalExec = result.exec;
343
+ result.exec = function(callback) {
344
+ var execResult = originalExec.call(this, callback);
345
+
346
+ // Promise 체인에 catch 추가
347
+ if (execResult && typeof execResult.catch === 'function') {
348
+ execResult = execResult.catch(function(error) {
349
+ // 에러 정보를 컨텍스트에 설정
350
+ ctx.error_message = error.message || error.toString();
351
+ ctx.error_class = error.name || error.constructor?.name || 'MongooseError';
352
+
353
+ // 에러 정보를 DataTextAgent에도 추가
354
+ if (conn_dbc_hash) {
355
+ DataTextAgent.ERROR.add(conn_dbc_hash, ctx.error_message);
356
+ }
357
+
358
+ Logger.printError("WHATAP-611", "Mongodb " + methodName + " execution error", error, false);
359
+ throw error; // 에러를 다시 던져서 원래 동작 유지
360
+ });
361
+ }
362
+
363
+ return execResult;
364
+ };
365
+
366
+ // then 메서드도 wrap (Promise 체인 사용 시)
367
+ var originalThen = result.then;
368
+ if (originalThen) {
369
+ result.then = function(onResolve, onReject) {
370
+ return originalThen.call(this, onResolve, function(error) {
371
+ // 에러 정보를 컨텍스트에 설정
372
+ ctx.error_message = error.message || error.toString();
373
+ ctx.error_class = error.name || error.constructor?.name || 'MongooseError';
374
+
375
+ // 에러 정보를 DataTextAgent에도 추가
376
+ if (conn_dbc_hash) {
377
+ DataTextAgent.ERROR.add(conn_dbc_hash, ctx.error_message);
143
378
  }
144
- if (_args[1]) {
145
- sql += ' value=' + JSON.stringify(Object.keys(_args[1]));
379
+
380
+ Logger.printError("WHATAP-611", "Mongodb " + methodName + " execution error", error, false);
381
+
382
+ // 원래 reject 핸들러가 있으면 호출, 없으면 에러를 다시 던짐
383
+ if (onReject) {
384
+ return onReject(error);
385
+ } else {
386
+ throw error;
146
387
  }
388
+ });
389
+ };
390
+ }
391
+ } else if (result && typeof result.then === 'function') {
392
+ // Promise인 경우 에러 처리를 위해 catch 추가 (직접 Promise를 반환하는 경우)
393
+ result = result.catch(function(error) {
394
+ // 에러 정보를 컨텍스트에 설정
395
+ ctx.error_message = error.message || error.toString();
396
+ ctx.error_class = error.name || error.constructor?.name || 'MongooseError';
147
397
 
148
- sql_step.hash = HashUtil.hashFromString(sql);
149
- sql_step.start_time = ctx.getElapsedTime();
150
- sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
151
- DataTextAgent.SQL.add(sql_step.hash, sql);
152
- ctx.profile.push(sql_step);
153
- }
154
- } catch(e) {
155
- Logger.printError("WHATAP-611", "Mongodb query error", e, false);
156
- sql_step = null;
398
+ // 에러 정보를 DataTextAgent에도 추가
399
+ if (conn_dbc_hash) {
400
+ DataTextAgent.ERROR.add(conn_dbc_hash, ctx.error_message);
157
401
  }
158
- })
159
- }).catch(e => {
160
- Logger.printError("WHATAP-612", "Mongodb connection error", e, false);
161
- })
162
- })
163
402
 
403
+ Logger.printError("WHATAP-611", "Mongodb " + methodName + " execution error", error, false);
404
+ throw error; // 에러를 다시 던져서 원래 동작 유지
405
+ });
406
+ }
407
+
408
+ } catch(error) {
409
+ hasError = true;
410
+ // 동기 에러 처리
411
+ ctx.error_message = error.message || error.toString();
412
+ ctx.error_class = error.name || error.constructor?.name || 'MongooseError';
413
+
414
+ // 에러 정보를 DataTextAgent에도 추가
415
+ if (conn_dbc_hash) {
416
+ DataTextAgent.ERROR.add(conn_dbc_hash, ctx.error_message);
417
+ }
418
+
419
+ Logger.printError("WHATAP-611", "Mongodb " + methodName + " execution error", error, false);
420
+ throw error;
421
+ }
422
+
423
+ // 결과 처리
424
+ try {
425
+ dbc_step.elapsed = ctx.getElapsedTime() - dbc_step.start_time;
426
+ ctx.profile.push(dbc_step);
427
+
428
+ // operation 이름 가져오기
429
+ var operation = (result && result.op) ? result.op : methodName;
430
+ ctx.footprint('Mongodb Command Start: ' + operation);
431
+
432
+ // Model 이름 가져오기
433
+ var modelName = thisArg.modelName || 'Unknown';
434
+
435
+ var sql = modelName + ' ' + operation;
436
+
437
+ if (argsArray[0]) {
438
+ try {
439
+ var keys = typeof argsArray[0] === 'object' ? Object.keys(argsArray[0]) : [argsArray[0]];
440
+ sql += ' field=' + JSON.stringify(keys);
441
+ } catch(e) {
442
+ sql += ' field=[unknown]';
443
+ }
444
+ }
445
+ if (argsArray[1]) {
446
+ try {
447
+ var keys = typeof argsArray[1] === 'object' ? Object.keys(argsArray[1]) : [argsArray[1]];
448
+ sql += ' value=' + JSON.stringify(keys);
449
+ } catch(e) {
450
+ sql += ' value=[unknown]';
451
+ }
452
+ }
453
+
454
+ sql_step.hash = HashUtil.hashFromString(sql);
455
+ sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
456
+ DataTextAgent.SQL.add(sql_step.hash, sql);
457
+ ctx.profile.push(sql_step);
458
+
459
+ } catch(e) {
460
+ Logger.printError("WHATAP-611", "Mongodb query processing error", e, false);
461
+ }
462
+
463
+ return result;
164
464
  };
165
465
 
166
466
  exports.MongooseObserver = MongooseObserver;
@@ -95,6 +95,8 @@ MssqlObserver.prototype.inject = function (mod, modName) {
95
95
  self.aop.functionHook(args, -1, function (obj, args) {
96
96
  TraceContextManager.resume(ctx);
97
97
  if(args[0] != null) {
98
+ ctx.error_message = args[0].message;
99
+ ctx.error_class = args[0].name || args[0].constructor?.name || 'MSSQLError';
98
100
  if (conf.trace_sql_error_stack && conf.trace_sql_error_depth) {
99
101
  var traceDepth = conf.trace_sql_error_depth;
100
102
 
@@ -12,7 +12,6 @@ var TraceContextManager = require('../trace/trace-context-manager'),
12
12
  DataTextAgent = require('../data/datatext-agent'),
13
13
  StatSql = require('../stat/stat-sql'),
14
14
  MeterSql = require('../counter/meter/meter-sql'),
15
- conf = require('../conf/configure'),
16
15
  IntKeyMap = require('../util/intkey-map'),
17
16
  EscapeLiteralSQL = require('../util/escape-literal-sql'),
18
17
  HashUtil = require('../util/hashutil'),
@@ -27,7 +26,7 @@ var TraceContextManager = require('../trace/trace-context-manager'),
27
26
 
28
27
  var MysqlObserver = function (agent) {
29
28
  this.agent = agent;
30
- this.packages = ['mysql', 'mysql2'];
29
+ this.packages = ['mysql'];
31
30
  };
32
31
 
33
32
  var queryHook = function (dbc, agent) {
@@ -128,6 +127,10 @@ var queryHook = function (dbc, agent) {
128
127
  ctx.error_message = errorStack.join("\n");
129
128
  sql_step.error = ctx.error = StatError.addError('mysql-' + args[0].code, args[0].sqlMessage, ctx.service_hash, TextTypes.SQL, null);
130
129
  }
130
+ ctx.error_class = args[0].name || args[0].constructor?.name || 'MySQLError';
131
+ if (!ctx.error_message) {
132
+ ctx.error_message = args[0].message || args[0].sqlMessage || 'MySQL error';
133
+ }
131
134
  if (conf._is_trace_ignore_err_cls_contains === true && args[0].code.indexOf(conf.trace_ignore_err_cls_contains) < 0) {
132
135
  sql_step.error = StatError.addError('mysql-' + args[0].code, args[0].message || 'mysql error', ctx.service_hash, TextTypes.SQL, sql_step.hash); /*long*/
133
136
  if (ctx.error.isZero()) {