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.
Files changed (196) hide show
  1. package/agent/darwin/arm64/whatap_nodejs +0 -0
  2. package/agent/linux/amd64/whatap_nodejs +0 -0
  3. package/agent/linux/arm64/whatap_nodejs +0 -0
  4. package/build.txt +4 -0
  5. package/lib/conf/config-default.js +3 -10
  6. package/lib/conf/configure.js +349 -369
  7. package/lib/conf/license.js +1 -1
  8. package/lib/control/packagectr-helper.js +3 -34
  9. package/lib/core/agent.js +882 -176
  10. package/lib/core/interceptor.js +6 -6
  11. package/lib/core/shimmer.js +36 -82
  12. package/lib/counter/counter-manager.js +8 -79
  13. package/lib/counter/task/activetransaction.js +17 -68
  14. package/lib/io/data-inputx.js +3 -13
  15. package/lib/io/data-outputx.js +206 -268
  16. package/lib/logger.js +6 -6
  17. package/lib/net/security-master.js +20 -139
  18. package/lib/observers/apollo-server-observer.js +27 -33
  19. package/lib/observers/global-observer.js +80 -155
  20. package/lib/observers/http-observer.js +236 -666
  21. package/lib/observers/ioredis-observer.js +294 -0
  22. package/lib/observers/maria-observer.js +362 -204
  23. package/lib/observers/mongodb-observer.js +226 -169
  24. package/lib/observers/mongoose-observer.js +323 -518
  25. package/lib/observers/mssql-observer.js +418 -177
  26. package/lib/observers/mysql-observer.js +449 -342
  27. package/lib/observers/mysql2-observer.js +358 -396
  28. package/lib/observers/oracle-observer.js +384 -559
  29. package/lib/observers/pgsql-observer.js +489 -231
  30. package/lib/observers/prisma-observer.js +92 -303
  31. package/lib/observers/process-observer.js +35 -79
  32. package/lib/observers/redis-observer.js +331 -166
  33. package/lib/observers/socket.io-observer.js +187 -226
  34. package/lib/observers/websocket-observer.js +301 -175
  35. package/lib/pack/counter-pack.js +0 -3
  36. package/lib/pack/log-sink-pack.js +52 -14
  37. package/lib/pack/tagcount-pack.js +4 -4
  38. package/lib/{counter/task → system}/gc-action.js +74 -27
  39. package/lib/trace/trace-context-manager.js +25 -113
  40. package/lib/trace/trace-context.js +7 -21
  41. package/lib/trace/trace-httpc.js +11 -17
  42. package/lib/trace/trace-sql.js +21 -29
  43. package/lib/udp/async_sender.js +119 -0
  44. package/lib/udp/index.js +17 -0
  45. package/lib/udp/packet_enum.js +52 -0
  46. package/lib/udp/packet_queue.js +69 -0
  47. package/lib/udp/packet_type_enum.js +33 -0
  48. package/lib/udp/param_def.js +72 -0
  49. package/lib/udp/udp_session.js +336 -0
  50. package/lib/util/escape-literal-sql.js +5 -5
  51. package/lib/util/hashutil.js +18 -18
  52. package/lib/util/keygen.js +3 -0
  53. package/lib/util/linkedset.js +2 -1
  54. package/lib/util/nodeutil.js +1 -2
  55. package/lib/util/sql-util.js +178 -0
  56. package/lib/util/trace-helper.js +91 -0
  57. package/lib/util/transfer.js +58 -0
  58. package/lib/value/map-value.js +2 -3
  59. package/package.json +5 -10
  60. package/lib/conf/conf-sys-mon.js +0 -101
  61. package/lib/control/cmd-config.js +0 -24
  62. package/lib/control/control-handler.js +0 -367
  63. package/lib/core/request-agent.js +0 -27
  64. package/lib/counter/meter/meter-activex.js +0 -67
  65. package/lib/counter/meter/meter-httpc.js +0 -57
  66. package/lib/counter/meter/meter-resource.js +0 -9
  67. package/lib/counter/meter/meter-service.js +0 -168
  68. package/lib/counter/meter/meter-socket.io.js +0 -51
  69. package/lib/counter/meter/meter-sql.js +0 -71
  70. package/lib/counter/meter/meter-users.js +0 -58
  71. package/lib/counter/meter.js +0 -183
  72. package/lib/counter/task/agentinfo.js +0 -107
  73. package/lib/counter/task/gcstat.js +0 -34
  74. package/lib/counter/task/heapmem.js +0 -25
  75. package/lib/counter/task/httpc.js +0 -76
  76. package/lib/counter/task/metering-info.js +0 -125
  77. package/lib/counter/task/proc-cpu.js +0 -29
  78. package/lib/counter/task/realtimeuser.js +0 -31
  79. package/lib/counter/task/res/systemECSTask.js +0 -39
  80. package/lib/counter/task/res/systemKubeTask.js +0 -53
  81. package/lib/counter/task/res/util/awsEcsClientThread.js +0 -218
  82. package/lib/counter/task/res/util/linuxProcStatUtil.js +0 -14
  83. package/lib/counter/task/res-sys-cpu.js +0 -62
  84. package/lib/counter/task/service.js +0 -202
  85. package/lib/counter/task/socketio.js +0 -30
  86. package/lib/counter/task/sql.js +0 -105
  87. package/lib/counter/task/systemperf.js +0 -43
  88. package/lib/data/datapack-sender.js +0 -289
  89. package/lib/data/dataprofile-agent.js +0 -162
  90. package/lib/data/datatext-agent.js +0 -135
  91. package/lib/data/event-level.js +0 -15
  92. package/lib/data/test.js +0 -49
  93. package/lib/data/zipprofile.js +0 -197
  94. package/lib/env/constants.js +0 -21
  95. package/lib/error/error-handler.js +0 -437
  96. package/lib/kube/kube-client.js +0 -144
  97. package/lib/lang/text-types.js +0 -58
  98. package/lib/logsink/line-log-util.js +0 -87
  99. package/lib/logsink/line-log.js +0 -12
  100. package/lib/logsink/log-sender.js +0 -78
  101. package/lib/logsink/log-tracer.js +0 -40
  102. package/lib/logsink/sender-util.js +0 -56
  103. package/lib/logsink/zip/zip-send.js +0 -177
  104. package/lib/net/netflag.js +0 -55
  105. package/lib/net/receiver.js +0 -66
  106. package/lib/net/sender.js +0 -141
  107. package/lib/net/tcp-return.js +0 -18
  108. package/lib/net/tcp-session.js +0 -286
  109. package/lib/net/tcpreq-client-proxy.js +0 -70
  110. package/lib/net/tcprequest-mgr.js +0 -58
  111. package/lib/observers/cluster-observer.js +0 -22
  112. package/lib/observers/express-observer.js +0 -215
  113. package/lib/observers/file-observer.js +0 -184
  114. package/lib/observers/grpc-observer.js +0 -336
  115. package/lib/observers/memcached-observer.js +0 -56
  116. package/lib/observers/mongo-observer.js +0 -317
  117. package/lib/observers/net-observer.js +0 -77
  118. package/lib/observers/promise-observer.js +0 -31
  119. package/lib/observers/schedule-observer.js +0 -67
  120. package/lib/observers/stream-observer.js +0 -19
  121. package/lib/observers/thrift-observer.js +0 -197
  122. package/lib/pack/activestack-pack.js +0 -55
  123. package/lib/pack/apenum.js +0 -8
  124. package/lib/pack/errorsnap-pack.js +0 -69
  125. package/lib/pack/event-pack.js +0 -54
  126. package/lib/pack/hitmap-pack.js +0 -63
  127. package/lib/pack/hitmap-pack1.js +0 -152
  128. package/lib/pack/netstat.js +0 -15
  129. package/lib/pack/otype.js +0 -7
  130. package/lib/pack/profile-pack.js +0 -49
  131. package/lib/pack/realtimeuser-pack.js +0 -41
  132. package/lib/pack/stat-general-pack.js +0 -96
  133. package/lib/pack/staterror-pack.js +0 -120
  134. package/lib/pack/stathttpc-pack.js +0 -66
  135. package/lib/pack/stathttpc-rec.js +0 -78
  136. package/lib/pack/statremote-pack.js +0 -46
  137. package/lib/pack/statservice-pack.js +0 -63
  138. package/lib/pack/statservice-pack1.js +0 -88
  139. package/lib/pack/statservice-rec.js +0 -292
  140. package/lib/pack/statservice-rec_dep.js +0 -151
  141. package/lib/pack/statsql-pack.js +0 -69
  142. package/lib/pack/statsql-rec.js +0 -100
  143. package/lib/pack/statuseragent-pack.js +0 -44
  144. package/lib/pack/tagctr.js +0 -15
  145. package/lib/pack/text-pack.js +0 -50
  146. package/lib/pack/time-count.js +0 -25
  147. package/lib/pack/websocket.js +0 -15
  148. package/lib/pack/zip-pack.js +0 -70
  149. package/lib/pii/pii-item.js +0 -31
  150. package/lib/pii/pii-mask.js +0 -174
  151. package/lib/plugin/plugin-loadermanager.js +0 -57
  152. package/lib/plugin/plugin.js +0 -75
  153. package/lib/service/tx-record.js +0 -332
  154. package/lib/stat/stat-error.js +0 -116
  155. package/lib/stat/stat-httpc.js +0 -98
  156. package/lib/stat/stat-remote-ip.js +0 -46
  157. package/lib/stat/stat-remote-ipurl.js +0 -88
  158. package/lib/stat/stat-sql.js +0 -113
  159. package/lib/stat/stat-tranx.js +0 -58
  160. package/lib/stat/stat-tx-caller.js +0 -160
  161. package/lib/stat/stat-tx-domain.js +0 -111
  162. package/lib/stat/stat-tx-referer.js +0 -112
  163. package/lib/stat/stat-useragent.js +0 -48
  164. package/lib/stat/timingsender.js +0 -76
  165. package/lib/step/activestack-step.js +0 -38
  166. package/lib/step/dbc-step.js +0 -36
  167. package/lib/step/http-stepx.js +0 -67
  168. package/lib/step/message-step.js +0 -40
  169. package/lib/step/method-stepx.js +0 -45
  170. package/lib/step/resultset-step.js +0 -40
  171. package/lib/step/securemsg-step.js +0 -44
  172. package/lib/step/socket-step.js +0 -46
  173. package/lib/step/sql-stepx.js +0 -68
  174. package/lib/step/sqlxtype.js +0 -16
  175. package/lib/step/step.js +0 -66
  176. package/lib/step/stepenum.js +0 -54
  177. package/lib/topology/link.js +0 -63
  178. package/lib/topology/nodeinfo.js +0 -123
  179. package/lib/topology/status-detector.js +0 -111
  180. package/lib/util/anylist.js +0 -103
  181. package/lib/util/cardinality/hyperloglog.js +0 -106
  182. package/lib/util/cardinality/murmurhash.js +0 -31
  183. package/lib/util/cardinality/registerset.js +0 -75
  184. package/lib/util/errordata.js +0 -21
  185. package/lib/util/iputil_x.js +0 -527
  186. package/lib/util/kube-util.js +0 -73
  187. package/lib/util/paramsecurity.js +0 -80
  188. package/lib/util/pre-process.js +0 -13
  189. package/lib/util/process-seq.js +0 -166
  190. package/lib/util/property-util.js +0 -36
  191. package/lib/util/request-queue.js +0 -70
  192. package/lib/util/requestdouble-queue.js +0 -72
  193. package/lib/util/resourceprofile.js +0 -157
  194. package/lib/util/stop-watch.js +0 -30
  195. package/lib/util/system-util.js +0 -10
  196. package/lib/util/userid-util.js +0 -57
