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
|
@@ -5,211 +5,110 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
var TraceContextManager = require('../trace/trace-context-manager'),
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
Long = require('long'),
|
|
21
|
-
conf = require('../conf/configure'),
|
|
22
|
-
Logger = require('../logger'),
|
|
23
|
-
TraceSQL = require('../trace/trace-sql')
|
|
24
|
-
const DateUtil = require('../util/dateutil');
|
|
25
|
-
const MessageStep = require("../step/message-step");
|
|
26
|
-
// const ResourceProfile = require("../util/resourceprofile");
|
|
8
|
+
ParsedSql = require('../trace/parsed-sql'),
|
|
9
|
+
conf = require('../conf/configure'),
|
|
10
|
+
IntKeyMap = require('../util/intkey-map'),
|
|
11
|
+
EscapeLiteralSQL = require('../util/escape-literal-sql'),
|
|
12
|
+
HashUtil = require('../util/hashutil'),
|
|
13
|
+
Logger = require('../logger'),
|
|
14
|
+
DateUtil = require('../util/dateutil'),
|
|
15
|
+
AsyncSender = require('../udp/async_sender'),
|
|
16
|
+
PacketTypeEnum = require('../udp/packet_type_enum'),
|
|
17
|
+
shimmer = require('../core/shimmer'),
|
|
18
|
+
TraceSQL = require('../trace/trace-sql'),
|
|
19
|
+
AsyncResource = require('async_hooks').AsyncResource;
|
|
27
20
|
|
|
28
21
|
var MssqlObserver = function (agent) {
|
|
29
22
|
this.agent = agent;
|
|
30
|
-
this.aop = agent.aop;
|
|
31
23
|
this.packages = ['mssql'];
|
|
32
24
|
};
|
|
33
|
-
var dbc_hash=0;
|
|
34
|
-
MssqlObserver.prototype.inject = function (mod, modName) {
|
|
35
25
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
Logger.initPrint("MssqlObserver");
|
|
40
|
-
|
|
41
|
-
var self = this;
|
|
42
|
-
|
|
43
|
-
var requestCommand = ['_bulk', '_query', '_execute'];
|
|
44
|
-
|
|
45
|
-
requestCommand.forEach(function (command) {
|
|
46
|
-
self.aop.both(mod.Request.prototype, command,
|
|
47
|
-
function (obj, args) {
|
|
48
|
-
|
|
49
|
-
var ctx = TraceContextManager.getCurrentContext();
|
|
50
|
-
if(ctx == null) { return; }
|
|
51
|
-
|
|
52
|
-
var sql_step = new SqlStepX();
|
|
53
|
-
var sql = (typeof args[0] === 'string') ? args[0] : JSON.stringify(args[0]),
|
|
54
|
-
psql = null;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if(dbc_hash===0){
|
|
58
|
-
if(obj.parent && obj.parent.config) {
|
|
59
|
-
var config = obj.parent.config,
|
|
60
|
-
dbc = 'mssql://';
|
|
61
|
-
try {
|
|
62
|
-
dbc += (config.server || '');
|
|
63
|
-
dbc += ':';
|
|
64
|
-
dbc += (config.port || '');
|
|
65
|
-
dbc += '/';
|
|
66
|
-
dbc += (config.database || '');
|
|
67
|
-
dbc_hash = HashUtil.hashFromString(dbc);
|
|
68
|
-
DataTextAgent.DBC.add(dbc_hash, dbc);
|
|
69
|
-
DataTextAgent.METHOD.add(dbc_hash, dbc);
|
|
70
|
-
DataTextAgent.ERROR.add(dbc_hash, dbc)
|
|
71
|
-
} catch(e) {
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
var dbc_step = new DBCStep();
|
|
76
|
-
dbc_step.hash = dbc_hash;
|
|
77
|
-
dbc_step.start_time = ctx.getElapsedTime();
|
|
78
|
-
ctx.profile.push(dbc_step);
|
|
26
|
+
var dbc_hash = 0;
|
|
27
|
+
var dbc = 'mssql://';
|
|
79
28
|
|
|
80
|
-
|
|
29
|
+
var hookedInstances = new WeakSet();
|
|
81
30
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
Logger.printError("WHATAP-192", "MssqlObserver escapeliteral error", e);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if(psql != null) {
|
|
89
|
-
DataTextAgent.SQL.add(sql_step.hash, sql);
|
|
90
|
-
// = psql.type.charCodeAt(0);
|
|
91
|
-
sql_step.hash = psql.sql;
|
|
92
|
-
}
|
|
93
|
-
sql_step.start_time = ctx.getElapsedTime();
|
|
94
|
-
ctx.profile.push(sql_step);
|
|
95
|
-
self.aop.functionHook(args, -1, function (obj, args) {
|
|
96
|
-
TraceContextManager.resume(ctx);
|
|
97
|
-
if(args[0] != null) {
|
|
98
|
-
ctx.error_message = args[0].message;
|
|
99
|
-
ctx.error_class = args[0].name || args[0].constructor?.name || 'MSSQLError';
|
|
100
|
-
if (conf.trace_sql_error_stack && conf.trace_sql_error_depth) {
|
|
101
|
-
var traceDepth = conf.trace_sql_error_depth;
|
|
102
|
-
|
|
103
|
-
var errorStack = args[0].stack.split("\n");
|
|
104
|
-
if (errorStack.length > traceDepth) {
|
|
105
|
-
errorStack = errorStack.slice(0, traceDepth + 1);
|
|
106
|
-
}
|
|
107
|
-
ctx.error_message = errorStack.join("\n");
|
|
108
|
-
sql_step.error = ctx.error = StatError.addError('mssql-' + args[0].code, args[0].message, ctx.service_hash, TextTypes.SQL, null);
|
|
109
|
-
}
|
|
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( 'mssql-'+args[0].code, args[0].message|| 'mssql error', ctx.service_hash, TextTypes.SQL, sql_step.hash); /*long*/
|
|
112
|
-
if (ctx.error.isZero()) { ctx.error = sql_step.error; }
|
|
113
|
-
} else if(conf._is_trace_ignore_err_msg_contains === true && args[0].message.indexOf(conf.trace_ignore_err_msg_contains) < 0){
|
|
114
|
-
sql_step.error = StatError.addError( 'mssql-'+args[0].code, args[0].message|| 'mssql error', ctx.service_hash, TextTypes.SQL, sql_step.hash); /*long*/
|
|
115
|
-
if (ctx.error.isZero()) { ctx.error = sql_step.error; }
|
|
116
|
-
} else if(conf._is_trace_ignore_err_cls_contains === false && conf._is_trace_ignore_err_msg_contains === false) {
|
|
117
|
-
sql_step.error = StatError.addError( 'mssql-'+args[0].code, args[0].message|| 'mssql error', ctx.service_hash, TextTypes.SQL, sql_step.hash); /*long*/
|
|
118
|
-
if (ctx.error.isZero()) { ctx.error = sql_step.error; }
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
|
|
123
|
-
TraceSQL.isSlowSQL(ctx);
|
|
124
|
-
|
|
125
|
-
MeterSql.add(dbc_hash, sql_step.elapsed, args[0] != null);
|
|
126
|
-
StatSql.addSqlTime(ctx.service_hash, sql_step.dbc,
|
|
127
|
-
sql_step.hash, sql_step.elapsed, args[0] != null, 0);
|
|
128
|
-
|
|
129
|
-
if(psql && psql.type == 'S') {
|
|
130
|
-
var result_step = new ResultSetStep();
|
|
131
|
-
result_step.dbc = sql_step.dbc;
|
|
132
|
-
result_step.sqlhash = sql_step.hash;
|
|
133
|
-
try {
|
|
134
|
-
result_step.fetch = args[1][0].length;
|
|
135
|
-
ctx.rs_count = ctx.rs_count ? ctx.rs_count + args[1][0].length : args[1][0].length;
|
|
136
|
-
} catch(e) {
|
|
137
|
-
}
|
|
138
|
-
ctx.profile.push(result_step);
|
|
31
|
+
var checkedSql = new IntKeyMap(2000).setMax(2000);
|
|
32
|
+
var nonLiteSql = new IntKeyMap(5000).setMax(5000);
|
|
33
|
+
var date = DateUtil.yyyymmdd();
|
|
139
34
|
|
|
140
|
-
|
|
141
|
-
|
|
35
|
+
function handleSqlError(ctx, err) {
|
|
36
|
+
if (!err) return;
|
|
142
37
|
|
|
143
|
-
|
|
144
|
-
|
|
38
|
+
try {
|
|
39
|
+
var errorClass = err.code || err.name || err.constructor?.name || 'MSSQLError';
|
|
40
|
+
var errorMessage = err.message || 'mssql error';
|
|
41
|
+
var errorStack = '';
|
|
145
42
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
var conn_dbc_hash=0;
|
|
152
|
-
self.aop.both(mod, 'connect',
|
|
153
|
-
function (obj, args, lctx) {
|
|
154
|
-
|
|
155
|
-
var ctx = TraceContextManager.getCurrentContext();
|
|
156
|
-
if(ctx == null) { return; }
|
|
157
|
-
lctx.context = ctx;
|
|
158
|
-
|
|
159
|
-
var conn = '';
|
|
160
|
-
if(args[0]) { //좀더 로직 개선 필요...
|
|
161
|
-
conn += args[0]['server'] || '';
|
|
162
|
-
conn += args[0]['database'] || '';
|
|
43
|
+
if (conf.trace_sql_error_stack && conf.trace_sql_error_depth && err.stack) {
|
|
44
|
+
var traceDepth = conf.trace_sql_error_depth;
|
|
45
|
+
var stackLines = err.stack.split("\n");
|
|
46
|
+
if (stackLines.length > traceDepth) {
|
|
47
|
+
stackLines = stackLines.slice(0, traceDepth + 1);
|
|
163
48
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
49
|
+
errorStack = stackLines.join("\n");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
var shouldAddError = false;
|
|
53
|
+
if (conf._is_trace_ignore_err_cls_contains === true && errorClass &&
|
|
54
|
+
errorClass.indexOf(conf.trace_ignore_err_cls_contains) < 0) {
|
|
55
|
+
shouldAddError = true;
|
|
56
|
+
} else if (conf._is_trace_ignore_err_msg_contains === true && errorMessage &&
|
|
57
|
+
errorMessage.indexOf(conf.trace_ignore_err_msg_contains) < 0) {
|
|
58
|
+
shouldAddError = true;
|
|
59
|
+
} else if (conf._is_trace_ignore_err_cls_contains === false &&
|
|
60
|
+
conf._is_trace_ignore_err_msg_contains === false) {
|
|
61
|
+
shouldAddError = true;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (shouldAddError) {
|
|
65
|
+
if (!ctx.error) ctx.error = 1;
|
|
66
|
+
ctx.status = 500;
|
|
67
|
+
var errors = [errorClass];
|
|
68
|
+
if (errorMessage) {
|
|
69
|
+
errors.push(errorMessage);
|
|
70
|
+
}
|
|
71
|
+
if (errorStack || err.stack) {
|
|
72
|
+
errors.push(errorStack || err.stack);
|
|
171
73
|
}
|
|
172
74
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
function (obj, args, ret, lctx) {
|
|
180
|
-
var pool = ret;
|
|
181
|
-
var ctx = lctx.context,
|
|
182
|
-
step = lctx.step;
|
|
183
|
-
|
|
184
|
-
if(ctx == null || step == null) { return; }
|
|
185
|
-
step.elapsed = ctx.getElapsedTime() - step.start_time;
|
|
186
|
-
ctx.profile.push(step);
|
|
187
|
-
});
|
|
188
|
-
};
|
|
75
|
+
AsyncSender.send_packet(PacketTypeEnum.TX_ERROR, ctx, errors);
|
|
76
|
+
}
|
|
77
|
+
} catch (e) {
|
|
78
|
+
Logger.printError('WHATAP-209', 'Error handling MSSQL error', e, false);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
189
81
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
82
|
+
function setupDbcInfo(config) {
|
|
83
|
+
if (dbc_hash === 0 && config) {
|
|
84
|
+
dbc = 'mssql://';
|
|
85
|
+
dbc += (config.server || '') + ':';
|
|
86
|
+
dbc += (config.port || '') + '/';
|
|
87
|
+
dbc += config.database || '';
|
|
88
|
+
dbc_hash = HashUtil.hashFromString(dbc);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
193
91
|
|
|
194
92
|
function escapeLiteral(sql) {
|
|
195
|
-
if(sql == null) {
|
|
93
|
+
if (sql == null) {
|
|
94
|
+
sql = '';
|
|
95
|
+
}
|
|
196
96
|
|
|
197
|
-
if(date !== DateUtil.yyyymmdd()) {
|
|
97
|
+
if (date !== DateUtil.yyyymmdd()) {
|
|
198
98
|
checkedSql.clear();
|
|
199
99
|
nonLiteSql.clear();
|
|
200
100
|
date = DateUtil.yyyymmdd();
|
|
201
|
-
Logger.print('WHATAP-SQL-CLEAR', 'MssqlObserver CLEAR OK!!!!!!!!!!!!!!!!', false);
|
|
202
101
|
}
|
|
203
102
|
|
|
204
103
|
var sqlHash = HashUtil.hashFromString(sql);
|
|
205
104
|
var psql = nonLiteSql.get(sqlHash);
|
|
206
105
|
|
|
207
|
-
if(psql != null) {
|
|
106
|
+
if (psql != null) {
|
|
208
107
|
return psql;
|
|
209
108
|
}
|
|
210
109
|
psql = checkedSql.get(sqlHash);
|
|
211
110
|
|
|
212
|
-
if(psql != null) {
|
|
111
|
+
if (psql != null) {
|
|
213
112
|
return psql;
|
|
214
113
|
}
|
|
215
114
|
|
|
@@ -217,9 +116,8 @@ function escapeLiteral(sql) {
|
|
|
217
116
|
els.process();
|
|
218
117
|
|
|
219
118
|
var hash = HashUtil.hashFromString(els.getParsedSql());
|
|
220
|
-
DataTextAgent.SQL.add(hash, els.getParsedSql());
|
|
221
119
|
|
|
222
|
-
if(hash === sqlHash) {
|
|
120
|
+
if (hash === sqlHash) {
|
|
223
121
|
psql = new ParsedSql(els.sqlType, hash, null);
|
|
224
122
|
nonLiteSql.put(sqlHash, psql);
|
|
225
123
|
} else {
|
|
@@ -229,4 +127,347 @@ function escapeLiteral(sql) {
|
|
|
229
127
|
return psql;
|
|
230
128
|
}
|
|
231
129
|
|
|
130
|
+
function createRequestWrapper(agent, dbcUrl, command) {
|
|
131
|
+
return function(original) {
|
|
132
|
+
return function wrappedRequest() {
|
|
133
|
+
var args = Array.prototype.slice.call(arguments);
|
|
134
|
+
var ctx = TraceContextManager.getCurrentContext();
|
|
135
|
+
|
|
136
|
+
if (ctx == null || args[0] == null) {
|
|
137
|
+
return original.apply(this, arguments);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (dbcUrl === 'mssql://' || !dbc_hash) {
|
|
141
|
+
return original.apply(this, arguments);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const asyncResource = new AsyncResource('mssql-request');
|
|
145
|
+
const callbackResource = new AsyncResource('mssql-callback');
|
|
146
|
+
|
|
147
|
+
return asyncResource.runInAsyncScope(() => {
|
|
148
|
+
ctx.start_time = Date.now();
|
|
149
|
+
ctx.elapsed = 0;
|
|
150
|
+
AsyncSender.send_packet(PacketTypeEnum.TX_DB_CONN, ctx, [dbcUrl]);
|
|
151
|
+
|
|
152
|
+
var sql_start_time = Date.now();
|
|
153
|
+
ctx.footprint('MsSQL ' + command + ' Start');
|
|
154
|
+
ctx.sql_count++;
|
|
155
|
+
|
|
156
|
+
var sql = args.length > 0 ? args[0] : undefined;
|
|
157
|
+
var finalSql = '';
|
|
158
|
+
|
|
159
|
+
try {
|
|
160
|
+
if (typeof sql === 'string') {
|
|
161
|
+
finalSql = sql;
|
|
162
|
+
} else if (sql !== null && typeof sql === 'object') {
|
|
163
|
+
finalSql = JSON.stringify(sql);
|
|
164
|
+
}
|
|
165
|
+
} catch (formatError) {
|
|
166
|
+
Logger.printError('WHATAP-210', 'Error formatting MSSQL query', formatError, false);
|
|
167
|
+
finalSql = '';
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (typeof finalSql !== 'string' || finalSql.length === 0) {
|
|
171
|
+
finalSql = '';
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
var psql = null;
|
|
175
|
+
if (typeof finalSql === 'string' && finalSql.length > 0) {
|
|
176
|
+
try {
|
|
177
|
+
psql = escapeLiteral(finalSql);
|
|
178
|
+
Logger.print('WHATAP-203', 'Processing SQL: ' + finalSql.substring(0, 200), false);
|
|
179
|
+
} catch (e) {
|
|
180
|
+
Logger.printError('WHATAP-211', 'MssqlObserver escapeliteral error', e, false);
|
|
181
|
+
}
|
|
182
|
+
} else {
|
|
183
|
+
psql = escapeLiteral(finalSql);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
ctx.active_sqlhash = true;
|
|
187
|
+
ctx.active_dbc = dbc_hash;
|
|
188
|
+
|
|
189
|
+
function requestCallback(err, results) {
|
|
190
|
+
var currentCtx = TraceContextManager.getCurrentContext();
|
|
191
|
+
if (currentCtx == null) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
TraceContextManager.resume(currentCtx.id);
|
|
196
|
+
|
|
197
|
+
var sql_elapsed = Date.now() - sql_start_time;
|
|
198
|
+
var resultCount = 0;
|
|
199
|
+
|
|
200
|
+
if (err) {
|
|
201
|
+
handleSqlError(currentCtx, err);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (!err && results) {
|
|
205
|
+
if (Array.isArray(results) && results.length > 0) {
|
|
206
|
+
if (results[0] && Array.isArray(results[0])) {
|
|
207
|
+
resultCount = results[0].length;
|
|
208
|
+
} else if (results[0] && results[0].recordset && Array.isArray(results[0].recordset)) {
|
|
209
|
+
resultCount = results[0].recordset.length;
|
|
210
|
+
}
|
|
211
|
+
} else if (results.recordset && Array.isArray(results.recordset)) {
|
|
212
|
+
resultCount = results.recordset.length;
|
|
213
|
+
} else if (results.rowsAffected && Array.isArray(results.rowsAffected)) {
|
|
214
|
+
resultCount = results.rowsAffected.reduce((sum, count) => sum + count, 0);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
try {
|
|
219
|
+
TraceSQL.isSlowSQL(currentCtx);
|
|
220
|
+
if (!err && psql != null && psql.type === 'S') {
|
|
221
|
+
TraceSQL.isTooManyRecords(resultCount, currentCtx);
|
|
222
|
+
}
|
|
223
|
+
} catch (e) {
|
|
224
|
+
Logger.printError('WHATAP-212', 'Error in TraceSQL processing', e, false);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
currentCtx.elapsed = sql_elapsed;
|
|
228
|
+
currentCtx.active_sqlhash = false;
|
|
229
|
+
AsyncSender.send_packet(PacketTypeEnum.TX_SQL, currentCtx, [dbcUrl, finalSql, String(resultCount)]);
|
|
230
|
+
|
|
231
|
+
currentCtx.footprint('MsSQL ' + command + ' Done');
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
var callbackWrapped = false;
|
|
235
|
+
var hasCallback = false;
|
|
236
|
+
|
|
237
|
+
// 콜백 찾기 및 래핑
|
|
238
|
+
for (var i = args.length - 1; i >= 0; i--) {
|
|
239
|
+
if (typeof args[i] === 'function') {
|
|
240
|
+
hasCallback = true;
|
|
241
|
+
var originalCallback = args[i];
|
|
242
|
+
args[i] = callbackResource.bind(function() {
|
|
243
|
+
var callbackArgs = Array.prototype.slice.call(arguments);
|
|
244
|
+
try {
|
|
245
|
+
requestCallback(callbackArgs[0], callbackArgs[1]);
|
|
246
|
+
} catch (e) {
|
|
247
|
+
Logger.printError('WHATAP-213', 'Error in callback hook', e, false);
|
|
248
|
+
}
|
|
249
|
+
if (originalCallback && typeof originalCallback === 'function') {
|
|
250
|
+
return originalCallback.apply(this, callbackArgs);
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
callbackWrapped = true;
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
try {
|
|
259
|
+
const result = original.apply(this, args);
|
|
260
|
+
|
|
261
|
+
// Promise 기반 처리
|
|
262
|
+
if (!hasCallback && result && typeof result.then === 'function') {
|
|
263
|
+
return result.then(function(res) {
|
|
264
|
+
requestCallback(null, res);
|
|
265
|
+
return res;
|
|
266
|
+
}).catch(function(err) {
|
|
267
|
+
requestCallback(err, null);
|
|
268
|
+
throw err;
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return result;
|
|
273
|
+
} catch (requestError) {
|
|
274
|
+
requestCallback(requestError, null);
|
|
275
|
+
throw requestError;
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
};
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
MssqlObserver.prototype.inject = function (mod, moduleName) {
|
|
283
|
+
if (mod.__whatap_observe__) {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
mod.__whatap_observe__ = true;
|
|
287
|
+
Logger.initPrint("MssqlObserver");
|
|
288
|
+
|
|
289
|
+
if (conf.sql_enabled === false) {
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
var self = this;
|
|
294
|
+
|
|
295
|
+
// Request 클래스의 메서드들 후킹
|
|
296
|
+
if (mod.Request && mod.Request.prototype) {
|
|
297
|
+
var requestCommands = ['_bulk', '_query', '_execute'];
|
|
298
|
+
|
|
299
|
+
requestCommands.forEach(function(command) {
|
|
300
|
+
if (mod.Request.prototype[command] && !mod.Request.prototype[command].__whatap_wrapped__) {
|
|
301
|
+
shimmer.wrap(mod.Request.prototype, command, function(original) {
|
|
302
|
+
return function wrappedRequestCommand() {
|
|
303
|
+
var args = Array.prototype.slice.call(arguments);
|
|
304
|
+
var ctx = TraceContextManager.getCurrentContext();
|
|
305
|
+
|
|
306
|
+
if (ctx == null) {
|
|
307
|
+
return original.apply(this, arguments);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// DBC 정보 설정
|
|
311
|
+
if (dbc_hash === 0 && this.parent && this.parent.config) {
|
|
312
|
+
setupDbcInfo(this.parent.config);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return createRequestWrapper(self.agent, dbc, command)(original).apply(this, args);
|
|
316
|
+
};
|
|
317
|
+
});
|
|
318
|
+
mod.Request.prototype[command].__whatap_wrapped__ = true;
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// connect 함수 후킹
|
|
324
|
+
if (mod.connect && !mod.connect.__whatap_wrapped__) {
|
|
325
|
+
shimmer.wrap(mod, 'connect', function(original) {
|
|
326
|
+
return function wrappedConnect() {
|
|
327
|
+
var args = Array.prototype.slice.call(arguments);
|
|
328
|
+
var ctx = TraceContextManager.getCurrentContext();
|
|
329
|
+
|
|
330
|
+
if (ctx == null) {
|
|
331
|
+
return original.apply(this, arguments);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// 연결 정보 설정
|
|
335
|
+
if (args[0]) {
|
|
336
|
+
setupDbcInfo(args[0]);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
const connectionResource = new AsyncResource('mssql-connect');
|
|
340
|
+
|
|
341
|
+
return connectionResource.runInAsyncScope(() => {
|
|
342
|
+
ctx.start_time = Date.now();
|
|
343
|
+
ctx.db_opening = true;
|
|
344
|
+
ctx.footprint('MsSQL Connecting Start');
|
|
345
|
+
|
|
346
|
+
// 콜백 래핑
|
|
347
|
+
for (var i = args.length - 1; i >= 0; i--) {
|
|
348
|
+
if (typeof args[i] === 'function') {
|
|
349
|
+
var originalCallback = args[i];
|
|
350
|
+
args[i] = connectionResource.bind(function() {
|
|
351
|
+
var callbackArgs = Array.prototype.slice.call(arguments);
|
|
352
|
+
var err = callbackArgs[0];
|
|
353
|
+
|
|
354
|
+
if (ctx) {
|
|
355
|
+
TraceContextManager.resume(ctx.id);
|
|
356
|
+
ctx.elapsed = Date.now() - ctx.start_time;
|
|
357
|
+
|
|
358
|
+
if (err) {
|
|
359
|
+
handleSqlError(ctx, err);
|
|
360
|
+
ctx.footprint('MsSQL Connecting Error');
|
|
361
|
+
} else {
|
|
362
|
+
ctx.footprint('MsSQL Connecting Done');
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
return originalCallback.apply(this, callbackArgs);
|
|
367
|
+
});
|
|
368
|
+
break;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
var result = original.apply(this, args);
|
|
373
|
+
|
|
374
|
+
// Promise 기반 처리
|
|
375
|
+
if (result && typeof result.then === 'function') {
|
|
376
|
+
return result.then(connectionResource.bind(function(pool) {
|
|
377
|
+
if (ctx) {
|
|
378
|
+
TraceContextManager.resume(ctx.id);
|
|
379
|
+
ctx.elapsed = Date.now() - ctx.start_time;
|
|
380
|
+
ctx.db_opening = false;
|
|
381
|
+
ctx.footprint('MsSQL Connecting Done');
|
|
382
|
+
}
|
|
383
|
+
return pool;
|
|
384
|
+
})).catch(connectionResource.bind(function(err) {
|
|
385
|
+
if (ctx) {
|
|
386
|
+
TraceContextManager.resume(ctx.id);
|
|
387
|
+
ctx.elapsed = Date.now() - ctx.start_time;
|
|
388
|
+
ctx.db_opening = false;
|
|
389
|
+
ctx.footprint('MsSQL Connecting Error');
|
|
390
|
+
handleSqlError(ctx, err);
|
|
391
|
+
}
|
|
392
|
+
throw err;
|
|
393
|
+
}));
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return result;
|
|
397
|
+
});
|
|
398
|
+
};
|
|
399
|
+
});
|
|
400
|
+
mod.connect.__whatap_wrapped__ = true;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// ConnectionPool 클래스 후킹 (있는 경우)
|
|
404
|
+
if (mod.ConnectionPool && !mod.ConnectionPool.__whatap_wrapped__) {
|
|
405
|
+
shimmer.wrap(mod, 'ConnectionPool', function(original) {
|
|
406
|
+
return function wrappedConnectionPool() {
|
|
407
|
+
var args = Array.prototype.slice.call(arguments);
|
|
408
|
+
|
|
409
|
+
// 연결 정보 설정
|
|
410
|
+
if (args[0]) {
|
|
411
|
+
setupDbcInfo(args[0]);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
var pool = new (Function.prototype.bind.apply(original, [null].concat(args)));
|
|
415
|
+
|
|
416
|
+
if (pool && !hookedInstances.has(pool)) {
|
|
417
|
+
hookedInstances.add(pool);
|
|
418
|
+
|
|
419
|
+
// connect 메서드 후킹
|
|
420
|
+
if (pool.connect && !pool.connect.__whatap_wrapped__) {
|
|
421
|
+
shimmer.wrap(pool, 'connect', function(original) {
|
|
422
|
+
return function wrappedPoolConnect() {
|
|
423
|
+
var args = Array.prototype.slice.call(arguments);
|
|
424
|
+
var ctx = TraceContextManager.getCurrentContext();
|
|
425
|
+
|
|
426
|
+
if (ctx == null) {
|
|
427
|
+
return original.apply(this, arguments);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
const connectionResource = new AsyncResource('mssql-pool-connect');
|
|
431
|
+
|
|
432
|
+
return connectionResource.runInAsyncScope(() => {
|
|
433
|
+
ctx.start_time = Date.now();
|
|
434
|
+
ctx.footprint('MsSQL Pool Connecting Start');
|
|
435
|
+
|
|
436
|
+
var result = original.apply(this, args);
|
|
437
|
+
|
|
438
|
+
// Promise 기반 처리
|
|
439
|
+
if (result && typeof result.then === 'function') {
|
|
440
|
+
return result.then(connectionResource.bind(function(res) {
|
|
441
|
+
if (ctx) {
|
|
442
|
+
TraceContextManager.resume(ctx.id);
|
|
443
|
+
ctx.elapsed = Date.now() - ctx.start_time;
|
|
444
|
+
ctx.footprint('MsSQL Pool Connecting Done');
|
|
445
|
+
}
|
|
446
|
+
return res;
|
|
447
|
+
})).catch(connectionResource.bind(function(err) {
|
|
448
|
+
if (ctx) {
|
|
449
|
+
TraceContextManager.resume(ctx.id);
|
|
450
|
+
ctx.elapsed = Date.now() - ctx.start_time;
|
|
451
|
+
ctx.footprint('MsSQL Pool Connecting Error');
|
|
452
|
+
handleSqlError(ctx, err);
|
|
453
|
+
}
|
|
454
|
+
throw err;
|
|
455
|
+
}));
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
return result;
|
|
459
|
+
});
|
|
460
|
+
};
|
|
461
|
+
});
|
|
462
|
+
pool.connect.__whatap_wrapped__ = true;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
return pool;
|
|
467
|
+
};
|
|
468
|
+
});
|
|
469
|
+
mod.ConnectionPool.__whatap_wrapped__ = true;
|
|
470
|
+
}
|
|
471
|
+
};
|
|
472
|
+
|
|
232
473
|
exports.MssqlObserver = MssqlObserver;
|