whatap 0.4.79 → 0.4.80

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.
Files changed (216) hide show
  1. package/.vscode/keep-context.json +3 -3
  2. package/README.md +51 -51
  3. package/bindings/darwin/x64/whatap.node +0 -0
  4. package/bindings/linux/ia32/whatap.node +0 -0
  5. package/bindings/linux/x64/whatap.node +0 -0
  6. package/help.txt +10 -10
  7. package/index.js +8 -8
  8. package/lib/conf/conf-sys-mon.js +100 -100
  9. package/lib/conf/config-default.js +238 -238
  10. package/lib/conf/configure.js +423 -423
  11. package/lib/conf/license.js +41 -41
  12. package/lib/control/cmd-config.js +23 -23
  13. package/lib/control/control-handler.js +344 -344
  14. package/lib/control/packagectr-helper.js +149 -149
  15. package/lib/core/agent.js +329 -328
  16. package/lib/core/interceptor.js +142 -142
  17. package/lib/core/request-agent.js +26 -26
  18. package/lib/counter/counter-manager.js +127 -127
  19. package/lib/counter/meter/meter-activex.js +66 -66
  20. package/lib/counter/meter/meter-httpc.js +57 -57
  21. package/lib/counter/meter/meter-resource.js +9 -9
  22. package/lib/counter/meter/meter-service.js +167 -167
  23. package/lib/counter/meter/meter-socket.io.js +50 -50
  24. package/lib/counter/meter/meter-sql.js +70 -70
  25. package/lib/counter/meter/meter-users.js +57 -57
  26. package/lib/counter/meter.js +183 -183
  27. package/lib/counter/task/activetransaction.js +93 -93
  28. package/lib/counter/task/agentinfo.js +105 -105
  29. package/lib/counter/task/counter-task.js +9 -9
  30. package/lib/counter/task/gcstat.js +34 -34
  31. package/lib/counter/task/heapmem.js +24 -24
  32. package/lib/counter/task/httpc.js +75 -75
  33. package/lib/counter/task/proc-cpu.js +28 -28
  34. package/lib/counter/task/realtimeuser.js +30 -30
  35. package/lib/counter/task/res/systemECSTask.js +54 -54
  36. package/lib/counter/task/res/systemKubeTask.js +52 -52
  37. package/lib/counter/task/res/util/awsEcsClientThread.js +166 -166
  38. package/lib/counter/task/res/util/linuxProcStatUtil.js +13 -13
  39. package/lib/counter/task/res-sys-cpu.js +61 -61
  40. package/lib/counter/task/service.js +201 -201
  41. package/lib/counter/task/socketio.js +29 -29
  42. package/lib/counter/task/sql.js +104 -104
  43. package/lib/counter/task/systemperf.js +42 -42
  44. package/lib/data/datapack-sender.js +256 -256
  45. package/lib/data/dataprofile-agent.js +136 -136
  46. package/lib/data/datatext-agent.js +135 -135
  47. package/lib/data/event-level.js +15 -15
  48. package/lib/data/test.js +48 -48
  49. package/lib/env/constants.js +20 -20
  50. package/lib/kube/kube-client.js +143 -143
  51. package/lib/lang/text-types.js +58 -58
  52. package/lib/logger.js +319 -319
  53. package/lib/net/netflag.js +54 -54
  54. package/lib/net/paramdef.js +40 -40
  55. package/lib/net/receiver.js +65 -65
  56. package/lib/net/security-master.js +182 -173
  57. package/lib/net/sender.js +140 -140
  58. package/lib/net/tcp-return.js +17 -17
  59. package/lib/net/tcp-session.js +285 -285
  60. package/lib/net/tcpreq-client-proxy.js +69 -69
  61. package/lib/net/tcprequest-mgr.js +57 -57
  62. package/lib/observers/cluster-observer.js +21 -21
  63. package/lib/observers/express-observer.js +214 -214
  64. package/lib/observers/file-observer.js +184 -184
  65. package/lib/observers/global-observer.js +30 -30
  66. package/lib/observers/http-observer.js +704 -704
  67. package/lib/observers/maria-observer.js +382 -382
  68. package/lib/observers/memcached-observer.js +55 -55
  69. package/lib/observers/mongo-observer.js +262 -265
  70. package/lib/observers/mongodb-observer.js +197 -197
  71. package/lib/observers/mongoose-observer.js +83 -83
  72. package/lib/observers/mssql-observer.js +205 -205
  73. package/lib/observers/mysql-observer.js +436 -394
  74. package/lib/observers/net-observer.js +72 -72
  75. package/lib/observers/pgsql-observer.js +295 -295
  76. package/lib/observers/process-observer.js +25 -25
  77. package/lib/observers/promise-observer.js +31 -31
  78. package/lib/observers/redis-observer.js +156 -109
  79. package/lib/observers/schedule-observer.js +66 -66
  80. package/lib/observers/socket.io-observer.js +54 -54
  81. package/lib/observers/stream-observer.js +19 -19
  82. package/lib/observers/thrift-observer.js +196 -196
  83. package/lib/pack/activestack-pack.js +54 -54
  84. package/lib/pack/counter-pack.js +649 -649
  85. package/lib/pack/errorsnap-pack.js +68 -68
  86. package/lib/pack/event-pack.js +53 -53
  87. package/lib/pack/hitmap-pack.js +62 -62
  88. package/lib/pack/hitmap-pack1.js +146 -146
  89. package/lib/pack/netstat.js +14 -14
  90. package/lib/pack/pack.js +49 -49
  91. package/lib/pack/packenum.js +60 -60
  92. package/lib/pack/param-pack.js +213 -213
  93. package/lib/pack/profile-pack.js +48 -48
  94. package/lib/pack/realtimeuser-pack.js +40 -40
  95. package/lib/pack/stat-general-pack.js +95 -95
  96. package/lib/pack/staterror-pack.js +119 -119
  97. package/lib/pack/stathttpc-pack.js +66 -66
  98. package/lib/pack/stathttpc-rec.js +78 -78
  99. package/lib/pack/statremote-pack.js +45 -45
  100. package/lib/pack/statservice-pack.js +62 -62
  101. package/lib/pack/statservice-pack1.js +87 -87
  102. package/lib/pack/statservice-rec.js +292 -292
  103. package/lib/pack/statservice-rec_dep.js +151 -151
  104. package/lib/pack/statsql-pack.js +69 -69
  105. package/lib/pack/statsql-rec.js +100 -100
  106. package/lib/pack/statuseragent-pack.js +43 -43
  107. package/lib/pack/tagcount-pack.js +398 -398
  108. package/lib/pack/tagctr.js +14 -14
  109. package/lib/pack/text-pack.js +49 -49
  110. package/lib/pack/time-count.js +25 -25
  111. package/lib/pack/websocket.js +14 -14
  112. package/lib/plugin/plugin-loadermanager.js +56 -56
  113. package/lib/plugin/plugin.js +75 -75
  114. package/lib/requestlog.js +326 -326
  115. package/lib/service/tx-record.js +288 -288
  116. package/lib/stat/stat-error.js +116 -116
  117. package/lib/stat/stat-httpc.js +97 -97
  118. package/lib/stat/stat-remoteip.js +46 -46
  119. package/lib/stat/stat-sql.js +112 -112
  120. package/lib/stat/stat-tranx.js +57 -57
  121. package/lib/stat/stat-tx-caller.js +159 -159
  122. package/lib/stat/stat-tx-domain.js +110 -110
  123. package/lib/stat/stat-tx-referer.js +111 -111
  124. package/lib/stat/stat-useragent.js +48 -48
  125. package/lib/stat/timingsender.js +72 -72
  126. package/lib/step/activestack-step.js +37 -37
  127. package/lib/step/dbc-step.js +35 -35
  128. package/lib/step/http-stepx.js +66 -66
  129. package/lib/step/message-step.js +39 -39
  130. package/lib/step/method-stepx.js +46 -46
  131. package/lib/step/resultset-step.js +39 -39
  132. package/lib/step/securemsg-step.js +43 -43
  133. package/lib/step/socket-step.js +46 -46
  134. package/lib/step/sql-stepx.js +67 -67
  135. package/lib/step/sqlxtype.js +15 -15
  136. package/lib/step/step.js +65 -65
  137. package/lib/step/stepenum.js +53 -53
  138. package/lib/trace/local-context.js +13 -13
  139. package/lib/trace/parsed-sql.js +13 -13
  140. package/lib/trace/profile-collector.js +70 -70
  141. package/lib/trace/serviceurl-pattern-detector.js +117 -117
  142. package/lib/trace/trace-context-manager.js +195 -195
  143. package/lib/trace/trace-context.js +134 -134
  144. package/lib/util/anylist.js +102 -102
  145. package/lib/util/array-util.js +100 -100
  146. package/lib/util/bitutil.js +27 -27
  147. package/lib/util/cardinality/hyperloglog.js +105 -105
  148. package/lib/util/cardinality/murmurhash.js +31 -31
  149. package/lib/util/cardinality/registerset.js +74 -74
  150. package/lib/util/config-util.js +17 -17
  151. package/lib/util/cypher.js +89 -89
  152. package/lib/util/datetimehelper.js +237 -229
  153. package/lib/util/dateutil.js +110 -106
  154. package/lib/util/errordata.js +20 -20
  155. package/lib/util/escape-literal-sql.js +342 -342
  156. package/lib/util/hashutil2.js +126 -126
  157. package/lib/util/hexa32.js +57 -57
  158. package/lib/util/index.js +78 -78
  159. package/lib/util/intint-map.js +47 -47
  160. package/lib/util/intkey-linkedmap.js +26 -26
  161. package/lib/util/intkey-map.js +25 -25
  162. package/lib/util/intset.js +82 -82
  163. package/lib/util/iputil.js +119 -119
  164. package/lib/util/iputil_x.js +526 -526
  165. package/lib/util/keygen.js +17 -17
  166. package/lib/util/kube-util.js +72 -72
  167. package/lib/util/longint-linkedmap.js +35 -35
  168. package/lib/util/longkey-linkedmap.js +25 -25
  169. package/lib/util/longlong-linkedmap.js +37 -37
  170. package/lib/util/nodeutil.js +67 -67
  171. package/lib/util/oidutil.js +96 -93
  172. package/lib/util/paramsecurity.js +78 -78
  173. package/lib/util/pathtree.js +172 -172
  174. package/lib/util/pre-process.js +13 -13
  175. package/lib/util/process-seq.js +165 -165
  176. package/lib/util/property-util.js +35 -35
  177. package/lib/util/request-queue.js +42 -42
  178. package/lib/util/requestdouble-queue.js +72 -72
  179. package/lib/util/resourceprofile.js +156 -156
  180. package/lib/util/seedrandom.js +242 -242
  181. package/lib/util/stop-watch.js +29 -29
  182. package/lib/util/string-util.js +9 -9
  183. package/lib/util/stringkey-linkedmap.js +28 -28
  184. package/lib/util/stringnum-linkedmap.js +31 -31
  185. package/lib/util/stringset.js +65 -65
  186. package/lib/util/system-util.js +9 -9
  187. package/lib/util/userid-util.js +57 -57
  188. package/lib/util/utils.js +67 -67
  189. package/lib/value/blob-value.js +61 -61
  190. package/lib/value/boolean-value.js +51 -51
  191. package/lib/value/decimal-value.js +71 -71
  192. package/lib/value/double-summary.js +105 -105
  193. package/lib/value/double-value.js +50 -50
  194. package/lib/value/float-array.js +59 -59
  195. package/lib/value/float-value.js +64 -64
  196. package/lib/value/int-array.js +59 -59
  197. package/lib/value/int-map-value.js +151 -151
  198. package/lib/value/int-value.js +64 -64
  199. package/lib/value/ip4-value.js +83 -83
  200. package/lib/value/list-value.js +136 -136
  201. package/lib/value/long-array.js +59 -59
  202. package/lib/value/long-summary.js +105 -105
  203. package/lib/value/map-value.js +175 -175
  204. package/lib/value/metric-value.js +157 -157
  205. package/lib/value/null-value.js +42 -42
  206. package/lib/value/number-value.js +34 -34
  207. package/lib/value/summary-value.js +29 -29
  208. package/lib/value/text-array.js +117 -117
  209. package/lib/value/text-value.js +59 -59
  210. package/lib/value/texthash-value.js +49 -49
  211. package/lib/value/value.js +14 -14
  212. package/lib/value/valueenum.js +99 -99
  213. package/logs/whatap-20230906.log +54 -0
  214. package/package.json +28 -28
  215. package/whatap.conf +1 -1
  216. package/logs/whatap-20230616.log +0 -13
