whatap 0.4.48 → 0.4.51

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.
@@ -4,7 +4,9 @@
4
4
  * can be found in the LICENSE file.
5
5
  */
6
6
 
7
+ const { reqlog_x_txid } = require('../conf/config-default');
7
8
  const controlHandler = require('../control/control-handler');
9
+ const RequestLog = require('../requestlog');
8
10
  var TraceContextManager = require('../trace/trace-context-manager'),
9
11
  URLPatternDetector = require('../trace/serviceurl-pattern-detector').Detector,
10
12
  DataTextAgent = require('../data/datatext-agent'),
@@ -124,6 +126,8 @@ HttpObserver.prototype.__createTransactionObserver = function(callback, isHttps,
124
126
  if (ctx.status >= 4 && ctx.error.isZero()) {
125
127
  ctx.error = StatError.addError(obj.statusCode, obj.statusMessage,
126
128
  ctx.service_hash);
129
+ ctx.statusCode = obj.statusCode;
130
+ ctx.statusMessage = obj.statusMessage;
127
131
  }
128
132
 
129
133
  self.__endTransaction(null, ctx, req, res);
@@ -356,7 +360,7 @@ HttpObserver.prototype.__endTransaction = function(error, ctx, req, res) {
356
360
  wtx.endTime = DateUtil.currentTime();
357
361
  profile.time = wtx.endTime;
358
362
  wtx.elapsed = ctx.getElapsedTime();
359
-
363
+
360
364
  ctx.service_hash = HashUtil.hashFromString(ctx.service_name);
361
365
  DataTextAgent.SERVICE.add(ctx.service_hash, ctx.service_name);
362
366
 
@@ -385,7 +389,7 @@ HttpObserver.prototype.__endTransaction = function(error, ctx, req, res) {
385
389
  wtx.status = ctx.status;
386
390
 
387
391
  wtx.http_method=TxRecord.HTTP_METHOD[ctx.http_method] || TxRecord.WEB_GET;
388
-
392
+ wtx.http_host = ctx.http_host;
389
393
  wtx.mtid=ctx.mtid;
390
394
  wtx.mdepth=ctx.mdepth;
391
395
  wtx.mcaller=ctx.mcaller_txid;
@@ -398,7 +402,11 @@ HttpObserver.prototype.__endTransaction = function(error, ctx, req, res) {
398
402
 
399
403
  profile.oid = SecurityMaster.OID;
400
404
  profile.service = wtx;
401
-
405
+ if(conf.reqlog_enabled === true) {
406
+ ctx.endTime = wtx.endTime;
407
+ ctx.elapsed = wtx.elapsed;
408
+ RequestLog.setRecord(ctx);
409
+ }
402
410
  //duplicated executed... so end() first
403
411
  TraceContextManager.end(ctx._id);
404
412
  setTimeout(function () {
@@ -406,6 +414,7 @@ HttpObserver.prototype.__endTransaction = function(error, ctx, req, res) {
406
414
  TraceContextManager.end(ctx._id);
407
415
  ctx = null;
408
416
  }, 100);
417
+
409
418
  } catch (e) {
410
419
  Logger.printError('WHATAP-607', 'End transaction error..', e, false);
411
420
  TraceContextManager.end(ctx._id);
@@ -603,7 +612,11 @@ HttpObserver.prototype.inject = function( mod, moduleName ) {
603
612
  if (step.error.isZero()) {
604
613
  step.error = StatError.addError(statusCode, response.statusMessage , ctx.service_hash,
605
614
  TextTypes.HTTPC_URL, step.url);
606
- if (ctx.error.isZero()) { ctx.error = step.error; }
615
+ if (ctx.error.isZero()) {
616
+ ctx.error = step.error;
617
+ ctx.statusCode = statusCode;
618
+ ctx.statusMessage = response.statusMessage;
619
+ }
607
620
  }
608
621
  }
609
622
  })
@@ -613,7 +626,11 @@ HttpObserver.prototype.inject = function( mod, moduleName ) {
613
626
  if (step.error.isZero()) {
614
627
  step.error = StatError.addError(err.code, err.message, ctx.service_hash,
615
628
  TextTypes.HTTPC_URL, step.url);
616
- if (ctx.error.isZero()) { ctx.error = step.error; }
629
+ if (ctx.error.isZero()) {
630
+ ctx.error = step.error;
631
+ ctx.statusCode = err.code;
632
+ ctx.statusMessage = err.message;
633
+ }
617
634
  }
618
635
 
619
636
  endHttpc(ctx, step);
@@ -661,6 +678,8 @@ HttpObserver.prototype.inject = function( mod, moduleName ) {
661
678
  step.error = StatError.addError('Timeout','Timeout', ctx.service_hash);
662
679
  if (ctx.error.isZero()) {
663
680
  ctx.error = step.error;
681
+ ctx.statusCode = 'Timeout';
682
+ ctx.statusMessage = 'Timeout';
664
683
  }
665
684
  }
666
685
  endHttpc(ctx, step);
@@ -0,0 +1,370 @@
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
+ ParsedSql = require('../trace/parsed-sql'),
9
+ SqlStepX = require('../step/sql-stepx'),
10
+ DBCStep = require('../step/dbc-step'),
11
+ ResultSetStep = require('../step/resultset-step'),
12
+ DataTextAgent = require('../data/datatext-agent'),
13
+ StatSql = require('../stat/stat-sql'),
14
+ MeterSql = require('../counter/meter/meter-sql'),
15
+ conf = require('../conf/configure'),
16
+ IntKeyMap = require('../util/intkey-map'),
17
+ EscapeLiteralSQL = require('../util/escape-literal-sql'),
18
+ HashUtil = require('../util/hashutil'),
19
+ StatError = require('../stat/stat-error'),
20
+ TextTypes = require('../lang/text-types'),
21
+ ParamSecurity = require('../util/paramsecurity'),
22
+ Logger = require('../logger'),
23
+ conf = require('../conf/configure'),
24
+ DateUtil = require('../util/dateutil'),
25
+ Buffer = require('buffer').Buffer;
26
+
27
+ var MariaObserver = function (agent) {
28
+ this.agent = agent;
29
+ this.packages = ['mariadb/callback'];
30
+ };
31
+
32
+ var queryHook = function (dbc_hash, agent) {
33
+
34
+ return function (obj, args) {
35
+ var ctx = TraceContextManager.getCurrentContext();
36
+
37
+ if (ctx == null || args[0] == null) { return; }
38
+ if(args[0].sql == null && typeof args[0] != 'string') { return; }
39
+
40
+ var sql_step = new SqlStepX();
41
+ sql_step.start_time = ctx.getElapsedTime();
42
+ ctx.profile.push(sql_step);
43
+
44
+ ctx.footprint('Maria Query Start');
45
+
46
+ ctx.sql_count++;
47
+
48
+ var sql = args.length > 0 ? args[0] : undefined,
49
+ psql = null;
50
+
51
+ if(typeof sql !== 'string') {
52
+ sql = args[0].sql || undefined;
53
+ }
54
+
55
+ if (typeof sql === 'string' && sql.length > 0) {
56
+ try {
57
+ psql = escapeLiteral(sql);
58
+ } catch (e) {
59
+ Logger.printError('WHATAP-191', 'MariaObserver escapeliteral error', e);
60
+ }
61
+ } else {
62
+ sql = '';
63
+ psql = escapeLiteral(sql);
64
+ }
65
+
66
+ if(psql != null) {
67
+ sql_step.hash = psql.sql;
68
+ // sql_step.crud = psql.type.charCodeAt(0);
69
+ }
70
+ sql_step.dbc = dbc_hash;
71
+
72
+ var els = new EscapeLiteralSQL(sql);
73
+ els.process();
74
+
75
+ ctx.active_sqlhash = sql_step.hash;
76
+ ctx.active_dbc = sql_step.dbc;
77
+ //ctx.active_crud = sql_step.crud;
78
+
79
+ if(conf.profile_sql_param_enabled) {
80
+ var params = args.length > 1 && Array.isArray(args[1]) ? args[1] : undefined;
81
+ sql_step.setTrue(1);
82
+ var crc = {value : 0};
83
+ sql_step.p1 = toParamBytes(psql.param, crc);
84
+ if(params != undefined) {
85
+ const result = params.map((param) => {
86
+ if(typeof param === 'string'){
87
+ return `'${param}'`
88
+ }
89
+ return param
90
+ }).toString()
91
+ sql_step.p2 = toParamBytes(result, crc);
92
+ }
93
+ sql_step.pcrc = crc.value;
94
+ }
95
+
96
+ var lastCallback = false;
97
+
98
+ function queryCallback(obj, args) {
99
+ if (ctx == null) { return; }
100
+ TraceContextManager.resume(ctx._id);
101
+
102
+ if(args[0]) {
103
+ try{
104
+ sql_step.error = StatError.addError(
105
+ ('Maria-'+args[0].code ),
106
+ (args[0].message || 'Maria error'),
107
+ ctx.service_hash,
108
+ TextTypes.SQL, sql_step.hash);
109
+ if(ctx.error.isZero()) {
110
+ ctx.error = sql_step.error;
111
+ }
112
+ }catch(e) {
113
+
114
+ }
115
+ }
116
+
117
+ sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
118
+ ctx.sql_time += sql_step.elapsed;
119
+
120
+ ctx.footprint('Maria Query Done');
121
+
122
+ MeterSql.add(dbc_hash, sql_step.elapsed, false);
123
+ StatSql.addSqlTime( ctx.service_hash, sql_step.dbc,
124
+ sql_step.hash, sql_step.elapsed, args[0] != null, 0);
125
+
126
+ if (Array.isArray(args[1]) && psql != null && psql.type === 'S') {
127
+ var result_step = new ResultSetStep();
128
+ result_step.start_time = ctx.getElapsedTime();
129
+ result_step.elapsed = 0;
130
+ result_step.fetch = args[1].length;
131
+ result_step.sqlhash = psql.sql;
132
+ result_step.dbc = dbc_hash;
133
+ ctx.profile.push(result_step);
134
+ MeterSql.addFetch(result_step.dbc, result_step.fetch, 0);
135
+ StatSql.addFetch(result_step.dbc, result_step.sqlhash, result_step.fetch, 0);
136
+ }
137
+
138
+ if (args[1] != null && psql != null && psql.type === 'U') {
139
+ sql_step.updated = args[1].affectedRows || 0;
140
+ //StatSql.addUpdate(dbc_hash, psql.sql, sql_step.updated);
141
+ }
142
+ }
143
+
144
+ lastCallback = agent.aop.functionHook(args, -1, queryCallback);
145
+
146
+ if(lastCallback === false && args.length>0 && args[0]._callback){
147
+ agent.aop.both(args[0], '_callback', queryCallback);
148
+ }
149
+ }
150
+ };
151
+
152
+ var toParamBytes = function(p, crc) {
153
+ if(p == null || p.length === 0) {
154
+ return null;
155
+ }
156
+ try{
157
+ return ParamSecurity.encrypt(Buffer.from(p), crc);
158
+ } catch(e) {
159
+ return null;
160
+ }
161
+ };
162
+
163
+ var errorDelegate = function () {
164
+ return function (obj, args) {
165
+ var ctx = TraceContextManager.getCurrentContext();
166
+ if(ctx == null) { return; }
167
+
168
+ var laststep = ctx.profile.getLastSteps(1);
169
+ if(laststep == null || laststep.length === 0) { return; }
170
+
171
+ var step = laststep[0];
172
+ if(!args[0].fatal) {
173
+ MeterSql.add(step.dbc, step.elapsed, true);
174
+ StatSql.addSqlTime(ctx, ctx.service_hash, step.dbc, step.hash, step.elapsed, true, 0);
175
+ }
176
+
177
+ try{
178
+ if(args[0].fatal) {
179
+ // Connection Error
180
+ step.error = StatError.addError( 'Maria-'+args[0].code, args[0].message, ctx.service_hash); /*long*/
181
+ } else {
182
+ step.error = StatError.addError( 'Maria-'+args[0].code, args[0].message, ctx.service_hash, TextTypes.SQL, step.hash); /*long*/
183
+ }
184
+ if (ctx.error.isZero()) { ctx.error = step.error; }
185
+ } catch(e) {
186
+ }
187
+ }
188
+ };
189
+
190
+ MariaObserver.prototype.inject = function (mod, moduleName) {
191
+ if(mod.__whatap_observe__) { return; }
192
+ mod.__whatap_observe__ = true;
193
+
194
+ var self = this;
195
+ var aop = self.agent.aop;
196
+
197
+ if( conf.sql_enabled === false ) { return; }
198
+ var dbc_hash=0;
199
+ aop.both(mod, 'createConnection',
200
+ function (obj, args, lctx) {
201
+ var ctx = lctx.context;
202
+ if(ctx == null || ctx.db_opening) { return; }
203
+ ctx.db_opening = true;
204
+ ctx.footprint('Maria Connecting Start');
205
+
206
+ var dbc_step = new DBCStep();
207
+ dbc_step.start_time = ctx.getElapsedTime();
208
+ lctx.step = dbc_step;
209
+ },
210
+ function (obj, args, ret, lctx) {
211
+ if(dbc_hash === 0){
212
+ var dbc;
213
+ if(args.length > 0) {
214
+ var info = (args[0] || {});
215
+ dbc = 'maria://';
216
+ dbc += info.user || '';
217
+ dbc += "@";
218
+ dbc += info.host || '';
219
+ dbc += '/';
220
+ dbc += info.database || '';
221
+ dbc_hash = HashUtil.hashFromString(dbc);
222
+ DataTextAgent.DBC.add(dbc_hash, dbc);
223
+ DataTextAgent.METHOD.add(dbc_hash, dbc);
224
+ DataTextAgent.ERROR.add(dbc_hash, dbc);
225
+ }
226
+ }
227
+
228
+ aop.both(ret, 'query', queryHook(dbc_hash, self.agent), function (obj, args, ret, lctx) {
229
+ var ctx = lctx.context;
230
+ TraceContextManager.resume(ctx);
231
+ });
232
+
233
+ aop.both(ret, 'execute', queryHook(dbc_hash, self.agent), function (obj, args, ret, lctx) {
234
+ var ctx = lctx.context;
235
+ TraceContextManager.resume(ctx);
236
+ });
237
+
238
+ aop.after(ret._protocol, '_delegateError', errorDelegate());
239
+
240
+ var ctx = lctx.context,
241
+ step = lctx.step;
242
+
243
+ if (ctx == null || step == null) { return; }
244
+
245
+ TraceContextManager.resume(ctx);
246
+ ctx.footprint('Maria Connecting Done');
247
+ ctx.db_opening = false;
248
+ step.hash = dbc_hash;
249
+
250
+ aop.both(ret, 'connect', function (obj, args) {
251
+ var ctx = TraceContextManager.getCurrentContext();
252
+ if (ctx == null) { return; }
253
+
254
+ ctx.footprint('Maria Connecting Start');
255
+
256
+ ctx.db_opening=true;
257
+
258
+ aop.functionHook(args, -1, function (obj, args) {
259
+ if (args[0] && step.error.isZero()) {
260
+ step.error = StatError.addError('Maria-'+args[0].code,
261
+ args[0].message, ctx.service_hash);
262
+ step.elapsed = ctx.getElapsedTime() - step.start_time;
263
+ }
264
+ TraceContextManager.resume(ctx._id);
265
+ });
266
+ ctx.profile.push(step);
267
+ }
268
+ ,
269
+ function (obj, args, ret, lctx) {
270
+ if(lctx.context){
271
+ ctx.db_opening=false;
272
+ ctx.footprint('Maria Connecting Done');
273
+ }
274
+ }
275
+ );
276
+ });
277
+
278
+
279
+ var dbc_pool_hash=0;
280
+ aop.after(mod, ['createPool', 'createPoolCluster'], function (obj, args, ret) {
281
+
282
+ var dbc = 'maria://';
283
+ if(dbc_pool_hash==0){
284
+ if(args.length > 0) {
285
+ var info = args[0];
286
+ //Open [DatabaseName] connection 메세지 보여줄때 필요함.
287
+ dbc += info.user || '';
288
+ dbc += "@";
289
+ dbc += info.host || '';
290
+ dbc += '/';
291
+ dbc += info.database || '';
292
+ }
293
+
294
+ dbc_pool_hash = HashUtil.hashFromString(dbc);
295
+ DataTextAgent.DBC.add(dbc_pool_hash, dbc);
296
+ DataTextAgent.METHOD.add(dbc_pool_hash, dbc);
297
+ DataTextAgent.ERROR.add(dbc_pool_hash, dbc);
298
+ }
299
+ aop.both(ret, 'getConnection', function (obj, args, lctx) {
300
+ var ctx = TraceContextManager.getCurrentContext();
301
+ if(ctx == null) {return;}
302
+
303
+ var dbc_step = new DBCStep();
304
+ dbc_step.hash = dbc_pool_hash;
305
+ dbc_step.start_time = ctx.getElapsedTime();
306
+
307
+ aop.functionHook(args, -1, function (obj, args) {
308
+ dbc_step.elapsed = ctx.getElapsedTime() - dbc_step.start_time;
309
+ ctx.profile.push(dbc_step);
310
+
311
+ TraceContextManager.resume(ctx._id);
312
+ DataTextAgent.DBC.add(dbc_hash, dbc);
313
+
314
+ if(args[0] != null) { return; }
315
+ var conn = args[1];
316
+ if(conn.__query_hook__) { return; }
317
+ conn.__query_hook__ = true;
318
+ aop.before(conn, 'query', queryHook(dbc_pool_hash, self.agent));
319
+ aop.before(conn, 'execute', queryHook(dbc_pool_hash, self.agent));
320
+ aop.before(conn._protocol, '_delegateError', errorDelegate(ctx));
321
+ });
322
+ }, function (obj, args, ret, lctx) {
323
+ MeterSql.setConnection(1, 0, dbc);
324
+ });
325
+ });
326
+ };
327
+
328
+ var checkedSql = new IntKeyMap(2000).setMax(2000);
329
+ var nonLiteSql = new IntKeyMap(5000).setMax(5000);
330
+ var date = DateUtil.yyyymmdd();
331
+
332
+ function escapeLiteral(sql) {
333
+ if(sql == null) { sql = ''; }
334
+
335
+ if(date !== DateUtil.yyyymmdd()) {
336
+ checkedSql.clear();
337
+ nonLiteSql.clear();
338
+ date = DateUtil.yyyymmdd();
339
+ Logger.print('WHATAP-SQL-CLEAR', 'MariaObserver CLEAR OK!!!!!!!!!!!!!!!!', false);
340
+ }
341
+
342
+ var sqlHash = HashUtil.hashFromString(sql);
343
+ var psql = nonLiteSql.get(sqlHash);
344
+
345
+ if(psql != null) {
346
+ return psql;
347
+ }
348
+ psql = checkedSql.get(sqlHash);
349
+
350
+ if(psql != null) {
351
+ return psql;
352
+ }
353
+
354
+ var els = new EscapeLiteralSQL(sql);
355
+ els.process();
356
+
357
+ var hash = HashUtil.hashFromString(els.getParsedSql());
358
+ DataTextAgent.SQL.add(hash, els.getParsedSql());
359
+
360
+ if(hash === sqlHash) {
361
+ psql = new ParsedSql(els.sqlType, hash, null);
362
+ nonLiteSql.put(sqlHash, psql);
363
+ } else {
364
+ psql = new ParsedSql(els.sqlType, hash, els.getParameter());
365
+ checkedSql.put(sqlHash, psql);
366
+ }
367
+ return psql;
368
+ }
369
+
370
+ exports.MariaObserver = MariaObserver;
@@ -26,7 +26,7 @@
26
26
 
27
27
  var MysqlObserver = function (agent) {
28
28
  this.agent = agent;
29
- this.packages = ['mysql','mysql2','mariadb'];
29
+ this.packages = ['mysql','mysql2'];
30
30
  };
31
31
 
32
32
  var queryHook = function (dbc_hash, agent) {