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.
Files changed (198) hide show
  1. package/README.md +33 -77
  2. package/lib/conf/conf-sys-mon.js +101 -0
  3. package/lib/conf/config-default.js +10 -3
  4. package/lib/conf/configure.js +369 -349
  5. package/lib/conf/license.js +1 -1
  6. package/lib/control/cmd-config.js +24 -0
  7. package/lib/control/control-handler.js +367 -0
  8. package/lib/control/packagectr-helper.js +34 -3
  9. package/lib/core/agent.js +176 -888
  10. package/lib/core/interceptor.js +6 -6
  11. package/lib/core/request-agent.js +27 -0
  12. package/lib/core/shimmer.js +82 -36
  13. package/lib/counter/counter-manager.js +79 -8
  14. package/lib/counter/meter/meter-activex.js +67 -0
  15. package/lib/counter/meter/meter-httpc.js +57 -0
  16. package/lib/counter/meter/meter-resource.js +9 -0
  17. package/lib/counter/meter/meter-service.js +168 -0
  18. package/lib/counter/meter/meter-socket.io.js +51 -0
  19. package/lib/counter/meter/meter-sql.js +71 -0
  20. package/lib/counter/meter/meter-users.js +58 -0
  21. package/lib/counter/meter.js +183 -0
  22. package/lib/counter/task/activetransaction.js +68 -17
  23. package/lib/counter/task/agentinfo.js +107 -0
  24. package/lib/{system → counter/task}/gc-action.js +27 -74
  25. package/lib/counter/task/gcstat.js +34 -0
  26. package/lib/counter/task/heapmem.js +25 -0
  27. package/lib/counter/task/httpc.js +76 -0
  28. package/lib/counter/task/metering-info.js +125 -0
  29. package/lib/counter/task/proc-cpu.js +29 -0
  30. package/lib/counter/task/realtimeuser.js +31 -0
  31. package/lib/counter/task/res/systemECSTask.js +39 -0
  32. package/lib/counter/task/res/systemKubeTask.js +53 -0
  33. package/lib/counter/task/res/util/awsEcsClientThread.js +218 -0
  34. package/lib/counter/task/res/util/linuxProcStatUtil.js +14 -0
  35. package/lib/counter/task/res-sys-cpu.js +62 -0
  36. package/lib/counter/task/service.js +202 -0
  37. package/lib/counter/task/socketio.js +30 -0
  38. package/lib/counter/task/sql.js +105 -0
  39. package/lib/counter/task/systemperf.js +43 -0
  40. package/lib/data/datapack-sender.js +289 -0
  41. package/lib/data/dataprofile-agent.js +162 -0
  42. package/lib/data/datatext-agent.js +135 -0
  43. package/lib/data/event-level.js +15 -0
  44. package/lib/data/test.js +49 -0
  45. package/lib/data/zipprofile.js +197 -0
  46. package/lib/env/constants.js +21 -0
  47. package/lib/error/error-handler.js +437 -0
  48. package/lib/io/data-inputx.js +13 -3
  49. package/lib/io/data-outputx.js +268 -206
  50. package/lib/kube/kube-client.js +144 -0
  51. package/lib/lang/text-types.js +58 -0
  52. package/lib/logger.js +6 -6
  53. package/lib/logsink/line-log-util.js +87 -0
  54. package/lib/logsink/line-log.js +12 -0
  55. package/lib/logsink/log-sender.js +78 -0
  56. package/lib/logsink/log-tracer.js +40 -0
  57. package/lib/logsink/sender-util.js +56 -0
  58. package/lib/logsink/zip/zip-send.js +177 -0
  59. package/lib/net/netflag.js +55 -0
  60. package/lib/net/receiver.js +66 -0
  61. package/lib/net/security-master.js +139 -20
  62. package/lib/net/sender.js +141 -0
  63. package/lib/net/tcp-return.js +18 -0
  64. package/lib/net/tcp-session.js +286 -0
  65. package/lib/net/tcpreq-client-proxy.js +70 -0
  66. package/lib/net/tcprequest-mgr.js +58 -0
  67. package/lib/observers/apollo-server-observer.js +33 -27
  68. package/lib/observers/cluster-observer.js +22 -0
  69. package/lib/observers/express-observer.js +215 -0
  70. package/lib/observers/file-observer.js +184 -0
  71. package/lib/observers/global-observer.js +155 -80
  72. package/lib/observers/grpc-observer.js +336 -0
  73. package/lib/observers/http-observer.js +666 -236
  74. package/lib/observers/maria-observer.js +204 -362
  75. package/lib/observers/memcached-observer.js +56 -0
  76. package/lib/observers/mongo-observer.js +317 -0
  77. package/lib/observers/mongodb-observer.js +169 -226
  78. package/lib/observers/mongoose-observer.js +518 -323
  79. package/lib/observers/mssql-observer.js +177 -418
  80. package/lib/observers/mysql-observer.js +342 -449
  81. package/lib/observers/mysql2-observer.js +396 -358
  82. package/lib/observers/net-observer.js +77 -0
  83. package/lib/observers/oracle-observer.js +559 -384
  84. package/lib/observers/pgsql-observer.js +231 -489
  85. package/lib/observers/prisma-observer.js +303 -92
  86. package/lib/observers/process-observer.js +79 -35
  87. package/lib/observers/promise-observer.js +31 -0
  88. package/lib/observers/redis-observer.js +166 -331
  89. package/lib/observers/schedule-observer.js +67 -0
  90. package/lib/observers/socket.io-observer.js +226 -187
  91. package/lib/observers/stream-observer.js +19 -0
  92. package/lib/observers/thrift-observer.js +197 -0
  93. package/lib/observers/websocket-observer.js +175 -301
  94. package/lib/pack/activestack-pack.js +55 -0
  95. package/lib/pack/apenum.js +8 -0
  96. package/lib/pack/counter-pack.js +3 -0
  97. package/lib/pack/errorsnap-pack.js +69 -0
  98. package/lib/pack/event-pack.js +54 -0
  99. package/lib/pack/hitmap-pack.js +63 -0
  100. package/lib/pack/hitmap-pack1.js +152 -0
  101. package/lib/pack/log-sink-pack.js +14 -52
  102. package/lib/pack/netstat.js +15 -0
  103. package/lib/pack/otype.js +7 -0
  104. package/lib/pack/profile-pack.js +49 -0
  105. package/lib/pack/realtimeuser-pack.js +41 -0
  106. package/lib/pack/stat-general-pack.js +96 -0
  107. package/lib/pack/staterror-pack.js +120 -0
  108. package/lib/pack/stathttpc-pack.js +66 -0
  109. package/lib/pack/stathttpc-rec.js +78 -0
  110. package/lib/pack/statremote-pack.js +46 -0
  111. package/lib/pack/statservice-pack.js +63 -0
  112. package/lib/pack/statservice-pack1.js +88 -0
  113. package/lib/pack/statservice-rec.js +292 -0
  114. package/lib/pack/statservice-rec_dep.js +151 -0
  115. package/lib/pack/statsql-pack.js +69 -0
  116. package/lib/pack/statsql-rec.js +100 -0
  117. package/lib/pack/statuseragent-pack.js +44 -0
  118. package/lib/pack/tagcount-pack.js +4 -4
  119. package/lib/pack/tagctr.js +15 -0
  120. package/lib/pack/text-pack.js +50 -0
  121. package/lib/pack/time-count.js +25 -0
  122. package/lib/pack/websocket.js +15 -0
  123. package/lib/pack/zip-pack.js +70 -0
  124. package/lib/pii/pii-item.js +31 -0
  125. package/lib/pii/pii-mask.js +174 -0
  126. package/lib/plugin/plugin-loadermanager.js +57 -0
  127. package/lib/plugin/plugin.js +75 -0
  128. package/lib/service/tx-record.js +332 -0
  129. package/lib/stat/stat-error.js +116 -0
  130. package/lib/stat/stat-httpc.js +98 -0
  131. package/lib/stat/stat-remote-ip.js +46 -0
  132. package/lib/stat/stat-remote-ipurl.js +88 -0
  133. package/lib/stat/stat-sql.js +113 -0
  134. package/lib/stat/stat-tranx.js +58 -0
  135. package/lib/stat/stat-tx-caller.js +160 -0
  136. package/lib/stat/stat-tx-domain.js +111 -0
  137. package/lib/stat/stat-tx-referer.js +112 -0
  138. package/lib/stat/stat-useragent.js +48 -0
  139. package/lib/stat/timingsender.js +76 -0
  140. package/lib/step/activestack-step.js +38 -0
  141. package/lib/step/dbc-step.js +36 -0
  142. package/lib/step/http-stepx.js +67 -0
  143. package/lib/step/message-step.js +40 -0
  144. package/lib/step/method-stepx.js +45 -0
  145. package/lib/step/resultset-step.js +40 -0
  146. package/lib/step/securemsg-step.js +44 -0
  147. package/lib/step/socket-step.js +46 -0
  148. package/lib/step/sql-stepx.js +68 -0
  149. package/lib/step/sqlxtype.js +16 -0
  150. package/lib/step/step.js +66 -0
  151. package/lib/step/stepenum.js +54 -0
  152. package/lib/topology/link.js +63 -0
  153. package/lib/topology/nodeinfo.js +123 -0
  154. package/lib/topology/status-detector.js +111 -0
  155. package/lib/trace/trace-context-manager.js +113 -25
  156. package/lib/trace/trace-context.js +21 -7
  157. package/lib/trace/trace-httpc.js +17 -11
  158. package/lib/trace/trace-sql.js +29 -21
  159. package/lib/util/anylist.js +103 -0
  160. package/lib/util/cardinality/hyperloglog.js +106 -0
  161. package/lib/util/cardinality/murmurhash.js +31 -0
  162. package/lib/util/cardinality/registerset.js +75 -0
  163. package/lib/util/errordata.js +21 -0
  164. package/lib/util/escape-literal-sql.js +5 -5
  165. package/lib/util/hashutil.js +18 -18
  166. package/lib/util/iputil_x.js +527 -0
  167. package/lib/util/keygen.js +0 -3
  168. package/lib/util/kube-util.js +73 -0
  169. package/lib/util/linkedset.js +1 -2
  170. package/lib/util/nodeutil.js +2 -1
  171. package/lib/util/paramsecurity.js +80 -0
  172. package/lib/util/pre-process.js +13 -0
  173. package/lib/util/process-seq.js +166 -0
  174. package/lib/util/property-util.js +36 -0
  175. package/lib/util/request-queue.js +70 -0
  176. package/lib/util/requestdouble-queue.js +72 -0
  177. package/lib/util/resourceprofile.js +157 -0
  178. package/lib/util/stop-watch.js +30 -0
  179. package/lib/util/system-util.js +10 -0
  180. package/lib/util/userid-util.js +57 -0
  181. package/lib/value/map-value.js +3 -2
  182. package/package.json +9 -5
  183. package/whatap.conf +1 -4
  184. package/agent/darwin/arm64/whatap_nodejs +0 -0
  185. package/agent/linux/amd64/whatap_nodejs +0 -0
  186. package/agent/linux/arm64/whatap_nodejs +0 -0
  187. package/build.txt +0 -4
  188. package/lib/observers/ioredis-observer.js +0 -294
  189. package/lib/udp/async_sender.js +0 -119
  190. package/lib/udp/index.js +0 -17
  191. package/lib/udp/packet_enum.js +0 -52
  192. package/lib/udp/packet_queue.js +0 -69
  193. package/lib/udp/packet_type_enum.js +0 -33
  194. package/lib/udp/param_def.js +0 -72
  195. package/lib/udp/udp_session.js +0 -336
  196. package/lib/util/sql-util.js +0 -178
  197. package/lib/util/trace-helper.js +0 -91
  198. package/lib/util/transfer.js +0 -58
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Copyright 2016 the WHATAP project authors. All rights reserved.
3
+ * Use of this source code is governed by a license that
4
+ * can be found in the LICENSE file.
5
+ */
6
+
7
+ var conf = require('../conf/configure'),
8
+ secuMaster = require('../net/security-master'),
9
+ TcpRequestMgr = require('../net/tcprequest-mgr'),
10
+ DateUtil = require('./../util/dateutil'),
11
+ RequestQueue = require('../util/request-queue'),
12
+ DataPackSender = require('../data/datapack-sender'),
13
+ DataOutputX = require('../io/data-outputx'),
14
+ ZipPack = require('../pack/zip-pack'),
15
+ DataPackSender = require('../data/datapack-sender'),
16
+ Logger = require('../logger');
17
+
18
+ const zlib = require('zlib');
19
+
20
+ var profile_zip_enabled = conf.getProperty('profile_zip_enabled', false);
21
+ var profile_zip_max_buffer_size = conf.getProperty('profile_zip_max_buffer_size', 1024*1024);
22
+ var profile_zip_min_size = conf.getProperty('profile_zip_min_size', 100)
23
+ var profile_zip_queue_size = conf.getProperty('profile_zip_queue_size', 500);
24
+ var profile_zip_max_wait_time = conf.getProperty('profile_zip_max_wait_time', 1000);
25
+ var net_send_max_bytes = conf.getProperty('net_send_max_bytes', 5 * 1024 * 1024);
26
+ var debug_profile_zip_enabled = conf.getProperty('debug_profile_zip_enabled', false);
27
+ var debug_profile_zip_interval = conf.getProperty('debug_profile_zip_interval', 5000);
28
+ conf.on('profile_zip_enabled', function(newProperty) {
29
+ profile_zip_enabled = newProperty;
30
+ if (profile_zip_enabled) {
31
+ ZipProfile.getInstance().startProcessQueue();
32
+ } else {
33
+ ZipProfile.getInstance().stopProcessQueue();
34
+ ZipProfile.resetInstance();
35
+ }
36
+ });
37
+
38
+ class ZipProfile {
39
+ constructor() {
40
+ if (ZipProfile.instance) {
41
+ return ZipProfile.instance;
42
+ }
43
+ this.queue = new RequestQueue(profile_zip_queue_size);
44
+ this.no_zip_sent = 0;
45
+ this.zip_sent = 0;
46
+ this.last_log = null;
47
+ this.buffer = Buffer.alloc(0);
48
+ this.packCount = 0;
49
+ this.first_time = null;
50
+ this.isProcessing = false;
51
+ ZipProfile.instance = this;
52
+
53
+ if (profile_zip_enabled) {
54
+ this.startProcessQueue();
55
+ }
56
+ }
57
+
58
+ static getInstance() {
59
+ if (!ZipProfile.instance) {
60
+ ZipProfile.instance = new ZipProfile();
61
+ }
62
+ return ZipProfile.instance;
63
+ }
64
+
65
+ static resetInstance() {
66
+ if(ZipProfile.instance){
67
+ ZipProfile.instance = null;
68
+ }
69
+ }
70
+
71
+ add(p){
72
+ var ok = this.queue.put(p);
73
+ if(!ok){
74
+ DataPackSender.sendPack(p);
75
+ this.no_zip_sent++;
76
+ }
77
+ }
78
+
79
+ async processQueue() {
80
+ this.isProcessing = true;
81
+ while (this.isProcessing) {
82
+ if(!profile_zip_enabled) { break; }
83
+
84
+ const p = await this.queue.getByTimeout(profile_zip_max_wait_time);
85
+ if(p) {
86
+ await this.append(p);
87
+ }else{
88
+ await this.sendAndClear();
89
+ }
90
+ await new Promise(resolve => setTimeout(resolve, 100));
91
+ }
92
+ }
93
+
94
+ async append(p) {
95
+ var b = DataOutputX.toBytesPack(p);
96
+ if(b.length >= net_send_max_bytes){ return; }
97
+
98
+ this.buffer = Buffer.concat([this.buffer, b]);
99
+ this.packCount++;
100
+
101
+ if(!this.first_time){
102
+ this.first_time = p.time;
103
+ if(this.buffer.length >= profile_zip_max_buffer_size){
104
+ await this.sendAndClear();
105
+ }
106
+ }else{
107
+ if(this.buffer.length >= profile_zip_max_buffer_size || (p.time - this.first_time) >= conf.getProperty('profile_zip_max_wait_time', 5000)){
108
+ await this.sendAndClear();
109
+ }
110
+ }
111
+ }
112
+
113
+ async sendAndClear() {
114
+ if(this.buffer.length === 0){ return; }
115
+
116
+ var p = new ZipPack();
117
+ p.time = DateUtil.currentTime();
118
+ p.recordCount = this.packCount;
119
+ p.records = this.buffer;
120
+
121
+ await this.doZip(p);
122
+ if(debug_profile_zip_enabled){
123
+ if(debug_profile_zip_interval){
124
+ Logger.print('WHATAP-ZIP-DEBUG', `PROFILE status=${p.status} records=${p.recordCount} | ${this.buffer.length} => ${p.records.length} queue=${this.queue.size()}`, false)
125
+ } else {
126
+ this.zip_sent++;
127
+ var now = Date.now();
128
+ if(now > (this.last_log + debug_profile_zip_interval)){
129
+ this.last_log = now;
130
+ this.log(p);
131
+ this.zip_sent = 0;
132
+ }
133
+ }
134
+ }
135
+
136
+ p.pcode = secuMaster.PCODE;
137
+ p.oid = secuMaster.OID;
138
+ p.okind = conf.OKIND;
139
+ p.onode = conf.ONODE;
140
+
141
+ TcpRequestMgr.addProfile(0, p);
142
+
143
+ this.buffer = Buffer.alloc(0);
144
+ this.first_time = 0;
145
+ this.packCount = 0;
146
+ }
147
+
148
+ log(p){
149
+ try{
150
+ var sb = `PROFILE `;
151
+ sb += `zip_sent=${this.zip_sent}`;
152
+ sb += ` records=${p.records}`;
153
+ sb += ` | =${this.buffer.length} => ${p.records.length}`;
154
+ sb += ` queue=${this.queue.size()}`;
155
+ if (this.no_zip_sent > 0) {
156
+ sb += ` no_zip_sent=${this.no_zip_sent}`;
157
+ }
158
+ Logger.print('WHATAP-ZIP-DEBUG', sb, false);
159
+ }catch (e) {
160
+ }
161
+ }
162
+
163
+ async doZip(p){
164
+ if(p.status !== 0){ return; }
165
+ if(p.records.length < profile_zip_min_size){ return; }
166
+ p.status = 1;
167
+
168
+ try{
169
+ p.records = await this._doZip(p.records);
170
+ }catch (e) {
171
+ Logger.print('WHATAP-ZIP-ERROR', 'Error occurred during compression.', false);
172
+ }
173
+ }
174
+
175
+ _doZip(data) {
176
+ return new Promise((resolve, reject) => {
177
+ zlib.gzip(data, (err, buffer) => {
178
+ if (err) {
179
+ reject(err);
180
+ } else {
181
+ resolve(buffer);
182
+ }
183
+ });
184
+ });
185
+ }
186
+
187
+ startProcessQueue() {
188
+ if (!this.isProcessing) {
189
+ this.processQueue()
190
+ }
191
+ }
192
+ stopProcessQueue() {
193
+ this.isProcessing = false;
194
+ }
195
+ }
196
+
197
+ module.exports = ZipProfile;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Copyright 2016 the WHATAP project authors. All rights reserved.
3
+ * Use of this source code is governed by a license that
4
+ * can be found in the LICENSE file.
5
+ */
6
+
7
+ var numType = {
8
+ INT8_MIN : -128,
9
+ INT8_MAX : 127,
10
+ INT16_MIN : -32768,
11
+ INT16_MAX : 32767,
12
+ INT24_MIN : -8388608,
13
+ INT24_MAX : 8388607,
14
+ INT32_MIN : -2147483648,
15
+ INT32_MAX : 2147483647,
16
+ INT40_MIN : -549755813888,
17
+ INT40_MAX : 549755813887,
18
+ INT64_MIN : -4503599627370496,
19
+ INT64_MAX : 4503599627370495
20
+ };
21
+ module.exports.numType = numType;
@@ -0,0 +1,437 @@
1
+ /**
2
+ * 메시지/알림 오류 처리
3
+ * @param {Object} ctx - Trace Context
4
+ * @param {Object} step - Message Step
5
+ * @param {Error} error - 오류 객체
6
+ */
7
+ function handleMessageError(ctx, step, error) {
8
+ setCommonErrorInfo(ctx, step, error, {
9
+ prefix: 'msg-',
10
+ textType: TextTypes.MESSAGE,
11
+ defaultMessage: 'Message processing error',
12
+ includeStack: false,
13
+ logPrefix: 'MESSAGE-ERROR'
14
+ });
15
+ }
16
+
17
+ /**
18
+ * 오류 정보를 Context에만 설정 (StatError 생성 없이)
19
+ * @param {Object} ctx - Trace Context
20
+ * @param {Error} error - 오류 객체
21
+ * @param {string} prefix - 오류 접두사
22
+ */
23
+ function setContextErrorOnly(ctx, error, prefix = '') {
24
+ if (!ctx || !error) return;
25
+
26
+ try {
27
+ // 오류 클래스 정보 설정
28
+ ctx.error_class = error.name || (error.constructor && error.constructor.name) || 'UnknownError';
29
+
30
+ // 오류 메시지 설정
31
+ ctx.error_message = error.message || error.stack || 'Unknown error';
32
+
33
+ // 상태 코드 설정 (있는 경우)
34
+ if (error.status || error.statusCode || error.code) {
35
+ ctx.statusCode = error.status || error.statusCode || error.code;
36
+ }
37
+
38
+ } catch (e) {
39
+ Logger.printError(
40
+ 'WHATAP-CONTEXT-ERROR',
41
+ 'Error setting context error info',
42
+ e,
43
+ false
44
+ );
45
+ }
46
+ }/**
47
+ * Step 타입에 따라 TextType 자동 추론
48
+ * @param {Object} step - Step 객체
49
+ * @returns {number} - TextTypes 상수
50
+ */
51
+ function inferTextTypeFromStep(step) {
52
+ if (!step) return TextTypes.MESSAGE;
53
+
54
+ // Step 클래스명 또는 타입으로 판단
55
+ const stepName = step.constructor?.name || '';
56
+
57
+ if (stepName.includes('Http') || step.url !== undefined) {
58
+ return TextTypes.HTTPC_URL;
59
+ }
60
+ if (stepName.includes('Socket') || stepName.includes('Websocket')) {
61
+ return TextTypes.MESSAGE;
62
+ }
63
+ if (stepName.includes('Message') || step.desc !== undefined) {
64
+ return TextTypes.MESSAGE;
65
+ }
66
+ if (stepName.includes('Sql') || step.hash !== undefined) {
67
+ return TextTypes.SQL;
68
+ }
69
+
70
+ // 기본값
71
+ return TextTypes.MESSAGE;
72
+ }/**
73
+ * 공통 오류 처리 유틸리티
74
+ * 모든 Observer에서 사용할 수 있는 통합 오류 처리 함수들
75
+ */
76
+
77
+ const StatError = require('../stat/stat-error');
78
+ const TextTypes = require('../lang/text-types');
79
+ const Logger = require('../logger');
80
+ const conf = require('../conf/configure');
81
+
82
+ /**
83
+ * 공통 오류 정보 설정 함수 (범용)
84
+ * @param {Object} ctx - Trace Context
85
+ * @param {Object} step - Step 객체 (SQL, HTTP, Message 등)
86
+ * @param {Error} error - 오류 객체
87
+ * @param {Object} options - 추가 옵션
88
+ * @param {string} options.prefix - 오류 코드 접두사 (예: 'mysql-', 'httpc-', 'redis-')
89
+ * @param {number} options.textType - TextTypes 상수 (기본값: null, step 타입에 따라 자동 결정)
90
+ * @param {boolean} options.includeStack - 스택 트레이스 포함 여부 (기본값: true)
91
+ * @param {string} options.defaultMessage - 기본 오류 메시지
92
+ * @param {boolean} options.setStatError - StatError 생성 여부 (기본값: true)
93
+ * @param {string} options.logPrefix - 로그 접두사 (기본값: 'COMMON-ERROR')
94
+ */
95
+ function setCommonErrorInfo(ctx, step, error, options = {}) {
96
+ if (!ctx || !error) {
97
+ return;
98
+ }
99
+
100
+ const {
101
+ prefix = '',
102
+ textType = null,
103
+ includeStack = true,
104
+ defaultMessage = 'Error',
105
+ setStatError = true,
106
+ logPrefix = 'COMMON-ERROR'
107
+ } = options;
108
+
109
+ try {
110
+ // 오류 클래스 정보 설정
111
+ const errorClass = error.name || (error.constructor && error.constructor.name) || 'UnknownError';
112
+ ctx.error_class = errorClass;
113
+
114
+ // 오류 코드 생성
115
+ const errorCode = error.code || error.errno || error.errorNum || 'UNKNOWN';
116
+ const fullErrorCode = prefix ? `${prefix}${errorCode}` : errorCode;
117
+
118
+ // 오류 메시지 설정
119
+ const errorMessage = error.message || error.sqlMessage || defaultMessage;
120
+
121
+ // 스택 트레이스 처리
122
+ if (includeStack && conf.trace_sql_error_stack && conf.trace_sql_error_depth && error.stack) {
123
+ const traceDepth = conf.trace_sql_error_depth;
124
+ const errorStack = error.stack.split("\n");
125
+
126
+ if (errorStack.length > traceDepth) {
127
+ ctx.error_message = errorStack.slice(0, traceDepth + 1).join("\n");
128
+ } else {
129
+ ctx.error_message = error.stack;
130
+ }
131
+ } else {
132
+ ctx.error_message = errorMessage;
133
+ }
134
+
135
+ // StatError 생성 (step이 있고 설정이 활성화된 경우)
136
+ if (step && setStatError) {
137
+ const shouldAddError = shouldIgnoreError(errorCode, errorMessage);
138
+
139
+ if (shouldAddError) {
140
+ // textType이 null이면 step 타입에 따라 자동 결정
141
+ const finalTextType = textType || inferTextTypeFromStep(step);
142
+
143
+ step.error = StatError.addError(
144
+ fullErrorCode,
145
+ errorMessage,
146
+ ctx.service_hash,
147
+ finalTextType,
148
+ step.hash || step.url || null
149
+ );
150
+
151
+ // Context 오류가 아직 설정되지 않았다면 설정
152
+ if (ctx.error && ctx.error.isZero && ctx.error.isZero()) {
153
+ ctx.error = step.error;
154
+ }
155
+ }
156
+ }
157
+
158
+ Logger.printError(
159
+ `WHATAP-${logPrefix.toUpperCase()}`,
160
+ `${prefix || 'SYSTEM'} Error: ${fullErrorCode} - ${errorMessage}`,
161
+ error,
162
+ false
163
+ );
164
+
165
+ } catch (e) {
166
+ Logger.printError(
167
+ 'WHATAP-ERROR-HANDLER',
168
+ 'Error in common error handler',
169
+ e,
170
+ false
171
+ );
172
+ }
173
+ }
174
+
175
+ /**
176
+ * 오류 무시 여부 확인
177
+ * @param {string} errorCode - 오류 코드
178
+ * @param {string} errorMessage - 오류 메시지
179
+ * @returns {boolean} - 오류를 처리할지 여부
180
+ */
181
+ function shouldIgnoreError(errorCode, errorMessage) {
182
+ try {
183
+ // 오류 클래스 무시 설정 확인
184
+ if (conf._is_trace_ignore_err_cls_contains === true &&
185
+ conf.trace_ignore_err_cls_contains &&
186
+ errorCode &&
187
+ errorCode.indexOf(conf.trace_ignore_err_cls_contains) >= 0) {
188
+ return false;
189
+ }
190
+
191
+ // 오류 메시지 무시 설정 확인
192
+ if (conf._is_trace_ignore_err_msg_contains === true &&
193
+ conf.trace_ignore_err_msg_contains &&
194
+ errorMessage &&
195
+ errorMessage.indexOf(conf.trace_ignore_err_msg_contains) >= 0) {
196
+ return false;
197
+ }
198
+
199
+ // 기본적으로 오류 처리
200
+ return true;
201
+ } catch (e) {
202
+ Logger.printError(
203
+ 'WHATAP-ERROR-IGNORE-CHECK',
204
+ 'Error checking ignore conditions',
205
+ e,
206
+ false
207
+ );
208
+ return true;
209
+ }
210
+ }
211
+
212
+ /**
213
+ * MySQL 전용 오류 처리
214
+ * @param {Object} ctx - Trace Context
215
+ * @param {Object} step - SQL Step
216
+ * @param {Error} error - MySQL 오류 객체
217
+ */
218
+ function handleMysqlError(ctx, step, error) {
219
+ setCommonErrorInfo(ctx, step, error, {
220
+ prefix: 'mysql-',
221
+ textType: TextTypes.SQL,
222
+ defaultMessage: 'mysql error'
223
+ });
224
+ }
225
+
226
+ /**
227
+ * PostgreSQL 전용 오류 처리
228
+ * @param {Object} ctx - Trace Context
229
+ * @param {Object} step - SQL Step
230
+ * @param {Error} error - PostgreSQL 오류 객체
231
+ */
232
+ function handlePgsqlError(ctx, step, error) {
233
+ setCommonErrorInfo(ctx, step, error, {
234
+ prefix: 'pgsql-',
235
+ textType: TextTypes.SQL,
236
+ defaultMessage: 'postgresql error'
237
+ });
238
+ }
239
+
240
+ /**
241
+ * Oracle 전용 오류 처리
242
+ * @param {Object} ctx - Trace Context
243
+ * @param {Object} step - SQL Step
244
+ * @param {Error} error - Oracle 오류 객체
245
+ */
246
+ function handleOracleError(ctx, step, error) {
247
+ setCommonErrorInfo(ctx, step, error, {
248
+ prefix: 'oracle-',
249
+ textType: TextTypes.SQL,
250
+ defaultMessage: 'Oracle error'
251
+ });
252
+ }
253
+
254
+ /**
255
+ * MongoDB 전용 오류 처리
256
+ * @param {Object} ctx - Trace Context
257
+ * @param {Object} step - SQL Step
258
+ * @param {Error} error - MongoDB 오류 객체
259
+ */
260
+ function handleMongoError(ctx, step, error) {
261
+ setCommonErrorInfo(ctx, step, error, {
262
+ prefix: 'mongodb-',
263
+ textType: TextTypes.SQL,
264
+ defaultMessage: 'MongoDB error'
265
+ });
266
+ }
267
+
268
+ /**
269
+ * Redis 전용 오류 처리
270
+ * @param {Object} ctx - Trace Context
271
+ * @param {Object} step - SQL Step
272
+ * @param {Error} error - Redis 오류 객체
273
+ */
274
+ function handleRedisError(ctx, step, error) {
275
+ setCommonErrorInfo(ctx, step, error, {
276
+ prefix: 'redis-',
277
+ textType: TextTypes.SQL,
278
+ defaultMessage: 'Redis error'
279
+ });
280
+ }
281
+
282
+ /**
283
+ * HTTP 클라이언트 오류 처리
284
+ * @param {Object} ctx - Trace Context
285
+ * @param {Object} step - HTTP Step
286
+ * @param {Error} error - HTTP 오류 객체
287
+ */
288
+ function handleHttpcError(ctx, step, error) {
289
+ setCommonErrorInfo(ctx, step, error, {
290
+ prefix: 'httpc-',
291
+ textType: TextTypes.HTTPC_URL,
292
+ defaultMessage: 'HTTP client error',
293
+ includeStack: false,
294
+ logPrefix: 'HTTPC-ERROR'
295
+ });
296
+ }
297
+
298
+ /**
299
+ * 일반적인 시스템 오류 처리
300
+ * @param {Object} ctx - Trace Context
301
+ * @param {Object} step - Step 객체 (선택사항)
302
+ * @param {Error} error - 오류 객체
303
+ * @param {string} prefix - 오류 접두사
304
+ */
305
+ function handleSystemError(ctx, step, error, prefix = 'system') {
306
+ setCommonErrorInfo(ctx, step, error, {
307
+ prefix: `${prefix}-`,
308
+ textType: null, // 자동 추론
309
+ defaultMessage: 'System error',
310
+ includeStack: true,
311
+ logPrefix: 'SYSTEM-ERROR'
312
+ });
313
+ }
314
+
315
+ /**
316
+ * gRPC 전용 오류 처리
317
+ * @param {Object} ctx - Trace Context
318
+ * @param {Object} step - gRPC Step (MessageStep)
319
+ * @param {Error} error - gRPC 오류 객체
320
+ */
321
+ function handleGrpcError(ctx, step, error) {
322
+ setCommonErrorInfo(ctx, step, error, {
323
+ prefix: 'grpc-',
324
+ textType: TextTypes.MESSAGE,
325
+ defaultMessage: 'gRPC error',
326
+ includeStack: true,
327
+ logPrefix: 'GRPC-ERROR'
328
+ });
329
+ }
330
+
331
+ /**
332
+ * WebSocket 전용 오류 처리
333
+ * @param {Object} ctx - Trace Context
334
+ * @param {Object} step - WebSocket Step (SocketStep)
335
+ * @param {Error} error - WebSocket 오류 객체
336
+ */
337
+ function handleWebsocketError(ctx, step, error) {
338
+ setCommonErrorInfo(ctx, step, error, {
339
+ prefix: 'websocket-',
340
+ textType: TextTypes.MESSAGE,
341
+ defaultMessage: 'WebSocket error',
342
+ includeStack: false,
343
+ logPrefix: 'WEBSOCKET-ERROR'
344
+ });
345
+ }
346
+
347
+ /**
348
+ * Socket.IO 전용 오류 처리
349
+ * @param {Object} ctx - Trace Context
350
+ * @param {Object} step - Socket.IO Step (SocketStep)
351
+ * @param {Error} error - Socket.IO 오류 객체
352
+ */
353
+ function handleSocketIOError(ctx, step, error) {
354
+ setCommonErrorInfo(ctx, step, error, {
355
+ prefix: 'socketio-',
356
+ textType: TextTypes.MESSAGE,
357
+ defaultMessage: 'Socket.IO error',
358
+ includeStack: false,
359
+ logPrefix: 'SOCKETIO-ERROR'
360
+ });
361
+ }
362
+
363
+ /**
364
+ * Global Fetch API 오류 처리
365
+ * @param {Object} ctx - Trace Context
366
+ * @param {Object} step - HTTP Step (HttpStepX)
367
+ * @param {Error|Response} error - Fetch 오류 객체 또는 Response 객체
368
+ */
369
+ function handleFetchError(ctx, step, error) {
370
+ // Response 객체인 경우와 Error 객체인 경우 구분
371
+ const isResponse = error && typeof error.status === 'number';
372
+
373
+ setCommonErrorInfo(ctx, step, error, {
374
+ prefix: 'fetch-',
375
+ textType: TextTypes.HTTPC_URL,
376
+ defaultMessage: isResponse ? 'Fetch HTTP error' : 'Fetch network error',
377
+ includeStack: !isResponse, // Response 객체는 스택 없음
378
+ logPrefix: 'FETCH-ERROR'
379
+ });
380
+ }
381
+
382
+ /**
383
+ * Process 관련 오류 처리 (stdout/stderr)
384
+ * @param {Object} ctx - Trace Context
385
+ * @param {Object} step - Process Step
386
+ * @param {Error} error - Process 오류 객체
387
+ */
388
+ function handleProcessError(ctx, step, error) {
389
+ setCommonErrorInfo(ctx, step, error, {
390
+ prefix: 'process-',
391
+ textType: TextTypes.MESSAGE,
392
+ defaultMessage: 'Process error',
393
+ includeStack: true,
394
+ logPrefix: 'PROCESS-ERROR'
395
+ });
396
+ }
397
+
398
+ /**
399
+ * Prisma 전용 오류 처리
400
+ * @param {Object} ctx - Trace Context
401
+ * @param {Object} step - SQL Step
402
+ * @param {Error} error - Prisma 오류 객체
403
+ */
404
+ function handlePrismaError(ctx, step, error) {
405
+ setCommonErrorInfo(ctx, step, error, {
406
+ prefix: 'prisma-',
407
+ textType: TextTypes.SQL,
408
+ defaultMessage: 'Prisma error'
409
+ });
410
+ }
411
+
412
+ module.exports = {
413
+ setCommonErrorInfo,
414
+ shouldIgnoreError,
415
+ inferTextTypeFromStep,
416
+ setContextErrorOnly,
417
+
418
+ // 데이터베이스 관련
419
+ handleMysqlError,
420
+ handlePgsqlError,
421
+ handleOracleError,
422
+ handleMongoError,
423
+ handleRedisError,
424
+ handlePrismaError,
425
+
426
+ // 네트워크/통신 관련
427
+ handleHttpcError,
428
+ handleFetchError,
429
+ handleGrpcError,
430
+ handleWebsocketError,
431
+ handleSocketIOError,
432
+
433
+ // 시스템 관련
434
+ handleSystemError,
435
+ handleProcessError,
436
+ handleMessageError
437
+ };
@@ -4,7 +4,17 @@
4
4
  * can be found in the LICENSE file.
