whatap 1.0.1-canary.2 → 1.0.2
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/README.md +33 -77
- package/lib/conf/conf-sys-mon.js +101 -0
- package/lib/conf/config-default.js +10 -3
- package/lib/conf/configure.js +369 -349
- package/lib/conf/license.js +1 -1
- package/lib/control/cmd-config.js +24 -0
- package/lib/control/control-handler.js +367 -0
- package/lib/control/packagectr-helper.js +34 -3
- package/lib/core/agent.js +176 -888
- package/lib/core/interceptor.js +6 -6
- package/lib/core/request-agent.js +27 -0
- package/lib/core/shimmer.js +82 -36
- package/lib/counter/counter-manager.js +79 -8
- package/lib/counter/meter/meter-activex.js +67 -0
- package/lib/counter/meter/meter-httpc.js +57 -0
- package/lib/counter/meter/meter-resource.js +9 -0
- package/lib/counter/meter/meter-service.js +168 -0
- package/lib/counter/meter/meter-socket.io.js +51 -0
- package/lib/counter/meter/meter-sql.js +71 -0
- package/lib/counter/meter/meter-users.js +58 -0
- package/lib/counter/meter.js +183 -0
- package/lib/counter/task/activetransaction.js +68 -17
- package/lib/counter/task/agentinfo.js +107 -0
- package/lib/{system → counter/task}/gc-action.js +27 -74
- package/lib/counter/task/gcstat.js +34 -0
- package/lib/counter/task/heapmem.js +25 -0
- package/lib/counter/task/httpc.js +76 -0
- package/lib/counter/task/metering-info.js +125 -0
- package/lib/counter/task/proc-cpu.js +29 -0
- package/lib/counter/task/realtimeuser.js +31 -0
- package/lib/counter/task/res/systemECSTask.js +39 -0
- package/lib/counter/task/res/systemKubeTask.js +53 -0
- package/lib/counter/task/res/util/awsEcsClientThread.js +218 -0
- package/lib/counter/task/res/util/linuxProcStatUtil.js +14 -0
- package/lib/counter/task/res-sys-cpu.js +62 -0
- package/lib/counter/task/service.js +202 -0
- package/lib/counter/task/socketio.js +30 -0
- package/lib/counter/task/sql.js +105 -0
- package/lib/counter/task/systemperf.js +43 -0
- package/lib/data/datapack-sender.js +289 -0
- package/lib/data/dataprofile-agent.js +162 -0
- package/lib/data/datatext-agent.js +135 -0
- package/lib/data/event-level.js +15 -0
- package/lib/data/test.js +49 -0
- package/lib/data/zipprofile.js +197 -0
- package/lib/env/constants.js +21 -0
- package/lib/error/error-handler.js +437 -0
- package/lib/io/data-inputx.js +13 -3
- package/lib/io/data-outputx.js +268 -206
- package/lib/kube/kube-client.js +144 -0
- package/lib/lang/text-types.js +58 -0
- package/lib/logger.js +6 -6
- package/lib/logsink/line-log-util.js +87 -0
- package/lib/logsink/line-log.js +12 -0
- package/lib/logsink/log-sender.js +78 -0
- package/lib/logsink/log-tracer.js +40 -0
- package/lib/logsink/sender-util.js +56 -0
- package/lib/logsink/zip/zip-send.js +177 -0
- package/lib/net/netflag.js +55 -0
- package/lib/net/receiver.js +66 -0
- package/lib/net/security-master.js +139 -20
- package/lib/net/sender.js +141 -0
- package/lib/net/tcp-return.js +18 -0
- package/lib/net/tcp-session.js +286 -0
- package/lib/net/tcpreq-client-proxy.js +70 -0
- package/lib/net/tcprequest-mgr.js +58 -0
- package/lib/observers/apollo-server-observer.js +33 -27
- package/lib/observers/cluster-observer.js +22 -0
- package/lib/observers/express-observer.js +215 -0
- package/lib/observers/file-observer.js +184 -0
- package/lib/observers/global-observer.js +155 -80
- package/lib/observers/grpc-observer.js +336 -0
- package/lib/observers/http-observer.js +666 -236
- package/lib/observers/maria-observer.js +204 -362
- package/lib/observers/memcached-observer.js +56 -0
- package/lib/observers/mongo-observer.js +317 -0
- package/lib/observers/mongodb-observer.js +169 -226
- package/lib/observers/mongoose-observer.js +518 -323
- package/lib/observers/mssql-observer.js +177 -418
- package/lib/observers/mysql-observer.js +342 -449
- package/lib/observers/mysql2-observer.js +396 -358
- package/lib/observers/net-observer.js +77 -0
- package/lib/observers/oracle-observer.js +559 -384
- package/lib/observers/pgsql-observer.js +231 -489
- package/lib/observers/prisma-observer.js +303 -92
- package/lib/observers/process-observer.js +79 -35
- package/lib/observers/promise-observer.js +31 -0
- package/lib/observers/redis-observer.js +166 -331
- package/lib/observers/schedule-observer.js +67 -0
- package/lib/observers/socket.io-observer.js +226 -187
- package/lib/observers/stream-observer.js +19 -0
- package/lib/observers/thrift-observer.js +197 -0
- package/lib/observers/websocket-observer.js +175 -301
- package/lib/pack/activestack-pack.js +55 -0
- package/lib/pack/apenum.js +8 -0
- package/lib/pack/counter-pack.js +3 -0
- package/lib/pack/errorsnap-pack.js +69 -0
- package/lib/pack/event-pack.js +54 -0
- package/lib/pack/hitmap-pack.js +63 -0
- package/lib/pack/hitmap-pack1.js +152 -0
- package/lib/pack/log-sink-pack.js +14 -52
- package/lib/pack/netstat.js +15 -0
- package/lib/pack/otype.js +7 -0
- package/lib/pack/profile-pack.js +49 -0
- package/lib/pack/realtimeuser-pack.js +41 -0
- package/lib/pack/stat-general-pack.js +96 -0
- package/lib/pack/staterror-pack.js +120 -0
- package/lib/pack/stathttpc-pack.js +66 -0
- package/lib/pack/stathttpc-rec.js +78 -0
- package/lib/pack/statremote-pack.js +46 -0
- package/lib/pack/statservice-pack.js +63 -0
- package/lib/pack/statservice-pack1.js +88 -0
- package/lib/pack/statservice-rec.js +292 -0
- package/lib/pack/statservice-rec_dep.js +151 -0
- package/lib/pack/statsql-pack.js +69 -0
- package/lib/pack/statsql-rec.js +100 -0
- package/lib/pack/statuseragent-pack.js +44 -0
- package/lib/pack/tagcount-pack.js +4 -4
- package/lib/pack/tagctr.js +15 -0
- package/lib/pack/text-pack.js +50 -0
- package/lib/pack/time-count.js +25 -0
- package/lib/pack/websocket.js +15 -0
- package/lib/pack/zip-pack.js +70 -0
- package/lib/pii/pii-item.js +31 -0
- package/lib/pii/pii-mask.js +174 -0
- package/lib/plugin/plugin-loadermanager.js +57 -0
- package/lib/plugin/plugin.js +75 -0
- package/lib/service/tx-record.js +332 -0
- package/lib/stat/stat-error.js +116 -0
- package/lib/stat/stat-httpc.js +98 -0
- package/lib/stat/stat-remote-ip.js +46 -0
- package/lib/stat/stat-remote-ipurl.js +88 -0
- package/lib/stat/stat-sql.js +113 -0
- package/lib/stat/stat-tranx.js +58 -0
- package/lib/stat/stat-tx-caller.js +160 -0
- package/lib/stat/stat-tx-domain.js +111 -0
- package/lib/stat/stat-tx-referer.js +112 -0
- package/lib/stat/stat-useragent.js +48 -0
- package/lib/stat/timingsender.js +76 -0
- package/lib/step/activestack-step.js +38 -0
- package/lib/step/dbc-step.js +36 -0
- package/lib/step/http-stepx.js +67 -0
- package/lib/step/message-step.js +40 -0
- package/lib/step/method-stepx.js +45 -0
- package/lib/step/resultset-step.js +40 -0
- package/lib/step/securemsg-step.js +44 -0
- package/lib/step/socket-step.js +46 -0
- package/lib/step/sql-stepx.js +68 -0
- package/lib/step/sqlxtype.js +16 -0
- package/lib/step/step.js +66 -0
- package/lib/step/stepenum.js +54 -0
- package/lib/topology/link.js +63 -0
- package/lib/topology/nodeinfo.js +123 -0
- package/lib/topology/status-detector.js +111 -0
- package/lib/trace/trace-context-manager.js +113 -25
- package/lib/trace/trace-context.js +21 -7
- package/lib/trace/trace-httpc.js +17 -11
- package/lib/trace/trace-sql.js +29 -21
- package/lib/util/anylist.js +103 -0
- package/lib/util/cardinality/hyperloglog.js +106 -0
- package/lib/util/cardinality/murmurhash.js +31 -0
- package/lib/util/cardinality/registerset.js +75 -0
- package/lib/util/errordata.js +21 -0
- package/lib/util/escape-literal-sql.js +5 -5
- package/lib/util/hashutil.js +18 -18
- package/lib/util/iputil_x.js +527 -0
- package/lib/util/keygen.js +0 -3
- package/lib/util/kube-util.js +73 -0
- package/lib/util/linkedset.js +1 -2
- package/lib/util/nodeutil.js +2 -1
- package/lib/util/paramsecurity.js +80 -0
- package/lib/util/pre-process.js +13 -0
- package/lib/util/process-seq.js +166 -0
- package/lib/util/property-util.js +36 -0
- package/lib/util/request-queue.js +70 -0
- package/lib/util/requestdouble-queue.js +72 -0
- package/lib/util/resourceprofile.js +157 -0
- package/lib/util/stop-watch.js +30 -0
- package/lib/util/system-util.js +10 -0
- package/lib/util/userid-util.js +57 -0
- package/lib/value/map-value.js +3 -2
- package/package.json +9 -5
- package/whatap.conf +1 -4
- 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 +0 -4
- package/lib/observers/ioredis-observer.js +0 -294
- package/lib/udp/async_sender.js +0 -119
- package/lib/udp/index.js +0 -17
- package/lib/udp/packet_enum.js +0 -52
- package/lib/udp/packet_queue.js +0 -69
- package/lib/udp/packet_type_enum.js +0 -33
- package/lib/udp/param_def.js +0 -72
- package/lib/udp/udp_session.js +0 -336
- package/lib/util/sql-util.js +0 -178
- package/lib/util/trace-helper.js +0 -91
- package/lib/util/transfer.js +0 -58
|
@@ -5,277 +5,258 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
var TraceContextManager = require('../trace/trace-context-manager'),
|
|
8
|
-
ParsedSql
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
+
DateUtil = require('../util/dateutil'),
|
|
24
|
+
Buffer = require('buffer').Buffer,
|
|
25
|
+
shimmer = require('../core/shimmer'),
|
|
26
|
+
TraceSQL = require('../trace/trace-sql');
|
|
20
27
|
|
|
21
28
|
var MariaObserver = function (agent) {
|
|
22
29
|
this.agent = agent;
|
|
23
30
|
this.packages = ['mariadb'];
|
|
24
31
|
};
|
|
25
32
|
|
|
26
|
-
var dbc_hash
|
|
27
|
-
|
|
33
|
+
var dbc, dbc_hash;
|
|
34
|
+
MariaObserver.prototype.inject = function (mod, moduleName) {
|
|
35
|
+
if (mod.__whatap_observe__) { return; }
|
|
36
|
+
mod.__whatap_observe__ = true;
|
|
28
37
|
|
|
29
|
-
|
|
30
|
-
var hookedInstances = new WeakSet();
|
|
38
|
+
Logger.initPrint("MariaObserver");
|
|
31
39
|
|
|
32
|
-
|
|
33
|
-
if (!err) return;
|
|
40
|
+
if (!conf.sql_enabled) return;
|
|
34
41
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (conf.trace_sql_error_stack && conf.trace_sql_error_depth && err.stack) {
|
|
41
|
-
var traceDepth = conf.trace_sql_error_depth;
|
|
42
|
-
var stackLines = err.stack.split("\n");
|
|
43
|
-
if (stackLines.length > traceDepth) {
|
|
44
|
-
stackLines = stackLines.slice(0, traceDepth + 1);
|
|
45
|
-
}
|
|
46
|
-
errorStack = stackLines.join("\n");
|
|
47
|
-
ctx.error_message = errorStack;
|
|
48
|
-
}
|
|
42
|
+
// shimmer.wrap(mod, 'createConnection', wrapCreateConnection(mod));
|
|
43
|
+
shimmer.wrap(mod, 'createConnection', wrapConnection(mod));
|
|
44
|
+
shimmer.wrap(mod, 'createPool', wrapCreatePool(mod));
|
|
45
|
+
};
|
|
49
46
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
shouldAddError = true;
|
|
54
|
-
} else if (conf._is_trace_ignore_err_msg_contains === true && errorMessage &&
|
|
55
|
-
errorMessage.indexOf(conf.trace_ignore_err_msg_contains) < 0) {
|
|
56
|
-
shouldAddError = true;
|
|
57
|
-
} else if (conf._is_trace_ignore_err_cls_contains === false &&
|
|
58
|
-
conf._is_trace_ignore_err_msg_contains === false) {
|
|
59
|
-
shouldAddError = true;
|
|
60
|
-
}
|
|
47
|
+
var _finishQuery = function (ctx, sql_step) {
|
|
48
|
+
sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
|
|
49
|
+
TraceSQL.isSlowSQL(ctx);
|
|
61
50
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
ctx.error_message = errorMessage;
|
|
66
|
-
ctx.errClass = errorClass;
|
|
67
|
-
ctx.errMessage = errorMessage;
|
|
51
|
+
MeterSql.add(sql_step.hash, sql_step.elapsed, false);
|
|
52
|
+
StatSql.addSqlTime(ctx, ctx.service_hash, sql_step.dbc, sql_step.hash, sql_step.elapsed, false, 0);
|
|
53
|
+
};
|
|
68
54
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
if (errorStack || err.stack) {
|
|
74
|
-
errors.push(errorStack || err.stack);
|
|
75
|
-
}
|
|
76
|
-
AsyncSender.send_packet(PacketTypeEnum.TX_ERROR, ctx, errors);
|
|
77
|
-
}
|
|
78
|
-
} catch (e) {
|
|
79
|
-
Logger.printError('WHATAP-214', 'Error handling MariaDB error', e, false);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
55
|
+
var _handleError = function (ctx, sql_step, err) {
|
|
56
|
+
sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
|
|
57
|
+
TraceSQL.isSlowSQL(ctx);
|
|
82
58
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
59
|
+
MeterSql.add(sql_step.hash, sql_step.elapsed, false);
|
|
60
|
+
StatSql.addSqlTime(ctx, ctx.service_hash, sql_step.dbc, sql_step.hash, sql_step.elapsed, true, 0);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
function wrapCreateConnection(agent) {
|
|
64
|
+
return function (original) {
|
|
65
|
+
return async function (...args) {
|
|
66
|
+
const ctx = TraceContextManager.getCurrentContext();
|
|
67
|
+
if (!ctx || ctx.db_opening) return original.apply(this, args);
|
|
68
|
+
|
|
69
|
+
ctx.db_opening = true;
|
|
70
|
+
ctx.footprint('Maria Connecting Start');
|
|
71
|
+
|
|
72
|
+
// const dbc_step = new DBCStep();
|
|
73
|
+
// dbc_step.start_time = ctx.getElapsedTime();
|
|
74
|
+
|
|
75
|
+
const connection = await original.apply(this, args);
|
|
76
|
+
wrapConnectionMethods(connection, agent);
|
|
77
|
+
|
|
78
|
+
ctx.footprint('Maria Connecting Done');
|
|
79
|
+
ctx.db_opening = false;
|
|
80
|
+
|
|
81
|
+
getDBCHash(args);
|
|
82
|
+
// dbc_step.hash = dbc_hash;
|
|
83
|
+
// ctx.profile.push(dbc_step);
|
|
84
|
+
|
|
85
|
+
return connection;
|
|
86
|
+
};
|
|
87
|
+
};
|
|
94
88
|
}
|
|
95
89
|
|
|
96
|
-
function
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
90
|
+
function wrapConnection(agent) {
|
|
91
|
+
return function (original) {
|
|
92
|
+
return function (...args) {
|
|
93
|
+
const connectionPromise = original.apply(this, args);
|
|
94
|
+
getDBCHash(args);
|
|
100
95
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
if (connection.execute && !connection.execute.__whatap_wrapped__) {
|
|
107
|
-
shimmer.wrap(connection, 'execute', createQueryWrapper(agent, dbc));
|
|
108
|
-
connection.execute.__whatap_wrapped__ = true;
|
|
96
|
+
return connectionPromise.then(connection => {
|
|
97
|
+
shimmer.wrap(connection, 'query', createQueryHook(agent));
|
|
98
|
+
return connection;
|
|
99
|
+
});
|
|
109
100
|
}
|
|
110
101
|
}
|
|
111
102
|
}
|
|
112
103
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
104
|
+
function wrapCreatePool(agent) {
|
|
105
|
+
return function (original) {
|
|
106
|
+
return function (...args) {
|
|
107
|
+
const pool = original.apply(this, args);
|
|
108
|
+
getDBCHash(args);
|
|
109
|
+
|
|
110
|
+
shimmer.wrap(pool, 'getConnection', (originalGetConnection) => {
|
|
111
|
+
return async function (...connArgs) {
|
|
112
|
+
const connection = await originalGetConnection.apply(this, connArgs);
|
|
113
|
+
wrapConnectionMethods(connection, agent);
|
|
114
|
+
return connection;
|
|
115
|
+
};
|
|
116
|
+
});
|
|
119
117
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
118
|
+
return pool;
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
}
|
|
123
122
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
123
|
+
function wrapConnectionMethods(connection, agent) {
|
|
124
|
+
shimmer.wrap(connection, 'query', createQueryHook(agent));
|
|
125
|
+
shimmer.wrap(connection, 'execute', createQueryHook(agent));
|
|
126
|
+
}
|
|
127
127
|
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
function createQueryHook(agent) {
|
|
129
|
+
return function (original) {
|
|
130
|
+
return function (...args) {
|
|
131
|
+
const ctx = TraceContextManager.getCurrentContext();
|
|
132
|
+
if (!ctx || !args[0]) return original.apply(this, args);
|
|
130
133
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
ctx.start_time = Date.now();
|
|
134
|
+
ctx.db_opening = true;
|
|
135
|
+
ctx.footprint('Maria Connecting Start');
|
|
134
136
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
137
|
+
const dbc_step = new DBCStep();
|
|
138
|
+
ctx.footprint('Maria Connecting Done');
|
|
139
|
+
ctx.db_opening = false;
|
|
138
140
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
ctx.footprint('MariaDB Query Start');
|
|
142
|
-
ctx.sql_count++;
|
|
141
|
+
dbc_step.hash = dbc_hash;
|
|
142
|
+
ctx.profile.push(dbc_step);
|
|
143
143
|
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
const sql_step = new SqlStepX();
|
|
145
|
+
sql_step.start_time = ctx.getElapsedTime();
|
|
146
|
+
ctx.profile.push(sql_step);
|
|
146
147
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if (args[0].values && Array.isArray(args[0].values)) {
|
|
150
|
-
params = args[0].values;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
148
|
+
ctx.footprint('Maria Query Start');
|
|
149
|
+
ctx.sql_count++;
|
|
153
150
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
if (typeof sql === 'string' && sql.length > 0 && params && params.length > 0) {
|
|
157
|
-
try {
|
|
158
|
-
// MariaDB는 mysql2 스타일의 파라미터 바인딩 지원
|
|
159
|
-
const result = params.map((param) => {
|
|
160
|
-
if(typeof param === 'string'){
|
|
161
|
-
return `'${param.replace(/'/g, "''")}'` // SQL injection 방지
|
|
162
|
-
}
|
|
163
|
-
return param
|
|
164
|
-
}).join(', ');
|
|
165
|
-
|
|
166
|
-
// 간단한 파라미터 치환 (? 기준)
|
|
167
|
-
var paramIndex = 0;
|
|
168
|
-
finalSql = sql.replace(/\?/g, function() {
|
|
169
|
-
if (paramIndex < params.length) {
|
|
170
|
-
var param = params[paramIndex++];
|
|
171
|
-
if (typeof param === 'string') {
|
|
172
|
-
return `'${param.replace(/'/g, "''")}'`;
|
|
173
|
-
}
|
|
174
|
-
return param;
|
|
175
|
-
}
|
|
176
|
-
return '?';
|
|
177
|
-
});
|
|
178
|
-
} catch (e) {
|
|
179
|
-
Logger.printError('WHATAP-SQL-BINDING', 'Error binding parameters', e, false);
|
|
180
|
-
finalSql = sql; // 바인딩 실패 시 원본 사용
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
var psql = null;
|
|
185
|
-
if (typeof finalSql === 'string' && finalSql.length > 0) {
|
|
186
|
-
try {
|
|
187
|
-
psql = escapeLiteral(finalSql);
|
|
188
|
-
// Logger.print('WHATAP-SQL-DEBUG', 'Processing SQL: ' + finalSql.substring(0, 200), false);
|
|
189
|
-
} catch (e) {
|
|
190
|
-
Logger.printError('WHATAP-215', 'MariaObserver escapeliteral error', e, false);
|
|
191
|
-
}
|
|
192
|
-
} else {
|
|
193
|
-
finalSql = '';
|
|
194
|
-
psql = escapeLiteral(finalSql);
|
|
195
|
-
}
|
|
151
|
+
var sql = args.length > 0 ? args[0] : undefined,
|
|
152
|
+
psql = null;
|
|
196
153
|
|
|
197
|
-
|
|
198
|
-
|
|
154
|
+
if(typeof sql !== 'string') {
|
|
155
|
+
sql = args[0].sql || undefined;
|
|
156
|
+
}
|
|
199
157
|
|
|
200
|
-
|
|
158
|
+
if (typeof sql === 'string' && sql.length > 0) {
|
|
159
|
+
try {
|
|
160
|
+
psql = escapeLiteral(sql);
|
|
161
|
+
} catch (e) {
|
|
162
|
+
Logger.printError('WHATAP-191', 'MariaObserver escapeliteral error', e);
|
|
163
|
+
}
|
|
164
|
+
} else {
|
|
165
|
+
sql = '';
|
|
166
|
+
psql = escapeLiteral(sql);
|
|
167
|
+
}
|
|
201
168
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
if (currentCtx == null) {
|
|
207
|
-
currentCtx = ctx;
|
|
208
|
-
}
|
|
169
|
+
if(psql != null) {
|
|
170
|
+
sql_step.hash = psql.sql;
|
|
171
|
+
// sql_step.crud = psql.type.charCodeAt(0);
|
|
172
|
+
}
|
|
209
173
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
// 결과 개수 계산
|
|
214
|
-
if (res) {
|
|
215
|
-
if (Array.isArray(res)) {
|
|
216
|
-
resultCount = res.length;
|
|
217
|
-
} else if (res.affectedRows !== undefined) {
|
|
218
|
-
resultCount = res.affectedRows;
|
|
219
|
-
} else if (res.changedRows !== undefined) {
|
|
220
|
-
resultCount = res.changedRows;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
174
|
+
var els = new EscapeLiteralSQL(sql);
|
|
175
|
+
els.process();
|
|
223
176
|
|
|
224
|
-
|
|
225
|
-
try {
|
|
226
|
-
TraceSQL.isSlowSQL(currentCtx);
|
|
177
|
+
ctx.active_sqlhash = sql_step.hash;
|
|
227
178
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
179
|
+
if(conf.profile_sql_param_enabled) {
|
|
180
|
+
var params = args.length > 1 && Array.isArray(args[1]) ? args[1] : undefined;
|
|
181
|
+
sql_step.setTrue(1);
|
|
182
|
+
var crc = {value : 0};
|
|
183
|
+
sql_step.p1 = toParamBytes(psql.param, crc);
|
|
184
|
+
if(params != undefined) {
|
|
185
|
+
const result = params.map((param) => {
|
|
186
|
+
if(typeof param === 'string'){
|
|
187
|
+
return `'${param}'`
|
|
234
188
|
}
|
|
189
|
+
return param
|
|
190
|
+
}).toString()
|
|
191
|
+
sql_step.p2 = toParamBytes(result, crc);
|
|
192
|
+
}
|
|
193
|
+
sql_step.pcrc = crc.value;
|
|
194
|
+
}
|
|
235
195
|
|
|
236
|
-
|
|
237
|
-
currentCtx.active_sqlhash = false;
|
|
238
|
-
AsyncSender.send_packet(PacketTypeEnum.TX_SQL, currentCtx, [dbcUrl, finalSql, String(resultCount)]);
|
|
239
|
-
|
|
240
|
-
currentCtx.footprint('MariaDB Query Done');
|
|
241
|
-
return res;
|
|
242
|
-
}).catch(err => {
|
|
243
|
-
var currentCtx = TraceContextManager.getCurrentContext();
|
|
244
|
-
if (currentCtx == null) {
|
|
245
|
-
currentCtx = ctx;
|
|
246
|
-
}
|
|
196
|
+
const result = original.apply(this, args);
|
|
247
197
|
|
|
248
|
-
|
|
198
|
+
return result.then(res => {
|
|
199
|
+
if (Array.isArray(res) && psql && psql.type === "S") {
|
|
200
|
+
var result_step = new ResultSetStep();
|
|
201
|
+
result_step.start_time = ctx.getElapsedTime();
|
|
202
|
+
result_step.elapsed = 0;
|
|
203
|
+
result_step.fetch = res.length;
|
|
204
|
+
result_step.sqlhash = psql.sql;
|
|
205
|
+
result_step.dbc = dbc_hash;
|
|
206
|
+
ctx.profile.push(result_step);
|
|
249
207
|
|
|
250
|
-
|
|
251
|
-
handleSqlError(currentCtx, err, sqlHash);
|
|
208
|
+
ctx.rs_count = ctx.rs_count ? ctx.rs_count + res.length : res.length;
|
|
252
209
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
AsyncSender.send_packet(PacketTypeEnum.TX_SQL, currentCtx, [dbcUrl, finalSql, '0']);
|
|
210
|
+
MeterSql.addFetch(result_step.dbc, result_step.fetch, 0);
|
|
211
|
+
StatSql.addFetch(result_step.dbc, result_step.sqlhash, result_step.fetch, 0);
|
|
256
212
|
|
|
257
|
-
|
|
258
|
-
throw err;
|
|
259
|
-
});
|
|
213
|
+
TraceSQL.isTooManyRecords(sql_step, result_step.fetch, ctx);
|
|
260
214
|
}
|
|
261
|
-
|
|
262
|
-
|
|
215
|
+
var isSelectQuery = psql && psql.type === "S"? true : false;
|
|
216
|
+
_finishQuery(ctx, sql_step, isSelectQuery, res);
|
|
217
|
+
return res;
|
|
218
|
+
}).catch(err => {
|
|
219
|
+
_handleError(ctx, sql_step, err)
|
|
220
|
+
if (conf.trace_sql_error_stack && conf.trace_sql_error_depth) {
|
|
221
|
+
var traceDepth = conf.trace_sql_error_depth;
|
|
222
|
+
|
|
223
|
+
var errorStack = err.stack.split("\n");
|
|
224
|
+
if (errorStack.length > traceDepth) {
|
|
225
|
+
errorStack = errorStack.slice(0, traceDepth + 1);
|
|
226
|
+
}
|
|
227
|
+
ctx.error_message = errorStack.join("\n");
|
|
228
|
+
sql_step.error = ctx.error = StatError.addError('pgsql -' + err.code, err.message, ctx.service_hash, TextTypes.SQL, null);
|
|
229
|
+
}
|
|
230
|
+
throw err;
|
|
263
231
|
});
|
|
264
232
|
};
|
|
265
233
|
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
var toParamBytes = function (p, crc) {
|
|
237
|
+
if (p == null || p.length === 0) {
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
try {
|
|
241
|
+
return ParamSecurity.encrypt(Buffer.from(p, 'utf8'), crc);
|
|
242
|
+
} catch (e) {
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
266
245
|
};
|
|
267
246
|
|
|
268
|
-
|
|
247
|
+
function getDBCHash(args) {
|
|
248
|
+
dbc = `mariadb://${(args[0] || {}).user || ''}@${(args[0] || {}).host || ''}/${(args[0] || {}).database || ''}`;
|
|
249
|
+
dbc_hash = HashUtil.hashFromString(dbc);
|
|
250
|
+
}
|
|
251
|
+
|
|
269
252
|
var checkedSql = new IntKeyMap(2000).setMax(2000);
|
|
270
253
|
var nonLiteSql = new IntKeyMap(5000).setMax(5000);
|
|
271
254
|
var date = DateUtil.yyyymmdd();
|
|
272
255
|
|
|
273
256
|
function escapeLiteral(sql) {
|
|
274
|
-
if
|
|
275
|
-
sql = '';
|
|
276
|
-
}
|
|
257
|
+
if(sql == null) { sql = ''; }
|
|
277
258
|
|
|
278
|
-
if
|
|
259
|
+
if(date !== DateUtil.yyyymmdd()) {
|
|
279
260
|
checkedSql.clear();
|
|
280
261
|
nonLiteSql.clear();
|
|
281
262
|
date = DateUtil.yyyymmdd();
|
|
@@ -285,12 +266,12 @@ function escapeLiteral(sql) {
|
|
|
285
266
|
var sqlHash = HashUtil.hashFromString(sql);
|
|
286
267
|
var psql = nonLiteSql.get(sqlHash);
|
|
287
268
|
|
|
288
|
-
if
|
|
269
|
+
if(psql != null) {
|
|
289
270
|
return psql;
|
|
290
271
|
}
|
|
291
272
|
psql = checkedSql.get(sqlHash);
|
|
292
273
|
|
|
293
|
-
if
|
|
274
|
+
if(psql != null) {
|
|
294
275
|
return psql;
|
|
295
276
|
}
|
|
296
277
|
|
|
@@ -298,7 +279,9 @@ function escapeLiteral(sql) {
|
|
|
298
279
|
els.process();
|
|
299
280
|
|
|
300
281
|
var hash = HashUtil.hashFromString(els.getParsedSql());
|
|
301
|
-
|
|
282
|
+
DataTextAgent.SQL.add(hash, els.getParsedSql());
|
|
283
|
+
|
|
284
|
+
if(hash === sqlHash) {
|
|
302
285
|
psql = new ParsedSql(els.sqlType, hash, null);
|
|
303
286
|
nonLiteSql.put(sqlHash, psql);
|
|
304
287
|
} else {
|
|
@@ -308,145 +291,4 @@ function escapeLiteral(sql) {
|
|
|
308
291
|
return psql;
|
|
309
292
|
}
|
|
310
293
|
|
|
311
|
-
// 메인 inject 함수
|
|
312
|
-
MariaObserver.prototype.inject = function (mod, moduleName) {
|
|
313
|
-
if (mod.__whatap_observe__) {
|
|
314
|
-
return;
|
|
315
|
-
}
|
|
316
|
-
mod.__whatap_observe__ = true;
|
|
317
|
-
Logger.initPrint("MariaObserver");
|
|
318
|
-
|
|
319
|
-
if (conf.sql_enabled === false) {
|
|
320
|
-
return;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
var self = this;
|
|
324
|
-
|
|
325
|
-
// createConnection 래핑
|
|
326
|
-
if (mod.createConnection && !mod.createConnection.__whatap_wrapped__) {
|
|
327
|
-
shimmer.wrap(mod, 'createConnection', function(original) {
|
|
328
|
-
return function wrappedCreateConnection() {
|
|
329
|
-
var args = Array.prototype.slice.call(arguments);
|
|
330
|
-
var ctx = TraceContextManager.getCurrentContext();
|
|
331
|
-
|
|
332
|
-
setupDbcInfo(args);
|
|
333
|
-
|
|
334
|
-
if (ctx && !ctx.db_opening) {
|
|
335
|
-
ctx.db_opening = true;
|
|
336
|
-
ctx.footprint('MariaDB Connecting Start');
|
|
337
|
-
ctx.start_time = Date.now();
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
const result = original.apply(this, args);
|
|
341
|
-
|
|
342
|
-
// Promise 기반 처리
|
|
343
|
-
if (result && typeof result.then === 'function') {
|
|
344
|
-
return result.then(connection => {
|
|
345
|
-
hookConnectionMethods(connection, self.agent);
|
|
346
|
-
|
|
347
|
-
if (ctx) {
|
|
348
|
-
ctx.elapsed = Date.now() - ctx.start_time;
|
|
349
|
-
ctx.footprint('MariaDB Connecting Done');
|
|
350
|
-
ctx.db_opening = false;
|
|
351
|
-
}
|
|
352
|
-
return connection;
|
|
353
|
-
}).catch(error => {
|
|
354
|
-
if (ctx) {
|
|
355
|
-
ctx.elapsed = Date.now() - ctx.start_time;
|
|
356
|
-
ctx.footprint('MariaDB Connecting Error');
|
|
357
|
-
ctx.db_opening = false;
|
|
358
|
-
handleSqlError(ctx, error, 0);
|
|
359
|
-
}
|
|
360
|
-
throw error;
|
|
361
|
-
});
|
|
362
|
-
} else {
|
|
363
|
-
// 동기 처리
|
|
364
|
-
hookConnectionMethods(result, self.agent);
|
|
365
|
-
|
|
366
|
-
if (ctx) {
|
|
367
|
-
ctx.elapsed = Date.now() - ctx.start_time;
|
|
368
|
-
ctx.footprint('MariaDB Connecting Done');
|
|
369
|
-
ctx.db_opening = false;
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
return result;
|
|
374
|
-
};
|
|
375
|
-
});
|
|
376
|
-
mod.createConnection.__whatap_wrapped__ = true;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
// createPool 래핑
|
|
380
|
-
if (mod.createPool && !mod.createPool.__whatap_wrapped__) {
|
|
381
|
-
shimmer.wrap(mod, 'createPool', function(original) {
|
|
382
|
-
return function wrappedCreatePool() {
|
|
383
|
-
var args = Array.prototype.slice.call(arguments);
|
|
384
|
-
setupDbcInfo(args);
|
|
385
|
-
|
|
386
|
-
var pool = original.apply(this, args);
|
|
387
|
-
|
|
388
|
-
if (pool && !hookedInstances.has(pool)) {
|
|
389
|
-
hookedInstances.add(pool);
|
|
390
|
-
|
|
391
|
-
// Pool의 직접 쿼리 메서드들 후킹
|
|
392
|
-
if (pool.query && !pool.query.__whatap_wrapped__) {
|
|
393
|
-
shimmer.wrap(pool, 'query', createQueryWrapper(self.agent, dbc));
|
|
394
|
-
pool.query.__whatap_wrapped__ = true;
|
|
395
|
-
}
|
|
396
|
-
if (pool.execute && !pool.execute.__whatap_wrapped__) {
|
|
397
|
-
shimmer.wrap(pool, 'execute', createQueryWrapper(self.agent, dbc));
|
|
398
|
-
pool.execute.__whatap_wrapped__ = true;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
// getConnection 메서드 후킹
|
|
402
|
-
if (pool.getConnection && !pool.getConnection.__whatap_wrapped__) {
|
|
403
|
-
shimmer.wrap(pool, 'getConnection', function(original) {
|
|
404
|
-
return function wrappedGetConnection() {
|
|
405
|
-
var args = Array.prototype.slice.call(arguments);
|
|
406
|
-
var ctx = TraceContextManager.getCurrentContext();
|
|
407
|
-
|
|
408
|
-
if (ctx == null) {
|
|
409
|
-
return original.apply(this, args);
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
const connectionResource = new AsyncResource('mariadb-getConnection');
|
|
413
|
-
|
|
414
|
-
return connectionResource.runInAsyncScope(() => {
|
|
415
|
-
ctx.start_time = Date.now();
|
|
416
|
-
|
|
417
|
-
const result = original.apply(this, args);
|
|
418
|
-
|
|
419
|
-
// Promise 기반 처리
|
|
420
|
-
if (result && typeof result.then === 'function') {
|
|
421
|
-
return result.then(connectionResource.bind(function(connection) {
|
|
422
|
-
TraceContextManager.resume(ctx.id);
|
|
423
|
-
ctx.elapsed = Date.now() - ctx.start_time;
|
|
424
|
-
|
|
425
|
-
if (connection && !connection.__query_hook__) {
|
|
426
|
-
connection.__query_hook__ = true;
|
|
427
|
-
hookConnectionMethods(connection, self.agent);
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
return connection;
|
|
431
|
-
}));
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
// 동기 처리
|
|
435
|
-
hookConnectionMethods(result, self.agent);
|
|
436
|
-
ctx.elapsed = Date.now() - ctx.start_time;
|
|
437
|
-
return result;
|
|
438
|
-
});
|
|
439
|
-
};
|
|
440
|
-
});
|
|
441
|
-
pool.getConnection.__whatap_wrapped__ = true;
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
return pool;
|
|
446
|
-
};
|
|
447
|
-
});
|
|
448
|
-
mod.createPool.__whatap_wrapped__ = true;
|
|
449
|
-
}
|
|
450
|
-
};
|
|
451
|
-
|
|
452
294
|
exports.MariaObserver = MariaObserver;
|