@@ -0,0 +1,294 @@
1
+ var TraceContextManager = require('../trace/trace-context-manager'),
2
+ HashUtil = require('../util/hashutil'),
3
+ Logger = require('../logger'),
4
+ conf = require('../conf/configure'),
5
+ AsyncSender = require('../udp/async_sender'),
6
+ PacketTypeEnum = require('../udp/packet_type_enum');
7
+
8
+ const { AsyncResource } = require('async_hooks');
9
+
10
+ var IORedisObserver = function (agent) {
11
+ this.agent = agent;
12
+ this.aop = agent.aop;
13
+ this.packages = ['ioredis'];
14
+ };
15
+
16
+ IORedisObserver.prototype.inject = function (mod, modName) {
17
+ if (mod.__whatap_observe__) {
18
+ return;
19
+ }
20
+ mod.__whatap_observe__ = true;
21
+ Logger.initPrint("IORedisObserver");
22
+
23
+ if (conf.sql_enabled === false) {
24
+ return;
25
+ }
26
+
27
+ var self = this;
28
+ var dbc_hash = 0;
29
+ var dbc = 'redis://';
30
+
31
+ // Redis 명령어 매핑 (Redis observer와 동일)
32
+ var REDIS_COMMANDS = {
33
+ // 기본 명령어들
34
+ 'ping': 'PING', 'get': 'GET', 'set': 'SET', 'del': 'DEL', 'exists': 'EXISTS', 'keys': 'KEYS',
35
+ 'setex': 'SETEX', 'setEx': 'SETEX', 'expire': 'EXPIRE', 'expireAt': 'EXPIREAT', 'expireat': 'EXPIREAT',
36
+ 'ttl': 'TTL', 'incr': 'INCR', 'decr': 'DECR', 'incrBy': 'INCRBY', 'incrby': 'INCRBY',
37
+ 'decrBy': 'DECRBY', 'decrby': 'DECRBY', 'mGet': 'MGET', 'mget': 'MGET', 'mSet': 'MSET', 'mset': 'MSET',
38
+
39
+ // Hash 명령어들
40
+ 'hSet': 'HSET', 'hset': 'HSET', 'hGet': 'HGET', 'hget': 'HGET', 'hGetAll': 'HGETALL', 'hgetall': 'HGETALL',
41
+ 'hMGet': 'HMGET', 'hmget': 'HMGET', 'hMSet': 'HMSET', 'hmset': 'HMSET', 'hDel': 'HDEL', 'hdel': 'HDEL',
42
+
43
+ // List 명령어들
44
+ 'lPush': 'LPUSH', 'lpush': 'LPUSH', 'rPush': 'RPUSH', 'rpush': 'RPUSH', 'lPop': 'LPOP', 'lpop': 'LPOP',
45
+ 'rPop': 'RPOP', 'rpop': 'RPOP', 'lRange': 'LRANGE', 'lrange': 'LRANGE', 'lLen': 'LLEN', 'llen': 'LLEN',
46
+ 'lSet': 'LSET', 'lset': 'LSET', 'lRem': 'LREM', 'lrem': 'LREM',
47
+
48
+ // Set 명령어들
49
+ 'sAdd': 'SADD', 'sadd': 'SADD', 'sMembers': 'SMEMBERS', 'smembers': 'SMEMBERS', 'sRem': 'SREM', 'srem': 'SREM',
50
+ 'sCard': 'SCARD', 'scard': 'SCARD',
51
+
52
+ // Sorted Set 명령어들
53
+ 'zAdd': 'ZADD', 'zadd': 'ZADD', 'zRange': 'ZRANGE', 'zrange': 'ZRANGE', 'zRem': 'ZREM', 'zrem': 'ZREM'
54
+ };
55
+
56
+ // DBC 정보 설정
57
+ function setupDbcInfo(connectionOptions) {
58
+ if (dbc_hash === 0 && connectionOptions) {
59
+ dbc = 'redis://';
60
+ dbc += connectionOptions.host || 'localhost';
61
+ dbc += ':';
62
+ dbc += connectionOptions.port || 6379;
63
+ dbc += '/';
64
+ dbc += connectionOptions.db || 0;
65
+ dbc_hash = HashUtil.hashFromString(dbc);
66
+ }
67
+ }
68
+
69
+ function handleRedisError(ctx, err) {
70
+ if (!err) return;
71
+
72
+ try {
73
+ var errorClass = err.code || err.name || 'IORedisError';
74
+ var errorMessage = err.message || 'ioredis error';
75
+
76
+ if (!ctx.error) ctx.error = 1;
77
+ ctx.status = 500;
78
+ var errors = [errorClass, errorMessage];
79
+
80
+ AsyncSender.send_packet(PacketTypeEnum.TX_ERROR, ctx, errors);
81
+ } catch (e) {
82
+ Logger.printError('WHATAP-234', 'Error handling IORedis error', e, false);
83
+ }
84
+ }
85
+
86
+ // IORedis 클래스의 prototype.sendCommand 메서드를 직접 후킹하는 방식
87
+ if (mod && mod.prototype && !mod.__whatap_wrapped__) {
88
+ // IORedis의 핵심 메서드인 sendCommand를 후킹
89
+ if (mod.prototype.sendCommand && !mod.prototype.sendCommand.__whatap_wrapped__) {
90
+ var originalSendCommand = mod.prototype.sendCommand;
91
+
92
+ mod.prototype.sendCommand = function(command, stream) {
93
+ var ctx = TraceContextManager.getCurrentContext();
94
+ if (!ctx || !command || !command.name) {
95
+ return originalSendCommand.apply(this, arguments);
96
+ }
97
+
98
+ var commandName = command.name.toLowerCase();
99
+ var normalizedCommand = REDIS_COMMANDS[commandName] || command.name.toUpperCase();
100
+
101
+ // 연결 정보 설정 (한 번만)
102
+ if (dbc_hash === 0 && this.options) {
103
+ setupDbcInfo(this.options);
104
+ }
105
+
106
+ var self = this;
107
+ var commandArgs = command.args || [];
108
+
109
+ const asyncResource = new AsyncResource('ioredis-command');
110
+
111
+ return asyncResource.runInAsyncScope(() => {
112
+ // DB 연결 패킷 전송
113
+ ctx.start_time = Date.now();
114
+ ctx.elapsed = 0;
115
+ ctx.active_sqlhash = true;
116
+ AsyncSender.send_packet(PacketTypeEnum.TX_DB_CONN, ctx, [dbc]);
117
+
118
+ // IORedis 명령 시작
119
+ var command_start_time = Date.now();
120
+ ctx.footprint(`IORedis ${normalizedCommand} Start`);
121
+
122
+ // IORedis에서는 command.args에서 쿼리 조합 (Python APM 방식 참고)
123
+ var queryParts = [normalizedCommand];
124
+ if (commandArgs && commandArgs.length > 0) {
125
+ // 각 인자를 문자열로 변환하고 20자로 제한
126
+ var argStrings = commandArgs.map(function(arg) {
127
+ var argStr = String(arg);
128
+ return argStr.length > 20 ? argStr.substring(0, 20) + '...' : argStr;
129
+ });
130
+ queryParts = queryParts.concat(argStrings);
131
+ }
132
+ var commandText = `Redis ` + queryParts.join(' ');
133
+
134
+ try {
135
+ var result = originalSendCommand.apply(self, arguments);
136
+
137
+ // IORedis는 항상 Promise를 반환
138
+ if (result && typeof result.then === 'function') {
139
+ return result.then(
140
+ function(res) {
141
+ var command_elapsed = Date.now() - command_start_time;
142
+ var resultCount = 0;
143
+
144
+ if (res !== undefined && res !== null) {
145
+ if (Array.isArray(res)) {
146
+ resultCount = res.length;
147
+ } else if (typeof res === 'string' || typeof res === 'number') {
148
+ resultCount = 1;
149
+ }
150
+ }
151
+
152
+ ctx.elapsed = command_elapsed;
153
+ ctx.active_sqlhash = false;
154
+ AsyncSender.send_packet(PacketTypeEnum.TX_SQL, ctx, [dbc, commandText, String(resultCount)]);
155
+ ctx.footprint(`IORedis ${normalizedCommand} Done`);
156
+ return res;
157
+ },
158
+ function(err) {
159
+ handleRedisError(ctx, err);
160
+ var command_elapsed = Date.now() - command_start_time;
161
+ ctx.elapsed = command_elapsed;
162
+ ctx.active_sqlhash = false;
163
+ AsyncSender.send_packet(PacketTypeEnum.TX_SQL, ctx, [dbc, commandText, '0']);
164
+ ctx.footprint(`IORedis ${normalizedCommand} Done`);
165
+ throw err;
166
+ }
167
+ );
168
+ } else {
169
+ // 예외적으로 Promise가 아닌 경우 처리
170
+ var command_elapsed = Date.now() - command_start_time;
171
+ var resultCount = 0;
172
+
173
+ if (result !== undefined && result !== null) {
174
+ if (Array.isArray(result)) {
175
+ resultCount = result.length;
176
+ } else if (typeof result === 'string' || typeof result === 'number') {
177
+ resultCount = 1;
178
+ }
179
+ }
180
+
181
+ ctx.elapsed = command_elapsed;
182
+ ctx.active_sqlhash = false;
183
+ AsyncSender.send_packet(PacketTypeEnum.TX_SQL, ctx, [dbc, commandText, String(resultCount)]);
184
+ ctx.footprint(`IORedis ${normalizedCommand} Done`);
185
+ return result;
186
+ }
187
+ } catch (commandError) {
188
+ handleRedisError(ctx, commandError);
189
+ var command_elapsed = Date.now() - command_start_time;
190
+ ctx.elapsed = command_elapsed;
191
+ ctx.active_sqlhash = false;
192
+ AsyncSender.send_packet(PacketTypeEnum.TX_SQL, ctx, [dbc, commandText, '0']);
193
+ ctx.footprint(`IORedis ${normalizedCommand} Done`);
194
+ throw commandError;
195
+ }
196
+ });
197
+ };
198
+
199
+ mod.prototype.sendCommand.__whatap_wrapped__ = true;
200
+ }
201
+
202
+ // IORedis 생성자도 후킹하여 연결 정보 수집
203
+ var originalConstructor = mod;
204
+ function WrappedIORedis() {
205
+ var args = Array.prototype.slice.call(arguments);
206
+ var ctx = TraceContextManager.getCurrentContext();
207
+
208
+ if (ctx) {
209
+ ctx.start_time = Date.now();
210
+ ctx.footprint('IORedis Client Creating');
211
+ ctx.db_opening = true;
212
+ }
213
+
214
+ // 원본 생성자 호출
215
+ var client = Object.create(originalConstructor.prototype);
216
+ originalConstructor.apply(client, args);
217
+
218
+ // 연결 옵션 파싱 및 DBC 정보 설정
219
+ var options = {};
220
+ if (args.length > 0) {
221
+ if (typeof args[0] === 'string') {
222
+ try {
223
+ var url = new URL(args[0]);
224
+ options = {
225
+ host: url.hostname,
226
+ port: parseInt(url.port) || 6379,
227
+ db: parseInt(url.pathname.slice(1)) || 0
228
+ };
229
+ } catch (e) {
230
+ options = { host: 'localhost', port: 6379, db: 0 };
231
+ }
232
+ } else if (typeof args[0] === 'number') {
233
+ options = {
234
+ host: args[1] || 'localhost',
235
+ port: args[0],
236
+ db: 0
237
+ };
238
+ } else if (typeof args[0] === 'object') {
239
+ options = args[0] || {};
240
+ if (!options.host) options.host = 'localhost';
241
+ if (!options.port) options.port = 6379;
242
+ if (options.db === undefined) options.db = 0;
243
+ }
244
+ } else {
245
+ options = { host: 'localhost', port: 6379, db: 0 };
246
+ }
247
+
248
+ setupDbcInfo(options);
249
+
250
+ if (ctx) {
251
+ ctx.elapsed = Date.now() - (ctx.start_time || Date.now());
252
+ ctx.footprint('IORedis Client Created');
253
+ if (ctx.db_opening !== undefined) {
254
+ ctx.db_opening = false;
255
+ }
256
+ }
257
+
258
+ return client;
259
+ }
260
+
261
+ // 프로토타입과 정적 속성 복사
262
+ WrappedIORedis.prototype = originalConstructor.prototype;
263
+ Object.setPrototypeOf(WrappedIORedis, originalConstructor);
264
+
265
+ Object.getOwnPropertyNames(originalConstructor).forEach(function(prop) {
266
+ if (prop !== 'prototype' && prop !== 'name' && prop !== 'length') {
267
+ try {
268
+ var descriptor = Object.getOwnPropertyDescriptor(originalConstructor, prop);
269
+ if (descriptor && descriptor.configurable !== false) {
270
+ Object.defineProperty(WrappedIORedis, prop, descriptor);
271
+ }
272
+ } catch (e) {
273
+ // 복사할 수 없는 속성은 건너뛰기
274
+ }
275
+ }
276
+ });
277
+
278
+ // 모듈 교체
279
+ Object.getOwnPropertyNames(WrappedIORedis).forEach(function(prop) {
280
+ if (prop !== 'prototype') {
281
+ try {
282
+ mod[prop] = WrappedIORedis[prop];
283
+ } catch (e) {
284
+ // 설정할 수 없는 속성은 건너뛰기
285
+ }
286
+ }
287
+ });
288
+
289
+ mod.__whatap_wrapped__ = true;
290
+ Logger.initPrint("IORedis sendCommand method successfully wrapped");
291
+ }
292
+ };
293
+
294
+ exports.IORedisObserver = IORedisObserver;