whatap 0.5.26 → 1.0.0
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.
- package/agent/darwin/arm64/whatap_nodejs +0 -0
- package/agent/linux/amd64/whatap_nodejs +0 -0
- package/agent/linux/arm64/whatap_nodejs +0 -0
- package/build.txt +4 -0
- package/lib/conf/config-default.js +3 -10
- package/lib/conf/configure.js +349 -369
- package/lib/conf/license.js +1 -1
- package/lib/control/packagectr-helper.js +3 -34
- package/lib/core/agent.js +882 -176
- package/lib/core/interceptor.js +6 -6
- package/lib/core/shimmer.js +36 -82
- package/lib/counter/counter-manager.js +8 -79
- package/lib/counter/task/activetransaction.js +17 -68
- package/lib/io/data-inputx.js +3 -13
- package/lib/io/data-outputx.js +206 -268
- package/lib/logger.js +6 -6
- package/lib/net/security-master.js +20 -139
- package/lib/observers/apollo-server-observer.js +27 -33
- package/lib/observers/global-observer.js +80 -155
- package/lib/observers/http-observer.js +236 -666
- package/lib/observers/ioredis-observer.js +294 -0
- package/lib/observers/maria-observer.js +362 -204
- package/lib/observers/mongodb-observer.js +226 -169
- package/lib/observers/mongoose-observer.js +323 -518
- package/lib/observers/mssql-observer.js +418 -177
- package/lib/observers/mysql-observer.js +449 -342
- package/lib/observers/mysql2-observer.js +358 -396
- package/lib/observers/oracle-observer.js +384 -559
- package/lib/observers/pgsql-observer.js +489 -231
- package/lib/observers/prisma-observer.js +92 -303
- package/lib/observers/process-observer.js +35 -79
- package/lib/observers/redis-observer.js +331 -166
- package/lib/observers/socket.io-observer.js +187 -226
- package/lib/observers/websocket-observer.js +301 -175
- package/lib/pack/counter-pack.js +0 -3
- package/lib/pack/log-sink-pack.js +52 -14
- package/lib/pack/tagcount-pack.js +4 -4
- package/lib/{counter/task → system}/gc-action.js +74 -27
- package/lib/trace/trace-context-manager.js +25 -113
- package/lib/trace/trace-context.js +7 -21
- package/lib/trace/trace-httpc.js +11 -17
- package/lib/trace/trace-sql.js +21 -29
- package/lib/udp/async_sender.js +119 -0
- package/lib/udp/index.js +17 -0
- package/lib/udp/packet_enum.js +52 -0
- package/lib/udp/packet_queue.js +69 -0
- package/lib/udp/packet_type_enum.js +33 -0
- package/lib/udp/param_def.js +72 -0
- package/lib/udp/udp_session.js +336 -0
- package/lib/util/escape-literal-sql.js +5 -5
- package/lib/util/hashutil.js +18 -18
- package/lib/util/keygen.js +3 -0
- package/lib/util/linkedset.js +2 -1
- package/lib/util/nodeutil.js +1 -2
- package/lib/util/sql-util.js +178 -0
- package/lib/util/trace-helper.js +91 -0
- package/lib/util/transfer.js +58 -0
- package/lib/value/map-value.js +2 -3
- package/package.json +5 -10
- package/lib/conf/conf-sys-mon.js +0 -101
- package/lib/control/cmd-config.js +0 -24
- package/lib/control/control-handler.js +0 -367
- package/lib/core/request-agent.js +0 -27
- package/lib/counter/meter/meter-activex.js +0 -67
- package/lib/counter/meter/meter-httpc.js +0 -57
- package/lib/counter/meter/meter-resource.js +0 -9
- package/lib/counter/meter/meter-service.js +0 -168
- package/lib/counter/meter/meter-socket.io.js +0 -51
- package/lib/counter/meter/meter-sql.js +0 -71
- package/lib/counter/meter/meter-users.js +0 -58
- package/lib/counter/meter.js +0 -183
- package/lib/counter/task/agentinfo.js +0 -107
- package/lib/counter/task/gcstat.js +0 -34
- package/lib/counter/task/heapmem.js +0 -25
- package/lib/counter/task/httpc.js +0 -76
- package/lib/counter/task/metering-info.js +0 -125
- package/lib/counter/task/proc-cpu.js +0 -29
- package/lib/counter/task/realtimeuser.js +0 -31
- package/lib/counter/task/res/systemECSTask.js +0 -39
- package/lib/counter/task/res/systemKubeTask.js +0 -53
- package/lib/counter/task/res/util/awsEcsClientThread.js +0 -218
- package/lib/counter/task/res/util/linuxProcStatUtil.js +0 -14
- package/lib/counter/task/res-sys-cpu.js +0 -62
- package/lib/counter/task/service.js +0 -202
- package/lib/counter/task/socketio.js +0 -30
- package/lib/counter/task/sql.js +0 -105
- package/lib/counter/task/systemperf.js +0 -43
- package/lib/data/datapack-sender.js +0 -289
- package/lib/data/dataprofile-agent.js +0 -162
- package/lib/data/datatext-agent.js +0 -135
- package/lib/data/event-level.js +0 -15
- package/lib/data/test.js +0 -49
- package/lib/data/zipprofile.js +0 -197
- package/lib/env/constants.js +0 -21
- package/lib/error/error-handler.js +0 -437
- package/lib/kube/kube-client.js +0 -144
- package/lib/lang/text-types.js +0 -58
- package/lib/logsink/line-log-util.js +0 -87
- package/lib/logsink/line-log.js +0 -12
- package/lib/logsink/log-sender.js +0 -78
- package/lib/logsink/log-tracer.js +0 -40
- package/lib/logsink/sender-util.js +0 -56
- package/lib/logsink/zip/zip-send.js +0 -177
- package/lib/net/netflag.js +0 -55
- package/lib/net/receiver.js +0 -66
- package/lib/net/sender.js +0 -141
- package/lib/net/tcp-return.js +0 -18
- package/lib/net/tcp-session.js +0 -286
- package/lib/net/tcpreq-client-proxy.js +0 -70
- package/lib/net/tcprequest-mgr.js +0 -58
- package/lib/observers/cluster-observer.js +0 -22
- package/lib/observers/express-observer.js +0 -215
- package/lib/observers/file-observer.js +0 -184
- package/lib/observers/grpc-observer.js +0 -336
- package/lib/observers/memcached-observer.js +0 -56
- package/lib/observers/mongo-observer.js +0 -317
- package/lib/observers/net-observer.js +0 -77
- package/lib/observers/promise-observer.js +0 -31
- package/lib/observers/schedule-observer.js +0 -67
- package/lib/observers/stream-observer.js +0 -19
- package/lib/observers/thrift-observer.js +0 -197
- package/lib/pack/activestack-pack.js +0 -55
- package/lib/pack/apenum.js +0 -8
- package/lib/pack/errorsnap-pack.js +0 -69
- package/lib/pack/event-pack.js +0 -54
- package/lib/pack/hitmap-pack.js +0 -63
- package/lib/pack/hitmap-pack1.js +0 -152
- package/lib/pack/netstat.js +0 -15
- package/lib/pack/otype.js +0 -7
- package/lib/pack/profile-pack.js +0 -49
- package/lib/pack/realtimeuser-pack.js +0 -41
- package/lib/pack/stat-general-pack.js +0 -96
- package/lib/pack/staterror-pack.js +0 -120
- package/lib/pack/stathttpc-pack.js +0 -66
- package/lib/pack/stathttpc-rec.js +0 -78
- package/lib/pack/statremote-pack.js +0 -46
- package/lib/pack/statservice-pack.js +0 -63
- package/lib/pack/statservice-pack1.js +0 -88
- package/lib/pack/statservice-rec.js +0 -292
- package/lib/pack/statservice-rec_dep.js +0 -151
- package/lib/pack/statsql-pack.js +0 -69
- package/lib/pack/statsql-rec.js +0 -100
- package/lib/pack/statuseragent-pack.js +0 -44
- package/lib/pack/tagctr.js +0 -15
- package/lib/pack/text-pack.js +0 -50
- package/lib/pack/time-count.js +0 -25
- package/lib/pack/websocket.js +0 -15
- package/lib/pack/zip-pack.js +0 -70
- package/lib/pii/pii-item.js +0 -31
- package/lib/pii/pii-mask.js +0 -174
- package/lib/plugin/plugin-loadermanager.js +0 -57
- package/lib/plugin/plugin.js +0 -75
- package/lib/service/tx-record.js +0 -332
- package/lib/stat/stat-error.js +0 -116
- package/lib/stat/stat-httpc.js +0 -98
- package/lib/stat/stat-remote-ip.js +0 -46
- package/lib/stat/stat-remote-ipurl.js +0 -88
- package/lib/stat/stat-sql.js +0 -113
- package/lib/stat/stat-tranx.js +0 -58
- package/lib/stat/stat-tx-caller.js +0 -160
- package/lib/stat/stat-tx-domain.js +0 -111
- package/lib/stat/stat-tx-referer.js +0 -112
- package/lib/stat/stat-useragent.js +0 -48
- package/lib/stat/timingsender.js +0 -76
- package/lib/step/activestack-step.js +0 -38
- package/lib/step/dbc-step.js +0 -36
- package/lib/step/http-stepx.js +0 -67
- package/lib/step/message-step.js +0 -40
- package/lib/step/method-stepx.js +0 -45
- package/lib/step/resultset-step.js +0 -40
- package/lib/step/securemsg-step.js +0 -44
- package/lib/step/socket-step.js +0 -46
- package/lib/step/sql-stepx.js +0 -68
- package/lib/step/sqlxtype.js +0 -16
- package/lib/step/step.js +0 -66
- package/lib/step/stepenum.js +0 -54
- package/lib/topology/link.js +0 -63
- package/lib/topology/nodeinfo.js +0 -123
- package/lib/topology/status-detector.js +0 -111
- package/lib/util/anylist.js +0 -103
- package/lib/util/cardinality/hyperloglog.js +0 -106
- package/lib/util/cardinality/murmurhash.js +0 -31
- package/lib/util/cardinality/registerset.js +0 -75
- package/lib/util/errordata.js +0 -21
- package/lib/util/iputil_x.js +0 -527
- package/lib/util/kube-util.js +0 -73
- package/lib/util/paramsecurity.js +0 -80
- package/lib/util/pre-process.js +0 -13
- package/lib/util/process-seq.js +0 -166
- package/lib/util/property-util.js +0 -36
- package/lib/util/request-queue.js +0 -70
- package/lib/util/requestdouble-queue.js +0 -72
- package/lib/util/resourceprofile.js +0 -157
- package/lib/util/stop-watch.js +0 -30
- package/lib/util/system-util.js +0 -10
- package/lib/util/userid-util.js +0 -57
|
@@ -6,420 +6,394 @@
|
|
|
6
6
|
|
|
7
7
|
var TraceContextManager = require('../trace/trace-context-manager'),
|
|
8
8
|
ParsedSql = require('../trace/parsed-sql'),
|
|
9
|
-
|
|
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'),
|
|
9
|
+
conf = require('../conf/configure'),
|
|
15
10
|
IntKeyMap = require('../util/intkey-map'),
|
|
16
11
|
EscapeLiteralSQL = require('../util/escape-literal-sql'),
|
|
17
12
|
HashUtil = require('../util/hashutil'),
|
|
18
|
-
StatError = require('../stat/stat-error'),
|
|
19
|
-
TextTypes = require('../lang/text-types'),
|
|
20
|
-
ParamSecurity = require('../util/paramsecurity'),
|
|
21
13
|
Logger = require('../logger'),
|
|
22
|
-
conf = require('../conf/configure'),
|
|
23
14
|
DateUtil = require('../util/dateutil'),
|
|
24
|
-
|
|
15
|
+
AsyncSender = require('../udp/async_sender'),
|
|
16
|
+
PacketTypeEnum = require('../udp/packet_type_enum'),
|
|
17
|
+
shimmer = require('../core/shimmer'),
|
|
25
18
|
TraceSQL = require('../trace/trace-sql');
|
|
19
|
+
const { AsyncResource } = require('async_hooks');
|
|
26
20
|
|
|
27
21
|
var MysqlObserver = function (agent) {
|
|
28
22
|
this.agent = agent;
|
|
29
23
|
this.packages = ['mysql'];
|
|
30
24
|
};
|
|
31
25
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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 dbc_step = new DBCStep();
|
|
45
|
-
var dbc_hash = HashUtil.hashFromString(dbc);
|
|
46
|
-
DataTextAgent.DBC.add(dbc_hash, dbc);
|
|
47
|
-
DataTextAgent.METHOD.add(dbc_hash, dbc);
|
|
48
|
-
DataTextAgent.ERROR.add(dbc_hash, dbc)
|
|
49
|
-
|
|
50
|
-
dbc_step.hash = dbc_hash;
|
|
51
|
-
dbc_step.start_time = ctx.getElapsedTime();
|
|
52
|
-
ctx.profile.push(dbc_step);
|
|
53
|
-
|
|
54
|
-
var sql_step = new SqlStepX();
|
|
55
|
-
sql_step.start_time = ctx.getElapsedTime();
|
|
56
|
-
ctx.profile.push(sql_step);
|
|
57
|
-
|
|
58
|
-
ctx.footprint('MySql Query Start');
|
|
59
|
-
|
|
60
|
-
ctx.sql_count++;
|
|
26
|
+
// 전역 dbc 정보
|
|
27
|
+
var dbc_hash = 0;
|
|
28
|
+
var dbc = 'mysql://';
|
|
61
29
|
|
|
62
|
-
|
|
63
|
-
|
|
30
|
+
// 후킹된 객체 추적
|
|
31
|
+
var hookedInstances = new WeakSet();
|
|
64
32
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
33
|
+
// 공통 함수들
|
|
34
|
+
function handleSqlError(ctx, err, sqlHash) {
|
|
35
|
+
if (!err) return;
|
|
68
36
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
37
|
+
try {
|
|
38
|
+
var errorClass = err.code || err.name || err.constructor?.name || 'MySQLError';
|
|
39
|
+
var errorMessage = err.message || err.sqlMessage || 'mysql error';
|
|
40
|
+
var errorStack = '';
|
|
41
|
+
|
|
42
|
+
if (conf.trace_sql_error_stack && conf.trace_sql_error_depth && err.stack) {
|
|
43
|
+
var traceDepth = conf.trace_sql_error_depth;
|
|
44
|
+
var stackLines = err.stack.split("\n");
|
|
45
|
+
if (stackLines.length > traceDepth) {
|
|
46
|
+
stackLines = stackLines.slice(0, traceDepth + 1);
|
|
74
47
|
}
|
|
75
|
-
|
|
76
|
-
sql = '';
|
|
77
|
-
psql = escapeLiteral(sql);
|
|
48
|
+
errorStack = stackLines.join("\n");
|
|
78
49
|
}
|
|
79
50
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
51
|
+
var shouldAddError = false;
|
|
52
|
+
if (conf._is_trace_ignore_err_cls_contains === true && errorClass &&
|
|
53
|
+
errorClass.indexOf(conf.trace_ignore_err_cls_contains) < 0) {
|
|
54
|
+
shouldAddError = true;
|
|
55
|
+
} else if (conf._is_trace_ignore_err_msg_contains === true && errorMessage &&
|
|
56
|
+
errorMessage.indexOf(conf.trace_ignore_err_msg_contains) < 0) {
|
|
57
|
+
shouldAddError = true;
|
|
58
|
+
} else if (conf._is_trace_ignore_err_cls_contains === false &&
|
|
59
|
+
conf._is_trace_ignore_err_msg_contains === false) {
|
|
60
|
+
shouldAddError = true;
|
|
83
61
|
}
|
|
84
|
-
sql_step.dbc = dbc_hash;
|
|
85
|
-
|
|
86
|
-
var els = new EscapeLiteralSQL(sql);
|
|
87
|
-
els.process();
|
|
88
|
-
|
|
89
|
-
ctx.active_sqlhash = sql_step.hash;
|
|
90
|
-
ctx.active_dbc = sql_step.dbc;
|
|
91
|
-
//ctx.active_crud = sql_step.crud;
|
|
92
|
-
|
|
93
|
-
if (conf.profile_sql_param_enabled) {
|
|
94
|
-
var params = args.length > 1 && Array.isArray(args[1]) ? args[1] : undefined;
|
|
95
|
-
sql_step.setTrue(1);
|
|
96
|
-
var crc = {value: 0};
|
|
97
|
-
sql_step.p1 = toParamBytes(psql.param, crc);
|
|
98
|
-
if (params != undefined) {
|
|
99
|
-
const result = params.map((param) => {
|
|
100
|
-
if (typeof param === 'string') {
|
|
101
|
-
return `'${param}'`
|
|
102
|
-
}
|
|
103
|
-
return param
|
|
104
|
-
}).toString()
|
|
105
|
-
sql_step.p2 = toParamBytes(result, crc);
|
|
106
|
-
}
|
|
107
|
-
sql_step.pcrc = crc.value;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
var lastCallback = false;
|
|
111
62
|
|
|
112
|
-
|
|
113
|
-
if
|
|
114
|
-
|
|
63
|
+
if (shouldAddError) {
|
|
64
|
+
if(!ctx.error) ctx.error = 1;
|
|
65
|
+
ctx.status = 500;
|
|
66
|
+
var errors = [errorClass];
|
|
67
|
+
if (errorMessage) {
|
|
68
|
+
errors.push(errorMessage);
|
|
115
69
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if (args[0]) {
|
|
119
|
-
try {
|
|
120
|
-
if (conf.trace_sql_error_stack && conf.trace_sql_error_depth) {
|
|
121
|
-
var traceDepth = conf.trace_sql_error_depth;
|
|
122
|
-
|
|
123
|
-
var errorStack = args[0].stack.split("\n");
|
|
124
|
-
if (errorStack.length > traceDepth) {
|
|
125
|
-
errorStack = errorStack.slice(0, traceDepth + 1);
|
|
126
|
-
}
|
|
127
|
-
ctx.error_message = errorStack.join("\n");
|
|
128
|
-
sql_step.error = ctx.error = StatError.addError('mysql-' + args[0].code, args[0].sqlMessage, ctx.service_hash, TextTypes.SQL, null);
|
|
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
|
-
}
|
|
134
|
-
if (conf._is_trace_ignore_err_cls_contains === true && args[0].code.indexOf(conf.trace_ignore_err_cls_contains) < 0) {
|
|
135
|
-
sql_step.error = StatError.addError('mysql-' + args[0].code, args[0].message || 'mysql error', ctx.service_hash, TextTypes.SQL, sql_step.hash); /*long*/
|
|
136
|
-
if (ctx.error.isZero()) {
|
|
137
|
-
ctx.error = sql_step.error;
|
|
138
|
-
}
|
|
139
|
-
} else if (conf._is_trace_ignore_err_msg_contains === true && args[0].message.indexOf(conf.trace_ignore_err_msg_contains) < 0) {
|
|
140
|
-
sql_step.error = StatError.addError('mysql-' + args[0].code, args[0].message || 'mysql error', ctx.service_hash, TextTypes.SQL, sql_step.hash); /*long*/
|
|
141
|
-
if (ctx.error.isZero()) {
|
|
142
|
-
ctx.error = sql_step.error;
|
|
143
|
-
}
|
|
144
|
-
} else if (conf._is_trace_ignore_err_cls_contains === false && conf._is_trace_ignore_err_msg_contains === false) {
|
|
145
|
-
sql_step.error = StatError.addError('mysql-' + args[0].code, args[0].message || 'mysql error', ctx.service_hash, TextTypes.SQL, sql_step.hash); /*long*/
|
|
146
|
-
if (ctx.error.isZero()) {
|
|
147
|
-
ctx.error = sql_step.error;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
/*
|
|
151
|
-
sql_step.error = StatError.addError(
|
|
152
|
-
('mysql-'+args[0].code ),
|
|
153
|
-
(args[0].message || 'mysql error'),
|
|
154
|
-
ctx.service_hash,
|
|
155
|
-
TextTypes.SQL, sql_step.hash);
|
|
156
|
-
if(ctx.error.isZero()) {
|
|
157
|
-
ctx.error = sql_step.error;
|
|
158
|
-
}
|
|
159
|
-
*/
|
|
160
|
-
} catch (e) {
|
|
161
|
-
|
|
162
|
-
}
|
|
70
|
+
if (errorStack || err.stack) {
|
|
71
|
+
errors.push(errorStack || err.stack);
|
|
163
72
|
}
|
|
164
73
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
// sql_step.start_cpu = ResourceProfile.getCPUTime();
|
|
172
|
-
// sql_step.start_mem = ResourceProfile.getUsedHeapSize();
|
|
173
|
-
// }
|
|
174
|
-
|
|
175
|
-
ctx.footprint('MySql Query Done');
|
|
176
|
-
|
|
177
|
-
MeterSql.add(dbc_hash, sql_step.elapsed, false);
|
|
178
|
-
StatSql.addSqlTime(ctx.service_hash, sql_step.dbc,
|
|
179
|
-
sql_step.hash, sql_step.elapsed, args[0] != null, 0);
|
|
180
|
-
|
|
181
|
-
if (Array.isArray(args[1]) && psql != null && psql.type === 'S') {
|
|
182
|
-
var result_step = new ResultSetStep();
|
|
183
|
-
result_step.start_time = ctx.getElapsedTime();
|
|
184
|
-
result_step.elapsed = 0;
|
|
185
|
-
result_step.fetch = args[1].length;
|
|
186
|
-
result_step.sqlhash = psql.sql;
|
|
187
|
-
result_step.dbc = dbc_hash;
|
|
188
|
-
ctx.profile.push(result_step);
|
|
74
|
+
AsyncSender.send_packet(PacketTypeEnum.TX_ERROR, ctx, errors);
|
|
75
|
+
}
|
|
76
|
+
} catch (e) {
|
|
77
|
+
Logger.printError('WHATAP-232', 'Error handling MySQL error', e, false);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
189
80
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
// ctx.rs_time = ctx.rs_time ? ctx.rs_time + (result_step.start_time - ctx.getElapsedTime()) : result_step.start_time - ctx.getElapsedTime();
|
|
81
|
+
function handleProtocolError(ctx, error) {
|
|
82
|
+
if (!error) return;
|
|
193
83
|
|
|
194
|
-
|
|
195
|
-
|
|
84
|
+
try {
|
|
85
|
+
var errorClass = error.code || error.name || error.constructor?.name || 'MySQLError';
|
|
86
|
+
var errorMessage = error.message || 'mysql error';
|
|
87
|
+
|
|
88
|
+
var shouldAddError = false;
|
|
89
|
+
if (conf._is_trace_ignore_err_cls_contains === true && errorClass.indexOf(conf.trace_ignore_err_cls_contains) < 0) {
|
|
90
|
+
shouldAddError = true;
|
|
91
|
+
} else if (conf._is_trace_ignore_err_msg_contains === true && errorMessage.indexOf(conf.trace_ignore_err_msg_contains) < 0) {
|
|
92
|
+
shouldAddError = true;
|
|
93
|
+
} else if (conf._is_trace_ignore_err_cls_contains === false && conf._is_trace_ignore_err_msg_contains === false) {
|
|
94
|
+
shouldAddError = true;
|
|
95
|
+
}
|
|
196
96
|
|
|
197
|
-
|
|
97
|
+
if (shouldAddError) {
|
|
98
|
+
ctx.error = 1;
|
|
99
|
+
ctx.status = 500;
|
|
100
|
+
var errors = [errorClass];
|
|
101
|
+
if (errorMessage) {
|
|
102
|
+
errors.push(errorMessage);
|
|
198
103
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
sql_step.updated = args[1].affectedRows || 0;
|
|
202
|
-
//StatSql.addUpdate(dbc_hash, psql.sql, sql_step.updated);
|
|
104
|
+
if (error.stack) {
|
|
105
|
+
errors.push(error.stack);
|
|
203
106
|
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
lastCallback = agent.aop.functionHook(args, -1, queryCallback);
|
|
207
107
|
|
|
208
|
-
|
|
209
|
-
agent.aop.both(args[0], '_callback', queryCallback);
|
|
108
|
+
AsyncSender.send_packet(PacketTypeEnum.TX_ERROR, ctx, errors);
|
|
210
109
|
}
|
|
110
|
+
} catch (e) {
|
|
111
|
+
Logger.printError('WHATAP-PROTOCOL-ERROR-HANDLING', 'Error processing protocol error', e, false);
|
|
211
112
|
}
|
|
212
|
-
}
|
|
113
|
+
}
|
|
213
114
|
|
|
214
|
-
|
|
215
|
-
if (
|
|
216
|
-
|
|
115
|
+
function setupDbcInfo(args) {
|
|
116
|
+
if (dbc_hash === 0 && args.length > 0) {
|
|
117
|
+
var info = args[0] || {};
|
|
118
|
+
dbc = 'mysql://';
|
|
119
|
+
dbc += info.user || '';
|
|
120
|
+
dbc += "@";
|
|
121
|
+
dbc += info.host || '';
|
|
122
|
+
dbc += '/';
|
|
123
|
+
dbc += info.database || '';
|
|
124
|
+
dbc_hash = HashUtil.hashFromString(dbc);
|
|
217
125
|
}
|
|
218
|
-
|
|
219
|
-
return ParamSecurity.encrypt(Buffer.from(p, 'utf8'), crc);
|
|
220
|
-
} catch (e) {
|
|
221
|
-
return null;
|
|
222
|
-
}
|
|
223
|
-
};
|
|
126
|
+
}
|
|
224
127
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
128
|
+
function hookConnectionMethods(connection, agent, mysqlModule) {
|
|
129
|
+
if (connection && !hookedInstances.has(connection)) {
|
|
130
|
+
hookedInstances.add(connection);
|
|
131
|
+
Logger.print('WHATAP-MYSQL-CONNECTION', 'Hooking new connection object', false);
|
|
231
132
|
|
|
232
|
-
|
|
233
|
-
if (
|
|
234
|
-
|
|
133
|
+
// query와 execute 메서드 후킹
|
|
134
|
+
if (connection.query && !connection.query.__whatap_wrapped__) {
|
|
135
|
+
shimmer.wrap(connection, 'query', createQueryWrapper(agent, dbc, mysqlModule));
|
|
136
|
+
connection.query.__whatap_wrapped__ = true;
|
|
235
137
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
MeterSql.add(step.dbc, step.elapsed, true);
|
|
240
|
-
StatSql.addSqlTime(ctx, ctx.service_hash, step.dbc, step.hash, step.elapsed, true, 0);
|
|
138
|
+
if (connection.execute && !connection.execute.__whatap_wrapped__) {
|
|
139
|
+
shimmer.wrap(connection, 'execute', createQueryWrapper(agent, dbc, mysqlModule));
|
|
140
|
+
connection.execute.__whatap_wrapped__ = true;
|
|
241
141
|
}
|
|
242
142
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
if (ctx.error.isZero()) {
|
|
263
|
-
ctx.error = step.error;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
143
|
+
// 프로토콜 에러 델리게이트 래핑
|
|
144
|
+
if (connection._protocol && connection._protocol._delegateError &&
|
|
145
|
+
!connection._protocol._delegateError.__whatap_wrapped__) {
|
|
146
|
+
try {
|
|
147
|
+
shimmer.wrap(connection._protocol, '_delegateError', function(original) {
|
|
148
|
+
return function wrappedDelegateError() {
|
|
149
|
+
var args = Array.prototype.slice.call(arguments);
|
|
150
|
+
var ctx = TraceContextManager.getCurrentContext();
|
|
151
|
+
|
|
152
|
+
if (ctx && args[0]) {
|
|
153
|
+
handleSqlError(ctx, args[0], 0);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return original.apply(this, args);
|
|
157
|
+
};
|
|
158
|
+
});
|
|
159
|
+
connection._protocol._delegateError.__whatap_wrapped__ = true;
|
|
160
|
+
} catch (e) {
|
|
161
|
+
Logger.printError('WHATAP-PROTOCOL-HOOK', 'Error hooking _delegateError', e, false);
|
|
266
162
|
}
|
|
267
|
-
} catch (e) {
|
|
268
163
|
}
|
|
269
164
|
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
MysqlObserver.prototype.inject = function (mod, moduleName) {
|
|
273
|
-
if (mod.__whatap_observe__) {
|
|
274
|
-
return;
|
|
275
|
-
}
|
|
276
|
-
mod.__whatap_observe__ = true;
|
|
277
|
-
Logger.initPrint("MysqlObserver");
|
|
278
|
-
var self = this;
|
|
279
|
-
var aop = self.agent.aop;
|
|
165
|
+
}
|
|
280
166
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
167
|
+
// 쿼리 래핑 함수
|
|
168
|
+
var createQueryWrapper = function(agent, dbcUrl, mysqlModule) {
|
|
169
|
+
return function(original) {
|
|
170
|
+
return function wrappedQuery() {
|
|
171
|
+
var args = Array.prototype.slice.call(arguments);
|
|
172
|
+
var ctx = TraceContextManager.getCurrentContext();
|
|
284
173
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
aop.both(mod, 'createConnection',
|
|
288
|
-
function (obj, args, lctx) {
|
|
289
|
-
var ctx = lctx.context;
|
|
290
|
-
if (ctx == null || ctx.db_opening) {
|
|
291
|
-
return;
|
|
174
|
+
if (ctx == null || args[0] == null) {
|
|
175
|
+
return original.apply(this, arguments);
|
|
292
176
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
var dbc_step = new DBCStep();
|
|
297
|
-
dbc_step.start_time = ctx.getElapsedTime();
|
|
298
|
-
lctx.step = dbc_step;
|
|
299
|
-
},
|
|
300
|
-
function (obj, args, ret, lctx) {
|
|
301
|
-
|
|
302
|
-
if (dbc_hash === 0) {
|
|
303
|
-
if (args.length > 0) {
|
|
304
|
-
var info = (args[0] || {});
|
|
305
|
-
dbc = 'mysql://';
|
|
306
|
-
dbc += info.user || '';
|
|
307
|
-
dbc += "@";
|
|
308
|
-
dbc += info.host || '';
|
|
309
|
-
dbc += '/';
|
|
310
|
-
dbc += info.database || '';
|
|
311
|
-
dbc_hash = HashUtil.hashFromString(dbc);
|
|
312
|
-
DataTextAgent.DBC.add(dbc_hash, dbc);
|
|
313
|
-
DataTextAgent.METHOD.add(dbc_hash, dbc);
|
|
314
|
-
DataTextAgent.ERROR.add(dbc_hash, dbc);
|
|
315
|
-
}
|
|
177
|
+
|
|
178
|
+
if (args[0].sql == null && typeof args[0] != 'string') {
|
|
179
|
+
return original.apply(this, arguments);
|
|
316
180
|
}
|
|
317
181
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
});
|
|
182
|
+
// AsyncResource 생성
|
|
183
|
+
const asyncResource = new AsyncResource('mysql-query');
|
|
184
|
+
const callbackResource = new AsyncResource('mysql-callback');
|
|
322
185
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
TraceContextManager.resume(ctx);
|
|
326
|
-
});
|
|
186
|
+
return asyncResource.runInAsyncScope(() => {
|
|
187
|
+
ctx.start_time = Date.now();
|
|
327
188
|
|
|
328
|
-
|
|
189
|
+
// DB 연결 패킷 전송 (elapsed = 0으로 설정)
|
|
190
|
+
ctx.elapsed = 0;
|
|
191
|
+
AsyncSender.send_packet(PacketTypeEnum.TX_DB_CONN, ctx, [dbcUrl]);
|
|
329
192
|
|
|
330
|
-
|
|
331
|
-
|
|
193
|
+
// SQL 시작 시간 기록
|
|
194
|
+
var sql_start_time = Date.now();
|
|
195
|
+
ctx.footprint('MySql Query Start');
|
|
332
196
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
197
|
+
var sql = args.length > 0 ? args[0] : undefined;
|
|
198
|
+
var values = args.length > 1 ? args[1] : undefined;
|
|
199
|
+
var finalSql = '';
|
|
200
|
+
|
|
201
|
+
// mysql.format()을 사용하여 최종 SQL 구성
|
|
202
|
+
try {
|
|
203
|
+
if (typeof sql === 'string') {
|
|
204
|
+
// 일반 문자열 쿼리인 경우
|
|
205
|
+
if (values && typeof mysqlModule.format === 'function') {
|
|
206
|
+
finalSql = mysqlModule.format(sql, values);
|
|
207
|
+
} else {
|
|
208
|
+
finalSql = sql;
|
|
209
|
+
}
|
|
210
|
+
} else if (sql && typeof sql === 'object') {
|
|
211
|
+
// 쿼리 객체인 경우 (prepared statement 등)
|
|
212
|
+
if (sql.sql) {
|
|
213
|
+
if (sql.values && typeof mysqlModule.format === 'function') {
|
|
214
|
+
finalSql = mysqlModule.format(sql.sql, sql.values);
|
|
215
|
+
} else {
|
|
216
|
+
finalSql = sql.sql;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
} catch (formatError) {
|
|
221
|
+
Logger.printError('WHATAP-SQL-FORMAT', 'Error formatting SQL with mysql.format()', formatError, false);
|
|
222
|
+
// 포맷 실패 시 원본 사용
|
|
223
|
+
if (typeof sql === 'string') {
|
|
224
|
+
finalSql = sql;
|
|
225
|
+
} else if (sql && sql.sql) {
|
|
226
|
+
finalSql = sql.sql;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (typeof finalSql !== 'string' || finalSql.length === 0) {
|
|
231
|
+
finalSql = '';
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
var psql = null;
|
|
235
|
+
if (typeof finalSql === 'string' && finalSql.length > 0) {
|
|
236
|
+
try {
|
|
237
|
+
psql = escapeLiteral(finalSql);
|
|
238
|
+
Logger.print('WHATAP-SQL-DEBUG', 'Processing SQL: ' + finalSql.substring(0, 200), false);
|
|
239
|
+
} catch (e) {
|
|
240
|
+
Logger.printError('WHATAP-233', 'MysqlObserver escapeliteral error', e, false);
|
|
241
|
+
}
|
|
242
|
+
} else {
|
|
243
|
+
psql = escapeLiteral(finalSql);
|
|
244
|
+
}
|
|
336
245
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
ctx.db_opening = false;
|
|
340
|
-
step.hash = dbc_hash;
|
|
246
|
+
var sqlHash = psql ? psql.sql : 0;
|
|
247
|
+
ctx.active_sqlhash = true;
|
|
341
248
|
|
|
342
|
-
|
|
249
|
+
// 쿼리 콜백 처리 함수 - AsyncResource로 바인딩
|
|
250
|
+
function queryCallback(err, results) {
|
|
251
|
+
// AsyncResource 스코프 내에서 실행되므로 컨텍스트 유지됨
|
|
343
252
|
var ctx = TraceContextManager.getCurrentContext();
|
|
344
253
|
if (ctx == null) {
|
|
345
254
|
return;
|
|
346
255
|
}
|
|
347
256
|
|
|
348
|
-
ctx.
|
|
257
|
+
TraceContextManager.resume(ctx.id);
|
|
349
258
|
|
|
350
|
-
|
|
259
|
+
var sql_elapsed = Date.now() - sql_start_time;
|
|
260
|
+
var resultCount = 0;
|
|
261
|
+
|
|
262
|
+
// 에러 처리 먼저 수행 (TX_ERROR 패킷 전송)
|
|
263
|
+
if (err) {
|
|
264
|
+
handleSqlError(ctx, err, sqlHash);
|
|
265
|
+
}
|
|
351
266
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
267
|
+
// 결과 개수 계산
|
|
268
|
+
if (!err && results) {
|
|
269
|
+
if (Array.isArray(results)) {
|
|
270
|
+
resultCount = results.length;
|
|
271
|
+
} else if (results.affectedRows !== undefined) {
|
|
272
|
+
resultCount = results.affectedRows;
|
|
273
|
+
} else if (results.changedRows !== undefined) {
|
|
274
|
+
resultCount = results.changedRows;
|
|
357
275
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
try {
|
|
279
|
+
TraceSQL.isSlowSQL(ctx);
|
|
280
|
+
if (!err && results && psql && psql.type === 'S') {
|
|
281
|
+
TraceSQL.isTooManyRecords(resultCount, ctx);
|
|
282
|
+
}
|
|
283
|
+
} catch (e) {
|
|
284
|
+
Logger.printError('WHATAP-TRACESQL', 'Error in TraceSQL processing', e, false);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
ctx.elapsed = sql_elapsed;
|
|
288
|
+
ctx.active_sqlhash = false;
|
|
289
|
+
AsyncSender.send_packet(PacketTypeEnum.TX_SQL, ctx, [dbcUrl, finalSql, String(resultCount)]);
|
|
290
|
+
|
|
291
|
+
ctx.footprint('MySql Query Done');
|
|
361
292
|
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
293
|
+
|
|
294
|
+
var callbackWrapped = false;
|
|
295
|
+
|
|
296
|
+
// 일반 콜백 래핑 - callbackResource로 바인딩
|
|
297
|
+
for (var i = args.length - 1; i >= 0; i--) {
|
|
298
|
+
if (typeof args[i] === 'function') {
|
|
299
|
+
var originalCallback = args[i];
|
|
300
|
+
// AsyncResource로 콜백 바인딩
|
|
301
|
+
args[i] = callbackResource.bind(function() {
|
|
302
|
+
var callbackArgs = Array.prototype.slice.call(arguments);
|
|
303
|
+
try {
|
|
304
|
+
queryCallback(callbackArgs[0], callbackArgs[1]);
|
|
305
|
+
} catch (e) {
|
|
306
|
+
Logger.printError('WHATAP-CALLBACK', 'Error in callback hook', e, false);
|
|
307
|
+
}
|
|
308
|
+
if (originalCallback && typeof originalCallback === 'function') {
|
|
309
|
+
return originalCallback.apply(this, callbackArgs);
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
callbackWrapped = true;
|
|
313
|
+
break;
|
|
367
314
|
}
|
|
368
315
|
}
|
|
369
|
-
);
|
|
370
|
-
});
|
|
371
316
|
|
|
317
|
+
// _callback 래핑 - callbackResource로 바인딩
|
|
318
|
+
if (!callbackWrapped && args.length > 0 && args[0]._callback) {
|
|
319
|
+
try {
|
|
320
|
+
var originalCallback = args[0]._callback;
|
|
321
|
+
args[0]._callback = callbackResource.bind(function() {
|
|
322
|
+
var callbackArgs = Array.prototype.slice.call(arguments);
|
|
323
|
+
try {
|
|
324
|
+
queryCallback(callbackArgs[0], callbackArgs[1]);
|
|
325
|
+
} catch (e) {
|
|
326
|
+
Logger.printError('WHATAP-CALLBACK', 'Error in _callback hook', e, false);
|
|
327
|
+
}
|
|
328
|
+
if (originalCallback && typeof originalCallback === 'function') {
|
|
329
|
+
return originalCallback.apply(this, callbackArgs);
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
callbackWrapped = true;
|
|
333
|
+
} catch (e) {
|
|
334
|
+
Logger.printError('WHATAP-CALLBACK-HOOK', 'Error hooking _callback', e, false);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
372
337
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
dbc += info.database || '';
|
|
384
|
-
}
|
|
338
|
+
try {
|
|
339
|
+
return original.apply(this, args);
|
|
340
|
+
} catch (queryError) {
|
|
341
|
+
queryCallback(queryError, null);
|
|
342
|
+
throw queryError;
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
};
|
|
346
|
+
};
|
|
347
|
+
};
|
|
385
348
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
aop.both(ret, 'getConnection', function (obj, args, lctx) {
|
|
349
|
+
// getConnection 래핑 함수
|
|
350
|
+
var wrapGetConnection = function(agent, mysqlModule) {
|
|
351
|
+
return function(original) {
|
|
352
|
+
return function wrappedGetConnection() {
|
|
353
|
+
var args = Array.prototype.slice.call(arguments);
|
|
392
354
|
var ctx = TraceContextManager.getCurrentContext();
|
|
355
|
+
|
|
393
356
|
if (ctx == null) {
|
|
394
|
-
return;
|
|
357
|
+
return original.apply(this, args);
|
|
395
358
|
}
|
|
396
359
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
var
|
|
405
|
-
|
|
406
|
-
|
|
360
|
+
// AsyncResource로 getConnection 컨텍스트 유지
|
|
361
|
+
const connectionResource = new AsyncResource('mysql-getConnection');
|
|
362
|
+
|
|
363
|
+
return connectionResource.runInAsyncScope(() => {
|
|
364
|
+
ctx.start_time = Date.now();
|
|
365
|
+
|
|
366
|
+
// 콜백 래핑
|
|
367
|
+
for (var i = args.length - 1; i >= 0; i--) {
|
|
368
|
+
if (typeof args[i] === 'function') {
|
|
369
|
+
var originalCallback = args[i];
|
|
370
|
+
// AsyncResource로 콜백 바인딩
|
|
371
|
+
args[i] = connectionResource.bind(function() {
|
|
372
|
+
var callbackArgs = Array.prototype.slice.call(arguments);
|
|
373
|
+
var err = callbackArgs[0];
|
|
374
|
+
var conn = callbackArgs[1];
|
|
375
|
+
|
|
376
|
+
TraceContextManager.resume(ctx.id);
|
|
377
|
+
ctx.elapsed = Date.now() - ctx.start_time;
|
|
378
|
+
|
|
379
|
+
if (!err && conn && !conn.__query_hook__) {
|
|
380
|
+
conn.__query_hook__ = true;
|
|
381
|
+
hookConnectionMethods(conn, agent, mysqlModule);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
return originalCallback.apply(this, callbackArgs);
|
|
385
|
+
});
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
407
388
|
}
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
aop.before(conn, 'execute', queryHook(dbc, self.agent));
|
|
411
|
-
aop.before(conn._protocol, '_delegateError', errorDelegate(ctx));
|
|
389
|
+
|
|
390
|
+
return original.apply(this, args);
|
|
412
391
|
});
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
var all = obj._allConnections.length;
|
|
416
|
-
var idle = obj._freeConnections.length;
|
|
417
|
-
MeterSql.setConnection((all - idle), idle, dbc);
|
|
418
|
-
}
|
|
419
|
-
});
|
|
420
|
-
});
|
|
392
|
+
};
|
|
393
|
+
};
|
|
421
394
|
};
|
|
422
395
|
|
|
396
|
+
// 유틸리티 함수들
|
|
423
397
|
var checkedSql = new IntKeyMap(2000).setMax(2000);
|
|
424
398
|
var nonLiteSql = new IntKeyMap(5000).setMax(5000);
|
|
425
399
|
var date = DateUtil.yyyymmdd();
|
|
@@ -452,8 +426,6 @@ function escapeLiteral(sql) {
|
|
|
452
426
|
els.process();
|
|
453
427
|
|
|
454
428
|
var hash = HashUtil.hashFromString(els.getParsedSql());
|
|
455
|
-
DataTextAgent.SQL.add(hash, els.getParsedSql());
|
|
456
|
-
|
|
457
429
|
if (hash === sqlHash) {
|
|
458
430
|
psql = new ParsedSql(els.sqlType, hash, null);
|
|
459
431
|
nonLiteSql.put(sqlHash, psql);
|
|
@@ -464,4 +436,139 @@ function escapeLiteral(sql) {
|
|
|
464
436
|
return psql;
|
|
465
437
|
}
|
|
466
438
|
|
|
439
|
+
// 메인 inject 함수
|
|
440
|
+
MysqlObserver.prototype.inject = function (mod, moduleName) {
|
|
441
|
+
if (mod.__whatap_observe__) {
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
mod.__whatap_observe__ = true;
|
|
445
|
+
Logger.initPrint("MysqlObserver");
|
|
446
|
+
|
|
447
|
+
if (conf.sql_enabled === false) {
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
var self = this;
|
|
452
|
+
|
|
453
|
+
// createConnection 래핑
|
|
454
|
+
if (mod.createConnection && !mod.createConnection.__whatap_wrapped__) {
|
|
455
|
+
shimmer.wrap(mod, 'createConnection', function(original) {
|
|
456
|
+
return function wrappedCreateConnection() {
|
|
457
|
+
var args = Array.prototype.slice.call(arguments);
|
|
458
|
+
var ctx = TraceContextManager.getCurrentContext();
|
|
459
|
+
|
|
460
|
+
setupDbcInfo(args);
|
|
461
|
+
|
|
462
|
+
if (ctx) {
|
|
463
|
+
ctx.db_opening = true;
|
|
464
|
+
ctx.footprint('MySql Connecting Start');
|
|
465
|
+
ctx.start_time = Date.now();
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
var result = original.apply(this, args);
|
|
469
|
+
|
|
470
|
+
// 연결 객체 후킹
|
|
471
|
+
hookConnectionMethods(result, self.agent, mod);
|
|
472
|
+
|
|
473
|
+
// connect 메서드 래핑
|
|
474
|
+
if (result && result.connect && !result.connect.__whatap_wrapped__) {
|
|
475
|
+
shimmer.wrap(result, 'connect', function(original) {
|
|
476
|
+
return function wrappedConnect() {
|
|
477
|
+
var args = Array.prototype.slice.call(arguments);
|
|
478
|
+
var ctx = TraceContextManager.getCurrentContext();
|
|
479
|
+
|
|
480
|
+
if (ctx) {
|
|
481
|
+
ctx.footprint('MySql Connecting Start');
|
|
482
|
+
ctx.db_opening = true;
|
|
483
|
+
|
|
484
|
+
// 콜백 래핑
|
|
485
|
+
for (var i = args.length - 1; i >= 0; i--) {
|
|
486
|
+
if (typeof args[i] === 'function') {
|
|
487
|
+
var originalCallback = args[i];
|
|
488
|
+
args[i] = function() {
|
|
489
|
+
var callbackArgs = Array.prototype.slice.call(arguments);
|
|
490
|
+
var err = callbackArgs[0];
|
|
491
|
+
|
|
492
|
+
if (err) {
|
|
493
|
+
handleSqlError(ctx, err, 0);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
ctx.db_opening = false;
|
|
497
|
+
ctx.footprint('MySql Connecting Done');
|
|
498
|
+
TraceContextManager.resume(ctx.id);
|
|
499
|
+
|
|
500
|
+
return originalCallback.apply(this, callbackArgs);
|
|
501
|
+
};
|
|
502
|
+
break;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
return original.apply(this, args);
|
|
508
|
+
};
|
|
509
|
+
});
|
|
510
|
+
result.connect.__whatap_wrapped__ = true;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
if (ctx) {
|
|
514
|
+
ctx.elapsed = Date.now() - ctx.start_time;
|
|
515
|
+
ctx.footprint('MySql Connecting Done');
|
|
516
|
+
ctx.db_opening = false;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
return result;
|
|
520
|
+
};
|
|
521
|
+
});
|
|
522
|
+
mod.createConnection.__whatap_wrapped__ = true;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// createPool 래핑
|
|
526
|
+
if (mod.createPool && !mod.createPool.__whatap_wrapped__) {
|
|
527
|
+
shimmer.wrap(mod, 'createPool', function(original) {
|
|
528
|
+
return function wrappedCreatePool() {
|
|
529
|
+
var args = Array.prototype.slice.call(arguments);
|
|
530
|
+
setupDbcInfo(args);
|
|
531
|
+
|
|
532
|
+
var pool = original.apply(this, args);
|
|
533
|
+
|
|
534
|
+
if (pool && !hookedInstances.has(pool)) {
|
|
535
|
+
hookedInstances.add(pool);
|
|
536
|
+
|
|
537
|
+
if (pool.getConnection && !pool.getConnection.__whatap_wrapped__) {
|
|
538
|
+
shimmer.wrap(pool, 'getConnection', wrapGetConnection(self.agent, mod));
|
|
539
|
+
pool.getConnection.__whatap_wrapped__ = true;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
return pool;
|
|
544
|
+
};
|
|
545
|
+
});
|
|
546
|
+
mod.createPool.__whatap_wrapped__ = true;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// createPoolCluster 래핑
|
|
550
|
+
if (mod.createPoolCluster && !mod.createPoolCluster.__whatap_wrapped__) {
|
|
551
|
+
shimmer.wrap(mod, 'createPoolCluster', function(original) {
|
|
552
|
+
return function wrappedCreatePoolCluster() {
|
|
553
|
+
var args = Array.prototype.slice.call(arguments);
|
|
554
|
+
setupDbcInfo(args);
|
|
555
|
+
|
|
556
|
+
var poolCluster = original.apply(this, args);
|
|
557
|
+
|
|
558
|
+
if (poolCluster && !hookedInstances.has(poolCluster)) {
|
|
559
|
+
hookedInstances.add(poolCluster);
|
|
560
|
+
|
|
561
|
+
if (poolCluster.getConnection && !poolCluster.getConnection.__whatap_wrapped__) {
|
|
562
|
+
shimmer.wrap(poolCluster, 'getConnection', wrapGetConnection(self.agent, mod));
|
|
563
|
+
poolCluster.getConnection.__whatap_wrapped__ = true;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
return poolCluster;
|
|
568
|
+
};
|
|
569
|
+
});
|
|
570
|
+
mod.createPoolCluster.__whatap_wrapped__ = true;
|
|
571
|
+
}
|
|
572
|
+
};
|
|
573
|
+
|
|
467
574
|
exports.MysqlObserver = MysqlObserver;
|