5
5
  */
6
6
 
7
- var ValueEnum = require('../value/valueenum'),
7
+ var constants = require('../env/constants'),
8
+ ValueEnum = require('../value/valueenum'),
9
+ CounterPack = require('../pack/counter-pack'),
10
+ ActiveStackPack = require('../pack/activestack-pack'),
11
+ TextPack = require('../pack/text-pack').TextPack,
12
+ StatHttpcPack = require('../pack/stathttpc-pack').StatHttpcPack,
13
+ StatErrorPack = require('../pack/staterror-pack').StatErrorPack,
14
+ ParamPack = require('../pack/param-pack').ParamPack,
15
+ ErrorSnapPack1 = require('../pack/errorsnap-pack').ErrorSnapPack1,
16
+ EventPack = require('../pack/event-pack').Instance,
17
+ HitMapPack1 = require('../pack/hitmap-pack1'),
8
18
  PackEnum = require('../pack/packenum'),
9
19
  Long = require('long');
10
20
 
@@ -121,7 +131,7 @@ DataInputX.prototype.readByte = function() {
121
131
  DataInputX.prototype.readIntBytes = function(max) {
122
132
  var len = this.readInt32BE();
123
133
  if(len < 0 || len > max){
124
- Logger.printError('WHATAP-501', "read byte is overflowed max:" + max + " len:" + len, new Error());
134
+ Logger.printError('WHATAP-210', "read byte is overflowed max:" + max + " len:" + len, new Error());
125
135
  }
126
136
  return this.read(len);
127
137
  };
@@ -228,7 +238,7 @@ DataInputX.prototype.readPack = function () {
228
238
  }
229
239
  return null;
230
240
  } catch (e) {
231
- require('../logger').printError('WHATAP-502', "DataInputX (readPack)", e , false);
241
+ require('../logger').printError('WHATAP-211', "DataInputX (readPack)", e , false);
232
242
  return null;
233
243
  }
234
244
  };