whatap 0.4.94 → 0.4.96

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.
@@ -64,6 +64,14 @@ var ConfigDefault = {
64
64
  "profile_http_parameter_url_prefix": "/",
65
65
  "profile_http_header_url_prefix": "/",
66
66
  "profile_connection_open_enabled": true,
67
+ "profile_zip_enabled": bool('profile_zip_enabled', false),
68
+ "profile_zip_queue_size": num('profile_zip_queue_size', 500),
69
+ "profile_zip_max_buffer_size": num('profile_zip_max_buffer_size', 1024*1024),
70
+ "profile_zip_min_size": num('profile_zip_min_size', 100),
71
+ "debug_profile_zip_enabled": bool('debug_profile_zip_enabled', false),
72
+ "debug_profile_zip_interval": num('debug_profile_zip_interval', 5000),
73
+ "profile_zip_max_wait_time": num('profile_zip_max_wait_time', 1000),
74
+ "profile_zip_max_wait2_time": num('profile_zip_max_wait2_time', 5000),
67
75
 
68
76
  "hook_method_patterns": str('hook_method_patterns',""),
69
77
  "hook_method_access_public_enabled": true,
@@ -99,7 +107,7 @@ var ConfigDefault = {
99
107
  "trace_sql_error_depth": num('trace_sql_error_depth', 50),
100
108
  "transaction_status_error_enable": bool("transaction_status_error_enable", true),
101
109
 
102
- "trace_sampling_enabled": bool("trace_sampling_enabled", false),
110
+ "trace_sampling_enabled": bool("trace_sampling_enabled", true),
103
111
  "trace_sampling_tps": bool("trace_sampling_tps", 1000),
104
112
 
105
113
  "profile_error_sql_time_max": num("profile_error_sql_time_max", 30000),
@@ -146,6 +154,8 @@ var ConfigDefault = {
146
154
  "httpc_not_found_ignore": bool('httpc_not_found_ignore', false),
147
155
  "httpc_not_found_ignore_time": num('httpc_not_found_ignore', 300000),
148
156
  "ignore_sql_error_code_set": str('ignore_sql_error_code_set', ''),
157
+ "ignore_nextjs_build_file_enabled": bool('ignore_nextjs_build_file_enabled', true),
158
+ "ignore_nextjs_build_file_path": str('ignore_nextjs_build_file_path', '/_next/'),
149
159
 
150
160
  //2017.05.02 AUTO ONAME
151
161
  "auto_oname_enabled" : bool('auto_oname_enabled',false),
package/lib/core/agent.js CHANGED
@@ -19,6 +19,7 @@ var Interceptor = require('./interceptor').Interceptor,
19
19
  MysqlObserver = require('../observers/mysql-observer').MysqlObserver,
20
20
  MariaObserver = require('../observers/maria-observer').MariaObserver,
21
21
  SocketioObserver = require('../observers/socket.io-observer').SocketIOObserver,
22
+ WebsocketObserver = require('../observers/websocket-observer').WebsocketObserver,
22
23
  ProcessObserver = require('../observers/process-observer').ProcessObserver,
23
24
  FileObserver = require('../observers/file-observer').FileObserver,
24
25
  MongoObserver = require('../observers/mongo-observer').MongoObserver,
@@ -253,6 +254,7 @@ NodeAgent.prototype.loadObserves = function() {
253
254
  observes.push(MysqlObserver);
254
255
  observes.push(MariaObserver);
255
256
  observes.push(SocketioObserver);
257
+ observes.push(WebsocketObserver);
256
258
  observes.push(ExpressObserver);
257
259
  observes.push(FileObserver);
258
260
  observes.push(MongoObserver);
@@ -4,134 +4,143 @@
4
4
  * can be found in the LICENSE file.
5
5
  */
6
6
 
7
- var DataPackSender = require('./datapack-sender'),
8
- StatTranX = require('../stat/stat-tranx'),
9
- StatRemoteIp = require('../stat/stat-remoteip'),
10
- StatUserAgent = require('../stat/stat-useragent'),
11
- StatTranxDomain = require('../stat/stat-tx-domain'),
12
- StatTranxMtCaller = require('../stat/stat-tx-caller'),
13
- StatTranxReferer = require('../stat/stat-tx-referer'),
14
- conf = require('../conf/configure'),
15
- HashUtil = require('../util/hashutil'),
16
- EventLevel = require('../data/event-level'),
17
- DataTextAgent = require('../data/datatext-agent'),
18
- Long = require('long'),
19
- Logger = require('../logger');
7
+ var DataPackSender = require('./datapack-sender'),
8
+ StatTranX = require('../stat/stat-tranx'),
9
+ StatRemoteIp = require('../stat/stat-remoteip'),
10
+ StatUserAgent = require('../stat/stat-useragent'),
11
+ StatTranxDomain = require('../stat/stat-tx-domain'),
12
+ StatTranxMtCaller = require('../stat/stat-tx-caller'),
13
+ StatTranxReferer = require('../stat/stat-tx-referer'),
14
+ conf = require('../conf/configure'),
15
+ HashUtil = require('../util/hashutil'),
16
+ EventLevel = require('../data/event-level'),
17
+ DataTextAgent = require('../data/datatext-agent'),
18
+ Long = require('long'),
19
+ Logger = require('../logger');
20
20
 
21
+ var ZipProfile = require('./zipprofile');
22
+ var profile_zip_enabled = conf.getProperty('profile_zip_enabled', false);
23
+ conf.on('profile_zip_enabled', function(newProperty) {
24
+ profile_zip_enabled = newProperty;
25
+ });
21
26
 
22
27
  var DataProfileAgent = {
23
- last_reject : 0,
24
- sendProfile : function (ctx, profile, rejected) {
25
- try {
26
- StatRemoteIp.incRemoteIp(ctx.remoteIp);
27
- StatUserAgent.incUserAgent(ctx.userAgent);
28
-
29
- var transaction = profile.service;
30
- if(conf.stat_domain_enabled && ctx.http_host_hash!=0) {
31
- StatTranxDomain.add(ctx.http_host_hash, ctx.service_hash, transaction.elapsed, ctx.error != 0);
32
- }
33
-
34
- if(conf.trace_referer_enabled && ctx.referer!=0) {
35
- StatTranxReferer.add(ctx.referer, ctx.service_hash, transaction.elapsed, ctx.error != 0);
36
- }
37
-
38
- if(conf.stat_mtrace_enabled && ctx.mcaller_pcode!=0) {
39
- var key = StatTranxMtCaller.getService(ctx.mcaller_pcode, ctx.mcaller_okind, ctx.mcaller_spec, ctx.mcaller_url,ctx.service_hash);
40
- transaction.mthis_spec = conf.mtrace_spec_hash
41
-
42
- if (ctx.mcaller_spec && ctx.mcaller_spec!='') {
43
- transaction.mcaller_spec = key.mcaller_spec = HashUtil.hashFromString(ctx.mcaller_spec);
44
- DataTextAgent.MTRACE_SPEC.add(transaction.mcaller_spec, ctx.mcaller_spec);
45
- }
46
- if (ctx.mcaller_url && ctx.mcaller_url!='') {
47
- transaction.mcaller_url = key.mcaller_url = HashUtil.hashFromString(ctx.mcaller_url);
48
- DataTextAgent.MTRACE_CALLER_URL.add(transaction.mcaller_url, ctx.mcaller_url);
49
- }
50
-
51
- // additional multi transaction
52
- //key.url = ctx.service_hash;
53
- var tc = StatTranxMtCaller.getService(key);
54
- if (tc != null) {
55
- tc.count++;
56
- if (transaction.errorLevel >= EventLevel.WARNING) {
57
- tc.error++;
58
- }
59
- tc.time += transaction.elapsed;
60
- }
61
-
62
- // StatTranxMtCaller.add(ctx.mcaller_pcode,
63
- // ctx.mcaller_okind,
64
- // transaction.mcaller_spec,
65
- // transaction.mcaller_url,
66
- // ctx.service_hash,
67
- // transaction.elapsed,
68
- // ctx.error != 0);
69
- }
70
-
71
- var stat = StatTranX.getService(transaction.service);
72
-
73
- if(stat !== null) {
74
- stat.count++;
75
- if(transaction.error.isZero() ==false) {
76
- stat.error++;
77
- }
78
- if(transaction.elapsed < 0) {
79
- transaction.elapsed = 0;
80
- }
81
-
82
- stat.actived += ctx.profileActive;
83
- stat.time_sum += transaction.elapsed;
84
- if (transaction.elapsed > stat.time_max) {
85
- stat.time_max = transaction.elapsed;
86
- }
87
-
88
- switch (transaction.apdex) {
89
- case 2:
90
- stat.apdex_satisfied++;
91
- break;
92
- case 1:
93
- stat.apdex_tolerated++;
94
- break;
28
+ last_reject : 0,
29
+ sendProfile : function (ctx, profile, rejected) {
30
+ try {
31
+ StatRemoteIp.incRemoteIp(ctx.remoteIp);
32
+ StatUserAgent.incUserAgent(ctx.userAgent);
33
+
34
+ var transaction = profile.service;
35
+ if(conf.stat_domain_enabled && ctx.http_host_hash!=0) {
36
+ StatTranxDomain.add(ctx.http_host_hash, ctx.service_hash, transaction.elapsed, ctx.error != 0);
37
+ }
38
+
39
+ if(conf.trace_referer_enabled && ctx.referer!=0) {
40
+ StatTranxReferer.add(ctx.referer, ctx.service_hash, transaction.elapsed, ctx.error != 0);
95
41
  }
96
- if (stat.time_min==0 || transaction.elapsed < stat.time_min) {
97
- stat.time_min = transaction.elapsed;
42
+
43
+ if(conf.stat_mtrace_enabled && ctx.mcaller_pcode!=0) {
44
+ var key = StatTranxMtCaller.getService(ctx.mcaller_pcode, ctx.mcaller_okind, ctx.mcaller_spec, ctx.mcaller_url,ctx.service_hash);
45
+ transaction.mthis_spec = conf.mtrace_spec_hash
46
+
47
+ if (ctx.mcaller_spec && ctx.mcaller_spec!='') {
48
+ transaction.mcaller_spec = key.mcaller_spec = HashUtil.hashFromString(ctx.mcaller_spec);
49
+ DataTextAgent.MTRACE_SPEC.add(transaction.mcaller_spec, ctx.mcaller_spec);
50
+ }
51
+ if (ctx.mcaller_url && ctx.mcaller_url!='') {
52
+ transaction.mcaller_url = key.mcaller_url = HashUtil.hashFromString(ctx.mcaller_url);
53
+ DataTextAgent.MTRACE_CALLER_URL.add(transaction.mcaller_url, ctx.mcaller_url);
54
+ }
55
+
56
+ // additional multi transaction
57
+ //key.url = ctx.service_hash;
58
+ var tc = StatTranxMtCaller.getService(key);
59
+ if (tc != null) {
60
+ tc.count++;
61
+ if (transaction.errorLevel >= EventLevel.WARNING) {
62
+ tc.error++;
63
+ }
64
+ tc.time += transaction.elapsed;
65
+ }
66
+
67
+ // StatTranxMtCaller.add(ctx.mcaller_pcode,
68
+ // ctx.mcaller_okind,
69
+ // transaction.mcaller_spec,
70
+ // transaction.mcaller_url,
71
+ // ctx.service_hash,
72
+ // transaction.elapsed,
73
+ // ctx.error != 0);
98
74
  }
99
- stat.time_std += (Long.fromInt(transaction.elapsed) * Long.fromInt(transaction.elapsed));
100
-
101
- stat.sql_count += transaction.sqlCount;
102
- stat.sql_time +=transaction.sqlTime;
103
- stat.sql_fetch += ctx.rs_count;
104
- stat.sql_fetch_time +=ctx.rs_time;
105
-
106
- stat.httpc_count += transaction.httpcCount;
107
- stat.httpc_time +=transaction.httpcTime;
108
-
109
- stat.malloc_sum +=transaction.malloc;
110
- stat.cpu_sum +=transaction.cpuTime;
111
-
112
- if (rejected) {
113
- var now = Date.now();
114
- if (now < this.last_reject + 1000) {
115
- return;
116
- }
117
- this.last_reject = now;
118
- } else if (stat.profiled == true // 이전(5분구간 내)에 프로파일이 수집된점이 있음
119
- && ctx.profileActive == 0 // 액티브 스택을 추적한적이 없음
120
- && transaction.elapsed < conf.profile_basetime
121
- && transaction.error.isZero()) {
122
- return;
123
- }
124
- stat.profiled = true;
125
- }
126
-
127
- var steps = ctx.profile.getSteps();
128
- profile.setProfile(steps);
129
- DataPackSender.sendProfilePack(profile);
130
-
131
- } catch(e) {
132
- Logger.printError('WHATAP-199', 'dataprofile-agent error', e);
133
- }
134
- }
75
+
76
+ var stat = StatTranX.getService(transaction.service);
77
+
78
+ if(stat !== null) {
79
+ stat.count++;
80
+ if(transaction.error.isZero() ==false) {
81
+ stat.error++;
82
+ }
83
+ if(transaction.elapsed < 0) {
84
+ transaction.elapsed = 0;
85
+ }
86
+
87
+ stat.actived += ctx.profileActive;
88
+ stat.time_sum += transaction.elapsed;
89
+ if (transaction.elapsed > stat.time_max) {
90
+ stat.time_max = transaction.elapsed;
91
+ }
92
+
93
+ switch (transaction.apdex) {
94
+ case 2:
95
+ stat.apdex_satisfied++;
96
+ break;
97
+ case 1:
98
+ stat.apdex_tolerated++;
99
+ break;
100
+ }
101
+ if (stat.time_min==0 || transaction.elapsed < stat.time_min) {
102
+ stat.time_min = transaction.elapsed;
103
+ }
104
+ stat.time_std += (Long.fromInt(transaction.elapsed) * Long.fromInt(transaction.elapsed));
105
+
106
+ stat.sql_count += transaction.sqlCount;
107
+ stat.sql_time +=transaction.sqlTime;
108
+ stat.sql_fetch += ctx.rs_count;
109
+ stat.sql_fetch_time +=ctx.rs_time;
110
+
111
+ stat.httpc_count += transaction.httpcCount;
112
+ stat.httpc_time +=transaction.httpcTime;
113
+
114
+ stat.malloc_sum +=transaction.malloc;
115
+ stat.cpu_sum +=transaction.cpuTime;
116
+
117
+ if (rejected) {
118
+ var now = Date.now();
119
+ if (now < this.last_reject + 1000) {
120
+ return;
121
+ }
122
+ this.last_reject = now;
123
+ } else if (stat.profiled == true // 이전(5분구간 내)에 프로파일이 수집된점이 있음
124
+ && ctx.profileActive == 0 // 액티브 스택을 추적한적이 없음
125
+ && transaction.elapsed < conf.profile_basetime
126
+ && transaction.error.isZero()) {
127
+ return;
128
+ }
129
+ stat.profiled = true;
130
+ }
131
+
132
+ var steps = ctx.profile.getSteps();
133
+ profile.setProfile(steps);
134
+ if(profile_zip_enabled){
135
+ ZipProfile.getInstance().add(profile);
136
+ } else {
137
+ DataPackSender.sendProfilePack(profile);
138
+ }
139
+
140
+ } catch(e) {
141
+ Logger.printError('WHATAP-199', 'dataprofile-agent error', e);
142
+ }
143
+ }
135
144
  };
136
145
 
137
146
  module.exports = DataProfileAgent;
@@ -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.processing) {
189
+ this.processQueue()
190
+ }
191
+ }
192
+ stopProcessQueue() {
193
+ this.processing = false;
194
+ }
195
+ }
196
+
197
+ module.exports = ZipProfile;
@@ -59,6 +59,8 @@ var httpc_not_found_ignore_time = conf.getProperty('httpc_not_found_ignore_time'
59
59
  var profile_http_header_ignore_keys = conf.getProperty('profile_http_header_ignore_keys', 'Cookie,cookie,accept,user-agent,referer');
60
60
  var profile_http_parameter_enabled = conf.getProperty('profile_http_parameter_enabled', true);
61
61
  var profile_http_parameter_keys = conf.getProperty('profile_http_parameter_keys', '');
62
+ var ignore_nextjs_build_file_enabled = conf.getProperty('ignore_nextjs_build_file_enabled', true);
63
+ var ignore_nextjs_build_file_path = conf.getProperty('ignore_nextjs_build_file_path', '/_next/');
62
64
  conf.on('trace_http_client_ip_header_key', function(newProperty) {
63
65
  configIpHeaderKey = newProperty;
64
66
  });
@@ -116,6 +118,12 @@ conf.on('profile_http_parameter_enabled', function (newProps) {
116
118
  conf.on('profile_http_parameter_keys', function (newProps) {
117
119
  profile_http_parameter_keys = newProps;
118
120
  })
121
+ conf.on('ignore_nextjs_build_file_enabled', function (newProps) {
122
+ ignore_nextjs_build_file_enabled = newProps;
123
+ })
124
+ conf.on('ignore_nextjs_build_file_path', function (newProps) {
125
+ ignore_nextjs_build_file_path = newProps;
126
+ })
119
127
  var staticConents = function (newProps) {
120
128
  var x=new Set();
121
129
  var words = !newProps?[]:newProps.split(',');
@@ -231,8 +239,11 @@ function isStatic(u){
231
239
  }
232
240
  function initCtx(req, res) {
233
241
  /*url이 없으면 추적하지 않는다*/
234
- if(req.url == null) { return null; }
242
+ if(!req.url) { return null; }
235
243
  if(ignore_http_method && ignore_http_method.toUpperCase().split(',').includes(req.method)) { return null; }
244
+ if (ignore_nextjs_build_file_enabled && ignore_nextjs_build_file_path && ignore_nextjs_build_file_path.split(',').some(path => req.url.startsWith(path))) {
245
+ return null;
246
+ }
236
247
 
237
248
  var ctx = TraceContextManager.start();
238
249
  if(ctx == null) { return null; }
@@ -738,6 +749,7 @@ HttpObserver.prototype.inject = function( mod, moduleName ) {
738
749
 
739
750
  var ctx = lctx.context;
740
751
  if (ctx == null || ( args[0].host == null && args[0].hostname == null)) { return; }
752
+ var is_ignore_error = false;
741
753
 
742
754
  ret.on('response', function(response){
743
755
  var statusCode = response.statusCode;
@@ -757,7 +769,7 @@ HttpObserver.prototype.inject = function( mod, moduleName ) {
757
769
  if (TraceContextManager.resume(ctx._id) == null) { return; }
758
770
  ctx.is_httpc_error = true;
759
771
 
760
- if (transaction_status_error_enable && step.error.isZero()) {
772
+ if (transaction_status_error_enable && step.error.isZero() && !is_ignore_error) {
761
773
  step.error = StatError.addError(err.code, err.message, ctx.service_hash,
762
774
  TextTypes.HTTPC_URL, step.url);
763
775
  if (ctx.error.isZero()) {
@@ -807,16 +819,17 @@ HttpObserver.prototype.inject = function( mod, moduleName ) {
807
819
 
808
820
  socket.on('timeout', function () {
809
821
  if (TraceContextManager.resume(ctx._id) == null) { return; }
810
- if (step.error.isZero()) {
811
- var msgObj = { 'class': 'Timeout', 'msg': 'Timeout' };
812
- step.error = StatError.addError('Timeout','Timeout', ctx.service_hash);
813
- if (transaction_status_error_enable && ctx.error.isZero()) {
814
- ctx.error = step.error;
815
- ctx.statusCode = 'Timeout';
816
- ctx.statusMessage = 'Timeout';
817
- }
818
- }
819
- endHttpc(ctx, step);
822
+ is_ignore_error = true;
823
+ // if (step.error.isZero()) {
824
+ // var msgObj = { 'class': 'Timeout', 'msg': 'Timeout' };
825
+ // step.error = StatError.addError('Timeout','Timeout', ctx.service_hash);
826
+ // if (transaction_status_error_enable && ctx.error.isZero()) {
827
+ // ctx.error = step.error;
828
+ // ctx.statusCode = 'Timeout';
829
+ // ctx.statusMessage = 'Timeout';
830
+ // }
831
+ // }
832
+ // endHttpc(ctx, step);
820
833
  });
821
834
  }
822
835
  });
@@ -28,7 +28,7 @@ var trace_background_socket_enabled = conf.getProperty('trace_background_socket_
28
28
  conf.on('trace_background_socket_enabled', function (newProps) {
29
29
  trace_background_socket_enabled = newProps;
30
30
  })
31
- var trace_sampling_enabled = conf.getProperty('trace_sampling_enabled', false);
31
+ var trace_sampling_enabled = conf.getProperty('trace_sampling_enabled', true);
32
32
  conf.on('trace_sampling_enabled', function (newProps) {
33
33
  trace_sampling_enabled = newProps;
34
34
  })
@@ -0,0 +1,195 @@
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 MeterSocketio = require('../counter/meter/meter-socket.io'),
8
+ TraceContextManager = require('../trace/trace-context-manager'),
9
+ SocketStep = require('../step/socket-step'),
10
+ conf = require('../conf/configure'),
11
+ IPUtil = require('../util/iputil'),
12
+ Logger = require('../logger');
13
+ const {Detector: URLPatternDetector} = require("whatap/lib/trace/serviceurl-pattern-detector");
14
+ const HashUtil = require("whatap/lib/util/hashutil");
15
+ const DataTextAgent = require("whatap/lib/data/datatext-agent");
16
+ const ResourceProfile = require("whatap/lib/util/resourceprofile");
17
+ const ProfilePack = require('../pack/profile-pack');
18
+ const TxRecord = require('../service/tx-record');
19
+ const DateUtil = require('../util/dateutil');
20
+ const SecurityMaster = require('../net/security-master');
21
+ const DataProfileAgent = require('../data/dataprofile-agent');
22
+ const MessageStep = require("whatap/lib/step/message-step");
23
+ const MeterUsers = require("whatap/lib/counter/meter/meter-users");
24
+ const DataPackSender = require("whatap/lib/data/datapack-sender");
25
+ const MeterService = require('../counter/meter/meter-service').MeterService;
26
+
27
+ var trace_background_socket_enabled = conf.getProperty('trace_background_socket_enabled', false);
28
+ conf.on('trace_background_socket_enabled', function (newProps) {
29
+ trace_background_socket_enabled = newProps;
30
+ })
31
+ var trace_sampling_enabled = conf.getProperty('trace_sampling_enabled', true);
32
+ conf.on('trace_sampling_enabled', function (newProps) {
33
+ trace_sampling_enabled = newProps;
34
+ })
35
+ var trace_sampling_tps = conf.getProperty('trace_sampling_tps', 1000);
36
+ conf.on('trace_sampling_tps', function (newProps) {
37
+ trace_sampling_tps = newProps;
38
+ })
39
+
40
+ var WebsocketObserver = function(agent){
41
+ this.agent = agent;
42
+ this.packages = ['websocket'];
43
+ };
44
+
45
+ var socket_count = {
46
+ count: 0,
47
+ start_time: null
48
+ };
49
+
50
+ WebsocketObserver.prototype.inject = function (mod, moduleName) {
51
+ if (mod.__whatap_observe__) {
52
+ return;
53
+ }
54
+ mod.__whatap_observe__ = true;
55
+ Logger.initPrint("WebsocketObserver");
56
+
57
+ var self = this;
58
+ var aop = self.agent.aop;
59
+
60
+ aop.after(mod.server.prototype, 'on', function (obj, args, ret, lctx){
61
+ aop.after(mod.connection.prototype, ['send', 'sendUTF', 'sendBytes'], function (obj, args, ret, lctx) {
62
+ if(!trace_background_socket_enabled) {
63
+ return;
64
+ }
65
+ if(trace_sampling_enabled){
66
+ var now = Date.now();
67
+ if(!socket_count.start_time) {
68
+ socket_count.start_time = now;
69
+ }
70
+
71
+ if ((now - socket_count.start_time) > 5000) {
72
+ socket_count.start_time = now;
73
+ socket_count.count = 0;
74
+ }
75
+
76
+ socket_count.count++;
77
+ if(socket_count.count > trace_sampling_tps) {
78
+ MeterService.add(0, 1, 0, 0, 0, 0);
79
+ return;
80
+ }
81
+ }
82
+
83
+ var protocol = obj.protocol;
84
+ var remoteAddress = obj.remoteAddress;
85
+
86
+ TraceContextManager._asyncLocalStorage.run(initCtx(obj, args), () => {
87
+ try{
88
+ var ctx = TraceContextManager._asyncLocalStorage.getStore();
89
+ if (!ctx) {
90
+ return;
91
+ }
92
+
93
+ var host;
94
+ if (remoteAddress && remoteAddress.includes(':')) {
95
+ host = remoteAddress.substring(remoteAddress.lastIndexOf(':') + 1);
96
+ }
97
+
98
+ ctx.socket_connecting = true;
99
+ ctx.footprint('Websocket Connecting: ' + host);
100
+
101
+ if (protocol) {
102
+ var protocol_hash = HashUtil.hashFromString('Protocol');
103
+ var step = new MessageStep();
104
+ step.hash = protocol_hash;
105
+ step.start_time = ctx.getElapsedTime();
106
+ step.desc = protocol;
107
+
108
+ DataTextAgent.MESSAGE.add(protocol_hash, 'Protocol');
109
+ ctx.profile.add(step);
110
+ }
111
+
112
+ var step = new SocketStep();
113
+ step.start_time = ctx.getElapsedTime();
114
+ step.ipaddr = Buffer.from(IPUtil.stringToBytes(host));
115
+ // step.port = port;
116
+
117
+ ctx.socket_connecting = false;
118
+ step.elapsed = ctx.getElapsedTime() - step.start_time;
119
+ ctx.profile.push(step);
120
+
121
+ ctx.footprint('Websocket Connecting Done');
122
+
123
+ self.__endTransaction(null, ctx);
124
+ return;
125
+ }catch (e) {
126
+ Logger.printError('WHATAP-616', 'Websocket transaction error..', e, false);
127
+ return;
128
+ }
129
+ });
130
+ })
131
+ })
132
+ };
133
+
134
+ WebsocketObserver.prototype.__endTransaction = function(error, ctx) {
135
+ try {
136
+ var profile = new ProfilePack();
137
+ var wtx = new TxRecord();
138
+ wtx.endTime = DateUtil.currentTime();
139
+ profile.time = wtx.endTime;
140
+ wtx.elapsed = ctx.getElapsedTime();
141
+
142
+ DataTextAgent.SERVICE.add(ctx.service_hash, ctx.service_name);
143
+
144
+ wtx.seq = ctx.txid;
145
+ wtx.service = ctx.service_hash;
146
+ wtx.cpuTime = ResourceProfile.getCPUTime() - ctx.start_cpu;
147
+ wtx.malloc = ResourceProfile.getUsedHeapSize()-ctx.start_malloc;
148
+ if(wtx.malloc < 0) { wtx.malloc = 0; }
149
+ wtx.status = 2;
150
+
151
+ wtx.ipaddr = ctx.remoteIp;
152
+
153
+ MeterService.add(wtx.service, wtx.elapsed,
154
+ wtx.errorLevel, ctx.mcaller_pcode, ctx.mcaller_okind, ctx.mcaller_oid);
155
+
156
+ profile.oid = SecurityMaster.OID;
157
+ profile.service = wtx;
158
+
159
+ TraceContextManager.end(ctx._id);
160
+
161
+ setTimeout(function () {
162
+ DataProfileAgent.sendProfile(ctx, profile, false);
163
+ TraceContextManager.end(ctx._id);
164
+ ctx = null;
165
+ }, 100);
166
+ } catch (e) {
167
+ Logger.printError('WHATAP-615', 'Websocket end transaction error..', e, false);
168
+ TraceContextManager.end(ctx._id);
169
+ ctx = null;
170
+ }
171
+
172
+ };
173
+
174
+ function initCtx(socket, args) {
175
+ const ctx = TraceContextManager.start();
176
+ if (!ctx) {return;}
177
+
178
+ var remote_addr;
179
+ const address = socket.remoteAddress;
180
+ if(address && address.includes(':')){
181
+ remote_addr = address.substring(address.lastIndexOf(':')+1);
182
+ }
183
+
184
+ ctx.start_malloc = ResourceProfile.getUsedHeapSize();
185
+ ctx.start_cpu = ResourceProfile.getCPUTime();
186
+
187
+ remote_addr=IPUtil.checkIp4(remote_addr);
188
+ ctx.remoteIp = IPUtil.stringToInt(remote_addr);
189
+ ctx.userid = Long.fromNumber(ctx.remoteIp);
190
+ MeterUsers.add(ctx.userid);
191
+
192
+ return ctx;
193
+ }
194
+
195
+ exports.WebsocketObserver = WebsocketObserver;
@@ -4,58 +4,60 @@
4
4
  * can be found in the LICENSE file.
5
5
  */
6
6
 
7
- exports.PARAMETER = 0x0100;
8
- exports.COUNTER_1 = 0x0201;
9
- exports.PROFILE = 0x0300;
10
- exports.ACTIVESTACK_1 = 0x0401;
11
- exports.TEXT = 0x0700;
12
- exports.ERROR_SNAP = 0x0800;
13
- exports.ERROR_SNAP_1 = 0x0801;
14
- exports.REALTIME_USER_1 = 0x0f01;
15
-
16
- exports.STAT_SERVICE= 0x0900;
17
- exports.STAT_SERVICE_1 = 0x0901;
18
- exports.STAT_GENERAL= 0x0910;
19
- exports.STAT_SQL = 0x0a00;
20
- exports.STAT_HTTPC = 0x0b00;
21
- exports.STAT_ERROR = 0x0c00;
22
- exports.STAT_METHOD = 0x0e00;
23
- exports.STAT_TOP_SERVICE= 0x1000;
24
- exports.STAT_REMOTE_IP = 0x1100;
25
- exports.STAT_USER_AGENT = 0x1200;
26
-
27
- exports.EVENT = 0x1400;
28
- exports.HITMAP = 0x1500;
29
- exports.HITMAP_1 = 0x1501;
30
- exports.COUNTER5M = 0x1600;
31
- exports.HITMAP5M = 0x1700;
32
-
33
- exports.TAG_COUNT = 0x1601;
34
-
35
- exports.PACK_NAME = {
36
- 0x0100 : 'PARAMETER',
37
- 0x0201 : 'COUNTER_1',
38
- 0x0300 : 'PROFILE',
39
- 0x0401 : 'ACTIVESTACK_1',
40
- 0x0700 : 'TEXT',
41
- 0x0800 : 'ERROR_SNAP',
42
- 0x0801 : 'ERROR_SNAP_1',
43
- 0x0f01 : 'REALTIME_USER_1',
44
- 0x0900 : 'STAT_SERVICE',
45
- 0x0901 : 'STAT_SERVICE_1',
46
- 0x0910 : 'STAT_GENERAL',
47
- 0x0a00 : 'STAT_SQL',
48
- 0x0b00 : 'STAT_HTTPC',
49
- 0x0c00 : 'STAT_ERROR',
50
- 0x0e00 : 'STAT_METHOD',
51
- 0x1000 : 'STAT_TOP_SERVICE',
52
- 0x1100 : 'STAT_REMOTE_IP',
53
- 0x1200 : 'STAT_USER_AGENT',
54
- 0x1400 : 'EVENT',
55
- 0x1500 : 'HITMAP',
56
- 0x1501 : 'HITMAP_1',
57
- 0x1600 : 'COUNTER5M',
58
- 0x1700 : 'HITMAP5M',
59
- 0x1601 : 'TAG_COUNT'
60
- };
7
+ exports.PARAMETER = 0x0100;
8
+ exports.COUNTER_1 = 0x0201;
9
+ exports.PROFILE = 0x0300;
10
+ exports.ACTIVESTACK_1 = 0x0401;
11
+ exports.TEXT = 0x0700;
12
+ exports.ERROR_SNAP = 0x0800;
13
+ exports.ERROR_SNAP_1 = 0x0801;
14
+ exports.REALTIME_USER_1 = 0x0f01;
15
+
16
+ exports.STAT_SERVICE= 0x0900;
17
+ exports.STAT_SERVICE_1 = 0x0901;
18
+ exports.STAT_GENERAL= 0x0910;
19
+ exports.STAT_SQL = 0x0a00;
20
+ exports.STAT_HTTPC = 0x0b00;
21
+ exports.STAT_ERROR = 0x0c00;
22
+ exports.STAT_METHOD = 0x0e00;
23
+ exports.STAT_TOP_SERVICE= 0x1000;
24
+ exports.STAT_REMOTE_IP = 0x1100;
25
+ exports.STAT_USER_AGENT = 0x1200;
26
+
27
+ exports.EVENT = 0x1400;
28
+ exports.HITMAP = 0x1500;
29
+ exports.HITMAP_1 = 0x1501;
30
+ exports.COUNTER5M = 0x1600;
31
+ exports.HITMAP5M = 0x1700;
32
+
33
+ exports.TAG_COUNT = 0x1601;
34
+ exports.ZIP = 0x170b;
35
+
36
+ exports.PACK_NAME = {
37
+ 0x0100 : 'PARAMETER',
38
+ 0x0201 : 'COUNTER_1',
39
+ 0x0300 : 'PROFILE',
40
+ 0x0401 : 'ACTIVESTACK_1',
41
+ 0x0700 : 'TEXT',
42
+ 0x0800 : 'ERROR_SNAP',
43
+ 0x0801 : 'ERROR_SNAP_1',
44
+ 0x0f01 : 'REALTIME_USER_1',
45
+ 0x0900 : 'STAT_SERVICE',
46
+ 0x0901 : 'STAT_SERVICE_1',
47
+ 0x0910 : 'STAT_GENERAL',
48
+ 0x0a00 : 'STAT_SQL',
49
+ 0x0b00 : 'STAT_HTTPC',
50
+ 0x0c00 : 'STAT_ERROR',
51
+ 0x0e00 : 'STAT_METHOD',
52
+ 0x1000 : 'STAT_TOP_SERVICE',
53
+ 0x1100 : 'STAT_REMOTE_IP',
54
+ 0x1200 : 'STAT_USER_AGENT',
55
+ 0x1400 : 'EVENT',
56
+ 0x1500 : 'HITMAP',
57
+ 0x1501 : 'HITMAP_1',
58
+ 0x1600 : 'COUNTER5M',
59
+ 0x1700 : 'HITMAP5M',
60
+ 0x1601 : 'TAG_COUNT',
61
+ 0x170b : 'ZIP'
62
+ };
61
63
 
@@ -0,0 +1,71 @@
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 PackEnum = require('./packenum'),
8
+ Pack = require('./pack'),
9
+ TxRecord = require('../service/tx-record'),
10
+ Step = require('../step/step'),
11
+ DataOutputX = require('../io/data-outputx'),
12
+ DataInputX = require('../io/data-inputx');
13
+ var zlib = require('zlib');
14
+
15
+ function ZipPack() {
16
+ Pack.call(this);
17
+ this.records = [];
18
+ this.recordCount = null;
19
+ this.status = 0;
20
+ }
21
+ ZipPack.prototype = new Pack();
22
+ ZipPack.prototype.constructor = ZipPack;
23
+ ZipPack.prototype.toString = function() {
24
+ var text = 'ZipPack ' + Pack.prototype.toString.call(this);
25
+ return text;
26
+ };
27
+ ZipPack.prototype.getPackType = function () {
28
+ return PackEnum.ZIP;
29
+ };
30
+ ZipPack.prototype.write = function (dout) {
31
+ Pack.prototype.write.call(this, dout);
32
+ dout.writeByte(this.status);
33
+ dout.writeDecimal(this.recordCount);
34
+ dout.writeBlob(this.records);
35
+ }
36
+ ZipPack.prototype.read = function (din) {
37
+ Pack.prototype.read.call(this, din);
38
+ this.status = din.readByte();
39
+ this.recordCount = din.readDecimal();
40
+ this.records = din.readBlob();
41
+ return this;
42
+ }
43
+ ZipPack.prototype.setRecords = function (items, size) {
44
+ if(size) this.recordCount = size;
45
+ else this.recordCount = items.length;
46
+
47
+ var o = new DataOutputX();
48
+ for(let i = 0; i < items.length; i++){
49
+ o.writePack(items[i]);
50
+ }
51
+ this.records = o.toByteArray();
52
+ return this;
53
+ }
54
+ ZipPack.prototype.getRecords = function () {
55
+ var items = [];
56
+ if(!this.records) {
57
+ return null;
58
+ }
59
+ var dataInputX = new DataInputX(this.records);
60
+ for(let i = 0; i < this.recordCount; i++){
61
+ var p = dataInputX.readPack();
62
+ p.pcode = this.pcode;
63
+ p.oid = this.oid;
64
+ p.okind = this.okind;
65
+ p.onode = this.onode;
66
+ items.push(p);
67
+ }
68
+ return items;
69
+ }
70
+
71
+ module.exports = ZipPack;
@@ -160,6 +160,8 @@ TraceContextManager.prototype.endTrace = function (ctx) {
160
160
  service.endTime = DateUtil.currentTime();
161
161
  service.elapsed = ctx.getElapsedTime();
162
162
  service.service = ctx.service_hash;
163
+ DataTextAgent.SERVICE.add(ctx.service_hash, ctx.service_name);
164
+
163
165
  service.cpuTime = ResourceProfile.getCPUTime() - ctx.start_cpu;
164
166
  service.malloc = ResourceProfile.getUsedHeapSize() - ctx.start_malloc;
165
167
  if(service.malloc < 0) { service.malloc = 0; }
@@ -20,7 +20,7 @@ ParamSecurity.prototype.getKey = function () {
20
20
  return buf;
21
21
  };
22
22
 
23
- ParamSecurity.prototype.reload = function () {
23
+ ParamSecurity.prototype.reload = function () {
24
24
  var home = conf['app.root'];
25
25
  if (home == null ) {
26
26
  var self = this;
@@ -30,7 +30,7 @@ ParamSecurity.prototype.reload = function () {
30
30
  return;
31
31
  }
32
32
 
33
- var file = path.join(home, 'paramkey.txt');
33
+ var file = path.join(home, 'security.conf');
34
34
  var self = this;
35
35
  try {
36
36
  var stat = fs.statSync(file);
@@ -40,8 +40,8 @@ ParamSecurity.prototype.reload = function () {
40
40
  }
41
41
  var readable = fs.createReadStream(file, {flags : 'r'});
42
42
  readable.on('readable', function () {
43
- if(self.key !== null
44
- && self.key !== undefined
43
+ if(self.key !== null
44
+ && self.key !== undefined
45
45
  && self.key.length === 0 ) { return; }
46
46
  var chunk;
47
47
  while (null !== (chunk = readable.read())) {
@@ -50,11 +50,12 @@ ParamSecurity.prototype.reload = function () {
50
50
  self.key = Buffer.from(self.key);
51
51
  });
52
52
  } catch (e) {
53
- self.key = self.getKey();
53
+ // self.key = self.getKey();
54
+ self.key = 'WHATAP';
54
55
  var printWriter = fs.createWriteStream(file, {flags : 'w'});
55
56
  printWriter.write(self.key);
56
57
  self.key = Buffer.from(self.key);
57
- }
58
+ }
58
59
  };
59
60
  ParamSecurity.prototype.encrypt = function (b, crc) {
60
61
  var self = this;
@@ -17,6 +17,33 @@ RequestQueue.prototype.get = function () {
17
17
  }
18
18
  return null;
19
19
  };
20
+ RequestQueue.prototype.getByTimeout = async function (timeout) {
21
+ try{
22
+ if (this.queue.size() > 0) {
23
+ return this.queue.removeFirst()
24
+ }
25
+ var timeto = Date.now() + timeout;
26
+ var time = timeout;
27
+ while (this.queue.size() === 0) {
28
+ try {
29
+ if (time > 0) {
30
+ await new Promise(resolve => setTimeout(resolve, time));
31
+ }
32
+ } catch (e) {
33
+ }
34
+ time = timeto - Date.now();
35
+ if (time <= 0) {
36
+ break;
37
+ }
38
+ }
39
+ if (this.queue.size() > 0) {
40
+ return this.queue.removeFirst();
41
+ }
42
+ return null;
43
+ }catch (e) {
44
+ return null;
45
+ }
46
+ };
20
47
  RequestQueue.prototype.put = function (o) {
21
48
  if(this.capacity <= 0 || this.queue.size() < this.capacity) {
22
49
  this.queue.add(o);
@@ -34,10 +61,10 @@ RequestQueue.prototype.clear = function () {
34
61
  };
35
62
 
36
63
  var failed = function (v) {
37
-
64
+
38
65
  };
39
66
  var overflowed = function (v) {
40
-
67
+
41
68
  };
42
69
 
43
70
  module.exports = RequestQueue;
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "whatap",
3
3
  "homepage": "http://www.whatap.io",
4
- "version": "0.4.94",
5
- "releaseDate": "20240307",
4
+ "version": "0.4.96",
5
+ "releaseDate": "20240530",
6
6
  "description": "Monitoring and Profiling Service",
7
7
  "main": "index.js",
8
8
  "scripts": {},