@@ -1,395 +1,437 @@
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 MysqlObserver = function (agent) {
28
- this.agent = agent;
29
- this.packages = ['mysql','mysql2'];
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('MySql 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', 'MysqlObserver 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
- if(conf._is_trace_ignore_err_cls_contains === true && args[0].code.indexOf(conf.trace_ignore_err_cls_contains) < 0 ){
105
- sql_step.error = StatError.addError( 'mysql-'+args[0].code, args[0].message || 'mysql error', ctx.service_hash, TextTypes.SQL, step.hash); /*long*/
106
- if (ctx.error.isZero()) { ctx.error = sql_step.error; }
107
- } else if(conf._is_trace_ignore_err_msg_contains === true && args[0].message.indexOf(conf.trace_ignore_err_msg_contains) < 0 ){
108
- sql_step.error = StatError.addError( 'mysql-'+args[0].code, args[0].message || 'mysql error', ctx.service_hash, TextTypes.SQL, step.hash); /*long*/
109
- if (ctx.error.isZero()) { ctx.error = sql_step.error; }
110
- } else if(conf._is_trace_ignore_err_cls_contains === false && conf._is_trace_ignore_err_msg_contains === false) {
111
- sql_step.error = StatError.addError( 'mysql-'+args[0].code, args[0].message || 'mysql error', ctx.service_hash, TextTypes.SQL, step.hash); /*long*/
112
- if (ctx.error.isZero()) { ctx.error = sql_step.error; }
113
- }
114
- /*
115
- sql_step.error = StatError.addError(
116
- ('mysql-'+args[0].code ),
117
- (args[0].message || 'mysql error'),
118
- ctx.service_hash,
119
- TextTypes.SQL, sql_step.hash);
120
- if(ctx.error.isZero()) {
121
- ctx.error = sql_step.error;
122
- }
123
- */
124
- }catch(e) {
125
-
126
- }
127
- }
128
-
129
- sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
130
- ctx.sql_time += sql_step.elapsed;
131
-
132
- ctx.footprint('MySql Query Done');
133
-
134
- MeterSql.add(dbc_hash, sql_step.elapsed, false);
135
- StatSql.addSqlTime( ctx.service_hash, sql_step.dbc,
136
- sql_step.hash, sql_step.elapsed, args[0] != null, 0);
137
-
138
- if (Array.isArray(args[1]) && psql != null && psql.type === 'S') {
139
- var result_step = new ResultSetStep();
140
- result_step.start_time = ctx.getElapsedTime();
141
- result_step.elapsed = 0;
142
- result_step.fetch = args[1].length;
143
- result_step.sqlhash = psql.sql;
144
- result_step.dbc = dbc_hash;
145
- ctx.profile.push(result_step);
146
- MeterSql.addFetch(result_step.dbc, result_step.fetch, 0);
147
- StatSql.addFetch(result_step.dbc, result_step.sqlhash, result_step.fetch, 0);
148
- }
149
-
150
- if (args[1] != null && psql != null && psql.type === 'U') {
151
- sql_step.updated = args[1].affectedRows || 0;
152
- //StatSql.addUpdate(dbc_hash, psql.sql, sql_step.updated);
153
- }
154
- }
155
-
156
- lastCallback = agent.aop.functionHook(args, -1, queryCallback);
157
-
158
- if(lastCallback === false && args.length>0 && args[0]._callback){
159
- agent.aop.both(args[0], '_callback', queryCallback);
160
- }
161
- }
162
- };
163
-
164
- var toParamBytes = function(p, crc) {
165
- if(p == null || p.length === 0) {
166
- return null;
167
- }
168
- try{
169
- return ParamSecurity.encrypt(Buffer.from(p, 'utf8'), crc);
170
- } catch(e) {
171
- return null;
172
- }
173
- };
174
-
175
- var errorDelegate = function () {
176
- return function (obj, args) {
177
- var ctx = TraceContextManager.getCurrentContext();
178
- if(ctx == null) { return; }
179
-
180
- var laststep = ctx.profile.getLastSteps(1);
181
- if(laststep == null || laststep.length === 0) { return; }
182
-
183
- var step = laststep[0];
184
- if(!args[0].fatal) {
185
- MeterSql.add(step.dbc, step.elapsed, true);
186
- StatSql.addSqlTime(ctx, ctx.service_hash, step.dbc, step.hash, step.elapsed, true, 0);
187
- }
188
-
189
- try{
190
- if(args[0].fatal) {
191
- step.error = StatError.addError( 'mysql-'+args[0].code, args[0].message, ctx.service_hash); /*long*/
192
- if (ctx.error.isZero()) { ctx.error = step.error; }
193
- } else {
194
- if(conf._is_trace_ignore_err_cls_contains === true && args[0].code.indexOf(conf.trace_ignore_err_cls_contains) < 0){
195
- step.error = StatError.addError( 'mysql-'+args[0].code, args[0].message, ctx.service_hash, TextTypes.SQL, step.hash); /*long*/
196
- if (ctx.error.isZero()) { ctx.error = step.error; }
197
- } else if(conf._is_trace_ignore_err_msg_contains === true && args[0].message.indexOf(conf.trace_ignore_err_msg_contains) < 0){
198
- step.error = StatError.addError( 'mysql-'+args[0].code, args[0].message, ctx.service_hash, TextTypes.SQL, step.hash); /*long*/
199
- if (ctx.error.isZero()) { ctx.error = step.error; }
200
- } else if(conf._is_trace_ignore_err_cls_contains === false && conf._is_trace_ignore_err_msg_contains === false) {
201
- step.error = StatError.addError( 'mysql-'+args[0].code, args[0].message, ctx.service_hash, TextTypes.SQL, step.hash); /*long*/
202
- if (ctx.error.isZero()) { ctx.error = step.error; }
203
- }
204
- }
205
- } catch(e) {
206
- }
207
- }
208
- };
209
-
210
- MysqlObserver.prototype.inject = function (mod, moduleName) {
211
- if(mod.__whatap_observe__) { return; }
212
- mod.__whatap_observe__ = true;
213
- Logger.initPrint("MysqlObserver");
214
- var self = this;
215
- var aop = self.agent.aop;
216
-
217
- if( conf.sql_enabled === false ) { return; }
218
-
219
- var dbc_hash=0;
220
- aop.both(mod, 'createConnection',
221
- function (obj, args, lctx) {
222
- var ctx = lctx.context;
223
- if(ctx == null || ctx.db_opening) { return; }
224
- ctx.db_opening = true;
225
- ctx.footprint('MySql Connecting Start');
226
-
227
- var dbc_step = new DBCStep();
228
- dbc_step.start_time = ctx.getElapsedTime();
229
- lctx.step = dbc_step;
230
- },
231
- function (obj, args, ret, lctx) {
232
-
233
- if(dbc_hash === 0){
234
- var dbc;
235
- if(args.length > 0) {
236
- var info = (args[0] || {});
237
- dbc = 'mysql://';
238
- dbc += info.user || '';
239
- dbc += "@";
240
- dbc += info.host || '';
241
- dbc += '/';
242
- dbc += info.database || '';
243
- dbc_hash = HashUtil.hashFromString(dbc);
244
- DataTextAgent.DBC.add(dbc_hash, dbc);
245
- DataTextAgent.METHOD.add(dbc_hash, dbc);
246
- DataTextAgent.ERROR.add(dbc_hash, dbc);
247
- }
248
- }
249
-
250
- aop.both(ret, 'query', queryHook(dbc_hash, self.agent), function (obj, args, ret, lctx) {
251
- var ctx = lctx.context;
252
- TraceContextManager.resume(ctx);
253
- });
254
-
255
- aop.both(ret, 'execute', queryHook(dbc_hash, self.agent), function (obj, args, ret, lctx) {
256
- var ctx = lctx.context;
257
- TraceContextManager.resume(ctx);
258
- });
259
-
260
- aop.after(ret._protocol, '_delegateError', errorDelegate());
261
-
262
- var ctx = lctx.context,
263
- step = lctx.step;
264
-
265
- if (ctx == null || step == null) { return; }
266
-
267
- TraceContextManager.resume(ctx);
268
- ctx.footprint('MySql Connecting Done');
269
- ctx.db_opening = false;
270
- step.hash = dbc_hash;
271
-
272
- aop.both(ret, 'connect', function (obj, args) {
273
- var ctx = TraceContextManager.getCurrentContext();
274
- if (ctx == null) { return; }
275
-
276
- ctx.footprint('MySql Connecting Start');
277
-
278
- ctx.db_opening=true;
279
-
280
- aop.functionHook(args, -1, function (obj, args) {
281
- if (args[0] && step.error.isZero()) {
282
- step.error = StatError.addError('mysql-'+args[0].code,
283
- args[0].message, ctx.service_hash);
284
- step.elapsed = ctx.getElapsedTime() - step.start_time;
285
- }
286
- TraceContextManager.resume(ctx._id);
287
- });
288
- ctx.profile.push(step);
289
- }
290
- ,
291
- function (obj, args, ret, lctx) {
292
- if(lctx.context){
293
- ctx.db_opening=false;
294
- ctx.footprint('MySql Connecting Done');
295
- }
296
- }
297
- );
298
- });
299
-
300
-
301
- var dbc_pool_hash=0;
302
- aop.after(mod, ['createPool'], function (obj, args, ret) {
303
- var dbc = 'mysql://';
304
- if(dbc_pool_hash==0){
305
- if(args.length > 0) {
306
- var info = args[0];
307
- //Open [DatabaseName] connection 메세지 보여줄때 필요함.
308
- dbc += info.user || '';
309
- dbc += "@";
310
- dbc += info.host || '';
311
- dbc += '/';
312
- dbc += info.database || '';
313
- }
314
-
315
- dbc_pool_hash = HashUtil.hashFromString(dbc);
316
- DataTextAgent.DBC.add(dbc_pool_hash, dbc);
317
- DataTextAgent.METHOD.add(dbc_pool_hash, dbc);
318
- DataTextAgent.ERROR.add(dbc_pool_hash, dbc);
319
- }
320
- aop.both(ret, 'getConnection', function (obj, args, lctx) {
321
- var ctx = TraceContextManager.getCurrentContext();
322
- if(ctx == null) {return;}
323
-
324
- var dbc_step = new DBCStep();
325
- dbc_step.hash = dbc_pool_hash;
326
- dbc_step.start_time = ctx.getElapsedTime();
327
-
328
- aop.functionHook(args, -1, function (obj, args) {
329
- dbc_step.elapsed = ctx.getElapsedTime() - dbc_step.start_time;
330
- ctx.profile.push(dbc_step);
331
-
332
- TraceContextManager.resume(ctx._id);
333
- DataTextAgent.DBC.add(dbc_hash, dbc);
334
-
335
- if(args[0] != null) { return; }
336
- var conn = args[1];
337
- if(conn.__query_hook__) { return; }
338
- conn.__query_hook__ = true;
339
- aop.before(conn, 'query', queryHook(dbc_pool_hash, self.agent));
340
- aop.before(conn, 'execute', queryHook(dbc_pool_hash, self.agent));
341
- aop.before(conn._protocol, '_delegateError', errorDelegate(ctx));
342
- });
343
- }, function (obj, args, ret, lctx) {
344
- if(obj._allConnections != undefined) {
345
- var all = obj._allConnections.length;
346
- var idle = obj._freeConnections.length;
347
- MeterSql.setConnection((all - idle), idle, dbc);
348
- }
349
- });
350
- });
351
- };
352
-
353
- var checkedSql = new IntKeyMap(2000).setMax(2000);
354
- var nonLiteSql = new IntKeyMap(5000).setMax(5000);
355
- var date = DateUtil.yyyymmdd();
356
-
357
- function escapeLiteral(sql) {
358
- if(sql == null) { sql = ''; }
359
-
360
- if(date !== DateUtil.yyyymmdd()) {
361
- checkedSql.clear();
362
- nonLiteSql.clear();
363
- date = DateUtil.yyyymmdd();
364
- Logger.print('WHATAP-SQL-CLEAR', 'MysqlObserver CLEAR OK!!!!!!!!!!!!!!!!', false);
365
- }
366
-
367
- var sqlHash = HashUtil.hashFromString(sql);
368
- var psql = nonLiteSql.get(sqlHash);
369
-
370
- if(psql != null) {
371
- return psql;
372
- }
373
- psql = checkedSql.get(sqlHash);
374
-
375
- if(psql != null) {
376
- return psql;
377
- }
378
-
379
- var els = new EscapeLiteralSQL(sql);
380
- els.process();
381
-
382
- var hash = HashUtil.hashFromString(els.getParsedSql());
383
- DataTextAgent.SQL.add(hash, els.getParsedSql());
384
-
385
- if(hash === sqlHash) {
386
- psql = new ParsedSql(els.sqlType, hash, null);
387
- nonLiteSql.put(sqlHash, psql);
388
- } else {
389
- psql = new ParsedSql(els.sqlType, hash, els.getParameter());
390
- checkedSql.put(sqlHash, psql);
391
- }
392
- return psql;
393
- }
394
-
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 MysqlObserver = function (agent) {
28
+ this.agent = agent;
29
+ this.packages = ['mysql', 'mysql2'];
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) {
38
+ return;
39
+ }
40
+ if (args[0].sql == null && typeof args[0] != 'string') {
41
+ return;
42
+ }
43
+
44
+ var sql_step = new SqlStepX();
45
+ sql_step.start_time = ctx.getElapsedTime();
46
+ ctx.profile.push(sql_step);
47
+
48
+ ctx.footprint('MySql Query Start');
49
+
50
+ ctx.sql_count++;
51
+
52
+ var sql = args.length > 0 ? args[0] : undefined,
53
+ psql = null;
54
+
55
+ if (typeof sql !== 'string') {
56
+ sql = args[0].sql || undefined;
57
+ }
58
+
59
+ if (typeof sql === 'string' && sql.length > 0) {
60
+ try {
61
+ psql = escapeLiteral(sql);
62
+ } catch (e) {
63
+ Logger.printError('WHATAP-191', 'MysqlObserver escapeliteral error', e);
64
+ }
65
+ } else {
66
+ sql = '';
67
+ psql = escapeLiteral(sql);
68
+ }
69
+
70
+ if (psql != null) {
71
+ sql_step.hash = psql.sql;
72
+ // sql_step.crud = psql.type.charCodeAt(0);
73
+ }
74
+ sql_step.dbc = dbc_hash;
75
+
76
+ var els = new EscapeLiteralSQL(sql);
77
+ els.process();
78
+
79
+ ctx.active_sqlhash = sql_step.hash;
80
+ ctx.active_dbc = sql_step.dbc;
81
+ //ctx.active_crud = sql_step.crud;
82
+
83
+ if (conf.profile_sql_param_enabled) {
84
+ var params = args.length > 1 && Array.isArray(args[1]) ? args[1] : undefined;
85
+ sql_step.setTrue(1);
86
+ var crc = {value: 0};
87
+ sql_step.p1 = toParamBytes(psql.param, crc);
88
+ if (params != undefined) {
89
+ const result = params.map((param) => {
90
+ if (typeof param === 'string') {
91
+ return `'${param}'`
92
+ }
93
+ return param
94
+ }).toString()
95
+ sql_step.p2 = toParamBytes(result, crc);
96
+ }
97
+ sql_step.pcrc = crc.value;
98
+ }
99
+
100
+ var lastCallback = false;
101
+
102
+ function queryCallback(obj, args) {
103
+ if (ctx == null) {
104
+ return;
105
+ }
106
+ TraceContextManager.resume(ctx._id);
107
+
108
+ if (args[0]) {
109
+ try {
110
+ if (conf._is_trace_ignore_err_cls_contains === true && args[0].code.indexOf(conf.trace_ignore_err_cls_contains) < 0) {
111
+ sql_step.error = StatError.addError('mysql-' + args[0].code, args[0].message || 'mysql error', ctx.service_hash, TextTypes.SQL, step.hash); /*long*/
112
+ if (ctx.error.isZero()) {
113
+ ctx.error = sql_step.error;
114
+ }
115
+ } else if (conf._is_trace_ignore_err_msg_contains === true && args[0].message.indexOf(conf.trace_ignore_err_msg_contains) < 0) {
116
+ sql_step.error = StatError.addError('mysql-' + args[0].code, args[0].message || 'mysql error', ctx.service_hash, TextTypes.SQL, step.hash); /*long*/
117
+ if (ctx.error.isZero()) {
118
+ ctx.error = sql_step.error;
119
+ }
120
+ } else if (conf._is_trace_ignore_err_cls_contains === false && conf._is_trace_ignore_err_msg_contains === false) {
121
+ sql_step.error = StatError.addError('mysql-' + args[0].code, args[0].message || 'mysql error', ctx.service_hash, TextTypes.SQL, step.hash); /*long*/
122
+ if (ctx.error.isZero()) {
123
+ ctx.error = sql_step.error;
124
+ }
125
+ }
126
+ /*
127
+ sql_step.error = StatError.addError(
128
+ ('mysql-'+args[0].code ),
129
+ (args[0].message || 'mysql error'),
130
+ ctx.service_hash,
131
+ TextTypes.SQL, sql_step.hash);
132
+ if(ctx.error.isZero()) {
133
+ ctx.error = sql_step.error;
134
+ }
135
+ */
136
+ } catch (e) {
137
+
138
+ }
139
+ }
140
+
141
+ sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
142
+ ctx.sql_time += sql_step.elapsed;
143
+
144
+ ctx.footprint('MySql Query Done');
145
+
146
+ MeterSql.add(dbc_hash, sql_step.elapsed, false);
147
+ StatSql.addSqlTime(ctx.service_hash, sql_step.dbc,
148
+ sql_step.hash, sql_step.elapsed, args[0] != null, 0);
149
+
150
+ if (Array.isArray(args[1]) && psql != null && psql.type === 'S') {
151
+ var result_step = new ResultSetStep();
152
+ result_step.start_time = ctx.getElapsedTime();
153
+ result_step.elapsed = 0;
154
+ result_step.fetch = args[1].length;
155
+ result_step.sqlhash = psql.sql;
156
+ result_step.dbc = dbc_hash;
157
+ ctx.profile.push(result_step);
158
+ MeterSql.addFetch(result_step.dbc, result_step.fetch, 0);
159
+ StatSql.addFetch(result_step.dbc, result_step.sqlhash, result_step.fetch, 0);
160
+ }
161
+
162
+ if (args[1] != null && psql != null && psql.type === 'U') {
163
+ sql_step.updated = args[1].affectedRows || 0;
164
+ //StatSql.addUpdate(dbc_hash, psql.sql, sql_step.updated);
165
+ }
166
+ }
167
+
168
+ lastCallback = agent.aop.functionHook(args, -1, queryCallback);
169
+
170
+ if (lastCallback === false && args.length > 0 && args[0]._callback) {
171
+ agent.aop.both(args[0], '_callback', queryCallback);
172
+ }
173
+ }
174
+ };
175
+
176
+ var toParamBytes = function (p, crc) {
177
+ if (p == null || p.length === 0) {
178
+ return null;
179
+ }
180
+ try {
181
+ return ParamSecurity.encrypt(Buffer.from(p, 'utf8'), crc);
182
+ } catch (e) {
183
+ return null;
184
+ }
185
+ };
186
+
187
+ var errorDelegate = function () {
188
+ return function (obj, args) {
189
+ var ctx = TraceContextManager.getCurrentContext();
190
+ if (ctx == null) {
191
+ return;
192
+ }
193
+
194
+ var laststep = ctx.profile.getLastSteps(1);
195
+ if (laststep == null || laststep.length === 0) {
196
+ return;
197
+ }
198
+
199
+ var step = laststep[0];
200
+ if (!args[0].fatal) {
201
+ MeterSql.add(step.dbc, step.elapsed, true);
202
+ StatSql.addSqlTime(ctx, ctx.service_hash, step.dbc, step.hash, step.elapsed, true, 0);
203
+ }
204
+
205
+ try {
206
+ if (args[0].fatal) {
207
+ step.error = StatError.addError('mysql-' + args[0].code, args[0].message, ctx.service_hash); /*long*/
208
+ if (ctx.error.isZero()) {
209
+ ctx.error = step.error;
210
+ }
211
+ } else {
212
+ if (conf._is_trace_ignore_err_cls_contains === true && args[0].code.indexOf(conf.trace_ignore_err_cls_contains) < 0) {
213
+ step.error = StatError.addError('mysql-' + args[0].code, args[0].message, ctx.service_hash, TextTypes.SQL, step.hash); /*long*/
214
+ if (ctx.error.isZero()) {
215
+ ctx.error = step.error;
216
+ }
217
+ } else if (conf._is_trace_ignore_err_msg_contains === true && args[0].message.indexOf(conf.trace_ignore_err_msg_contains) < 0) {
218
+ step.error = StatError.addError('mysql-' + args[0].code, args[0].message, ctx.service_hash, TextTypes.SQL, step.hash); /*long*/
219
+ if (ctx.error.isZero()) {
220
+ ctx.error = step.error;
221
+ }
222
+ } else if (conf._is_trace_ignore_err_cls_contains === false && conf._is_trace_ignore_err_msg_contains === false) {
223
+ step.error = StatError.addError('mysql-' + args[0].code, args[0].message, ctx.service_hash, TextTypes.SQL, step.hash); /*long*/
224
+ if (ctx.error.isZero()) {
225
+ ctx.error = step.error;
226
+ }
227
+ }
228
+ }
229
+ } catch (e) {
230
+ }
231
+ }
232
+ };
233
+
234
+ MysqlObserver.prototype.inject = function (mod, moduleName) {
235
+ if (mod.__whatap_observe__) {
236
+ return;
237
+ }
238
+ mod.__whatap_observe__ = true;
239
+ Logger.initPrint("MysqlObserver");
240
+ var self = this;
241
+ var aop = self.agent.aop;
242
+
243
+ if (conf.sql_enabled === false) {
244
+ return;
245
+ }
246
+
247
+ var dbc_hash = 0;
248
+ aop.both(mod, 'createConnection',
249
+ function (obj, args, lctx) {
250
+ var ctx = lctx.context;
251
+ if (ctx == null || ctx.db_opening) {
252
+ return;
253
+ }
254
+ ctx.db_opening = true;
255
+ ctx.footprint('MySql Connecting Start');
256
+
257
+ var dbc_step = new DBCStep();
258
+ dbc_step.start_time = ctx.getElapsedTime();
259
+ lctx.step = dbc_step;
260
+ },
261
+ function (obj, args, ret, lctx) {
262
+
263
+ if (dbc_hash === 0) {
264
+ var dbc;
265
+ if (args.length > 0) {
266
+ var info = (args[0] || {});
267
+ dbc = 'mysql://';
268
+ dbc += info.user || '';
269
+ dbc += "@";
270
+ dbc += info.host || '';
271
+ dbc += '/';
272
+ dbc += info.database || '';
273
+ dbc_hash = HashUtil.hashFromString(dbc);
274
+ DataTextAgent.DBC.add(dbc_hash, dbc);
275
+ DataTextAgent.METHOD.add(dbc_hash, dbc);
276
+ DataTextAgent.ERROR.add(dbc_hash, dbc);
277
+ }
278
+ }
279
+
280
+ aop.both(ret, 'query', queryHook(dbc_hash, self.agent), function (obj, args, ret, lctx) {
281
+ var ctx = lctx.context;
282
+ TraceContextManager.resume(ctx);
283
+ });
284
+
285
+ aop.both(ret, 'execute', queryHook(dbc_hash, self.agent), function (obj, args, ret, lctx) {
286
+ var ctx = lctx.context;
287
+ TraceContextManager.resume(ctx);
288
+ });
289
+
290
+ aop.after(ret._protocol, '_delegateError', errorDelegate());
291
+
292
+ var ctx = lctx.context,
293
+ step = lctx.step;
294
+
295
+ if (ctx == null || step == null) {
296
+ return;
297
+ }
298
+
299
+ TraceContextManager.resume(ctx);
300
+ ctx.footprint('MySql Connecting Done');
301
+ ctx.db_opening = false;
302
+ step.hash = dbc_hash;
303
+
304
+ aop.both(ret, 'connect', function (obj, args) {
305
+ var ctx = TraceContextManager.getCurrentContext();
306
+ if (ctx == null) {
307
+ return;
308
+ }
309
+
310
+ ctx.footprint('MySql Connecting Start');
311
+
312
+ ctx.db_opening = true;
313
+
314
+ aop.functionHook(args, -1, function (obj, args) {
315
+ if (args[0] && step.error.isZero()) {
316
+ step.error = StatError.addError('mysql-' + args[0].code,
317
+ args[0].message, ctx.service_hash);
318
+ step.elapsed = ctx.getElapsedTime() - step.start_time;
319
+ }
320
+ TraceContextManager.resume(ctx._id);
321
+ });
322
+ ctx.profile.push(step);
323
+ }
324
+ ,
325
+ function (obj, args, ret, lctx) {
326
+ if (lctx.context) {
327
+ ctx.db_opening = false;
328
+ ctx.footprint('MySql Connecting Done');
329
+ }
330
+ }
331
+ );
332
+ });
333
+
334
+
335
+ var dbc_pool_hash = 0;
336
+ aop.after(mod, ['createPool', 'createPoolCluster'], function (obj, args, ret) {
337
+ var dbc = 'mysql://';
338
+ if (dbc_pool_hash == 0) {
339
+ if (args.length > 0) {
340
+ var info = args[0];
341
+ //Open [DatabaseName] connection 메세지 보여줄때 필요함.
342
+ dbc += info.user || '';
343
+ dbc += "@";
344
+ dbc += info.host || '';
345
+ dbc += '/';
346
+ dbc += info.database || '';
347
+ }
348
+
349
+ dbc_pool_hash = HashUtil.hashFromString(dbc);
350
+ DataTextAgent.DBC.add(dbc_pool_hash, dbc);
351
+ DataTextAgent.METHOD.add(dbc_pool_hash, dbc);
352
+ DataTextAgent.ERROR.add(dbc_pool_hash, dbc);
353
+ }
354
+ aop.both(ret, 'getConnection', function (obj, args, lctx) {
355
+ var ctx = TraceContextManager.getCurrentContext();
356
+ if (ctx == null) {
357
+ return;
358
+ }
359
+
360
+ var dbc_step = new DBCStep();
361
+ dbc_step.hash = dbc_pool_hash;
362
+ dbc_step.start_time = ctx.getElapsedTime();
363
+
364
+ aop.functionHook(args, -1, function (obj, args) {
365
+ dbc_step.elapsed = ctx.getElapsedTime() - dbc_step.start_time;
366
+ ctx.profile.push(dbc_step);
367
+
368
+ TraceContextManager.resume(ctx._id);
369
+ DataTextAgent.DBC.add(dbc_hash, dbc);
370
+
371
+ if (args[0] != null) {
372
+ return;
373
+ }
374
+ var conn = args[1];
375
+ if (conn.__query_hook__) {
376
+ return;
377
+ }
378
+ conn.__query_hook__ = true;
379
+ aop.before(conn, 'query', queryHook(dbc_pool_hash, self.agent));
380
+ aop.before(conn, 'execute', queryHook(dbc_pool_hash, self.agent));
381
+ aop.before(conn._protocol, '_delegateError', errorDelegate(ctx));
382
+ });
383
+ }, function (obj, args, ret, lctx) {
384
+ if (obj._allConnections != undefined) {
385
+ var all = obj._allConnections.length;
386
+ var idle = obj._freeConnections.length;
387
+ MeterSql.setConnection((all - idle), idle, dbc);
388
+ }
389
+ });
390
+ });
391
+ };
392
+
393
+ var checkedSql = new IntKeyMap(2000).setMax(2000);
394
+ var nonLiteSql = new IntKeyMap(5000).setMax(5000);
395
+ var date = DateUtil.yyyymmdd();
396
+
397
+ function escapeLiteral(sql) {
398
+ if (sql == null) {
399
+ sql = '';
400
+ }
401
+
402
+ if (date !== DateUtil.yyyymmdd()) {
403
+ checkedSql.clear();
404
+ nonLiteSql.clear();
405
+ date = DateUtil.yyyymmdd();
406
+ Logger.print('WHATAP-SQL-CLEAR', 'MysqlObserver CLEAR OK!!!!!!!!!!!!!!!!', false);
407
+ }
408
+
409
+ var sqlHash = HashUtil.hashFromString(sql);
410
+ var psql = nonLiteSql.get(sqlHash);
411
+
412
+ if (psql != null) {
413
+ return psql;
414
+ }
415
+ psql = checkedSql.get(sqlHash);
416
+
417
+ if (psql != null) {
418
+ return psql;
419
+ }
420
+
421
+ var els = new EscapeLiteralSQL(sql);
422
+ els.process();
423
+
424
+ var hash = HashUtil.hashFromString(els.getParsedSql());
425
+ DataTextAgent.SQL.add(hash, els.getParsedSql());
426
+
427
+ if (hash === sqlHash) {
428
+ psql = new ParsedSql(els.sqlType, hash, null);
429
+ nonLiteSql.put(sqlHash, psql);
430
+ } else {
431
+ psql = new ParsedSql(els.sqlType, hash, els.getParameter());
432
+ checkedSql.put(sqlHash, psql);
433
+ }
434
+ return psql;
435
+ }
436
+
395
437
  exports.MysqlObserver = MysqlObserver;