whatap 0.4.93 → 0.4.95
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/lib/conf/config-default.js +15 -0
- package/lib/data/dataprofile-agent.js +132 -123
- package/lib/data/zipprofile.js +197 -0
- package/lib/observers/http-observer.js +77 -21
- package/lib/observers/maria-observer.js +6 -0
- package/lib/observers/mongoose-observer.js +15 -9
- package/lib/observers/mssql-observer.js +6 -0
- package/lib/observers/mysql-observer.js +7 -1
- package/lib/observers/pgsql-observer.js +7 -0
- package/lib/observers/socket.io-observer.js +153 -25
- package/lib/pack/packenum.js +56 -54
- package/lib/pack/zip-pack.js +71 -0
- package/lib/util/paramsecurity.js +5 -5
- package/lib/util/request-queue.js +29 -2
- package/package.json +2 -2
|
@@ -57,11 +57,21 @@ var ConfigDefault = {
|
|
|
57
57
|
|
|
58
58
|
"profile_http_querystring_enabled": bool('profile_http_querystring_enabled',false),
|
|
59
59
|
"profile_http_header_enabled": bool('profile_http_header_enabled',false),
|
|
60
|
+
"profile_http_header_ignore_keys": str('profile_http_header_ignore_keys','Cookie,cookie,accept,user-agent,referer'),
|
|
60
61
|
"profile_http_parameter_enabled": bool('profile_http_parameter_enabled',false),
|
|
62
|
+
"profile_http_parameter_keys": str('profile_http_parameter_keys',''),
|
|
61
63
|
"profile_httpc_parameter_enabled": bool('profile_httpc_parameter_enabled',false),
|
|
62
64
|
"profile_http_parameter_url_prefix": "/",
|
|
63
65
|
"profile_http_header_url_prefix": "/",
|
|
64
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', 1000),
|
|
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),
|
|
65
75
|
|
|
66
76
|
"hook_method_patterns": str('hook_method_patterns',""),
|
|
67
77
|
"hook_method_access_public_enabled": true,
|
|
@@ -85,6 +95,7 @@ var ConfigDefault = {
|
|
|
85
95
|
"trace_user_agent_header_key": str('trace_user_agent_header_key',''),
|
|
86
96
|
"trace_referer_header_key": str('trace_referer_header_key',''),
|
|
87
97
|
"profile_sql_param_enabled": bool('profile_sql_param_enabled',false),
|
|
98
|
+
"profile_sql_resource_enabled": bool('profile_sql_resource_enabled',false),
|
|
88
99
|
"error_snap_enabled" : true,
|
|
89
100
|
"trace_user_enabled": bool('trace_user_enabled',true),
|
|
90
101
|
"trace_user_using_ip": bool('trace_user_using_ip',true),
|
|
@@ -96,6 +107,9 @@ var ConfigDefault = {
|
|
|
96
107
|
"trace_sql_error_depth": num('trace_sql_error_depth', 50),
|
|
97
108
|
"transaction_status_error_enable": bool("transaction_status_error_enable", true),
|
|
98
109
|
|
|
110
|
+
"trace_sampling_enabled": bool("trace_sampling_enabled", false),
|
|
111
|
+
"trace_sampling_tps": bool("trace_sampling_tps", 1000),
|
|
112
|
+
|
|
99
113
|
"profile_error_sql_time_max": num("profile_error_sql_time_max", 30000),
|
|
100
114
|
"profile_error_step_enabled": bool('profile_error_step_enabled', true),
|
|
101
115
|
"hook_direct_patch_classes": "",
|
|
@@ -139,6 +153,7 @@ var ConfigDefault = {
|
|
|
139
153
|
"trace_sql_normalize_enabled" : true,
|
|
140
154
|
"httpc_not_found_ignore": bool('httpc_not_found_ignore', false),
|
|
141
155
|
"httpc_not_found_ignore_time": num('httpc_not_found_ignore', 300000),
|
|
156
|
+
"ignore_sql_error_code_set": str('ignore_sql_error_code_set', ''),
|
|
142
157
|
|
|
143
158
|
//2017.05.02 AUTO ONAME
|
|
144
159
|
"auto_oname_enabled" : bool('auto_oname_enabled',false),
|
|
@@ -4,134 +4,143 @@
|
|
|
4
4
|
* can be found in the LICENSE file.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
97
|
-
|
|
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
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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;
|
|
@@ -32,11 +32,14 @@ var TraceContextManager = require('../trace/trace-context-manager'),
|
|
|
32
32
|
ResourceProfile = require('../util/resourceprofile'),
|
|
33
33
|
TextTypes = require('../lang/text-types'),
|
|
34
34
|
MessageStep = require('../step/message-step'),
|
|
35
|
+
SecureMsgStep = require('../step/securemsg-step'),
|
|
35
36
|
PluginLoaderManager = require('../plugin/plugin-loadermanager'),
|
|
36
37
|
Long = require('long'),
|
|
37
38
|
KeyGen = require('../util/keygen'),
|
|
38
39
|
Logger = require('../logger'),
|
|
39
40
|
IntKeyLinkedMap = require("../util/intkey-linkedmap");
|
|
41
|
+
const ParamSecurity = require("../util/paramsecurity");
|
|
42
|
+
const {Buffer} = require("buffer");
|
|
40
43
|
|
|
41
44
|
var _exts=new Set([".css",".js",".png", ".htm", ".html", ".gif", ".jpg", ".css", ".txt", ".ico"]);
|
|
42
45
|
|
|
@@ -53,6 +56,9 @@ var httpc_status_ignore_set = conf.getProperty('httpc_status_ignore_set', '');
|
|
|
53
56
|
var profile_error_step_enabled = conf.getProperty('profile_error_step_enabled', '');
|
|
54
57
|
var httpc_not_found_ignore = conf.getProperty('httpc_not_found_ignore', false);
|
|
55
58
|
var httpc_not_found_ignore_time = conf.getProperty('httpc_not_found_ignore_time', 300000);
|
|
59
|
+
var profile_http_header_ignore_keys = conf.getProperty('profile_http_header_ignore_keys', 'Cookie,cookie,accept,user-agent,referer');
|
|
60
|
+
var profile_http_parameter_enabled = conf.getProperty('profile_http_parameter_enabled', true);
|
|
61
|
+
var profile_http_parameter_keys = conf.getProperty('profile_http_parameter_keys', '');
|
|
56
62
|
conf.on('trace_http_client_ip_header_key', function(newProperty) {
|
|
57
63
|
configIpHeaderKey = newProperty;
|
|
58
64
|
});
|
|
@@ -101,6 +107,15 @@ conf.on('httpc_not_found_ignore', function (newProps) {
|
|
|
101
107
|
conf.on('httpc_not_found_ignore_time', function (newProps) {
|
|
102
108
|
httpc_not_found_ignore_time = newProps;
|
|
103
109
|
})
|
|
110
|
+
conf.on('profile_http_header_ignore_keys', function (newProps) {
|
|
111
|
+
profile_http_header_ignore_keys = newProps;
|
|
112
|
+
})
|
|
113
|
+
conf.on('profile_http_parameter_enabled', function (newProps) {
|
|
114
|
+
profile_http_parameter_enabled = newProps;
|
|
115
|
+
})
|
|
116
|
+
conf.on('profile_http_parameter_keys', function (newProps) {
|
|
117
|
+
profile_http_parameter_keys = newProps;
|
|
118
|
+
})
|
|
104
119
|
var staticConents = function (newProps) {
|
|
105
120
|
var x=new Set();
|
|
106
121
|
var words = !newProps?[]:newProps.split(',');
|
|
@@ -121,7 +136,7 @@ conf.on('web_static_content_extensions', staticConents);
|
|
|
121
136
|
staticConents(conf["web_static_content_extensions"]);
|
|
122
137
|
|
|
123
138
|
var httpc_not_found_ignore_map = null;
|
|
124
|
-
var httpc_not_found_ignore_url =
|
|
139
|
+
var httpc_not_found_ignore_url = new Set();
|
|
125
140
|
|
|
126
141
|
var HttpObserver = function(agent){
|
|
127
142
|
this.agent = agent;
|
|
@@ -156,7 +171,7 @@ HttpObserver.prototype.__createTransactionObserver = function(callback, isHttps,
|
|
|
156
171
|
if(ctx == null) { return; }
|
|
157
172
|
PluginLoaderManager.do('httpserviceend', ctx, req, res);
|
|
158
173
|
|
|
159
|
-
var not_found_ignore = httpc_not_found_ignore_url.
|
|
174
|
+
var not_found_ignore = httpc_not_found_ignore_url.has(req.url);
|
|
160
175
|
if (httpc_not_found_ignore && !not_found_ignore && obj.statusCode === 404) {
|
|
161
176
|
const url_hash = HashUtil.hashFromString(req.url);
|
|
162
177
|
const currentTime = new Date().getTime();
|
|
@@ -324,10 +339,28 @@ function initCtx(req, res) {
|
|
|
324
339
|
var step = new MessageStep();
|
|
325
340
|
step.hash = HashUtil.hashFromString("HTTP-HEADERS");
|
|
326
341
|
step.start_time = ctx.getElapsedTime();
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
342
|
+
|
|
343
|
+
var header_ignore_key_set = new Set();
|
|
344
|
+
if(profile_http_header_ignore_keys) {
|
|
345
|
+
header_ignore_key_set = new Set(profile_http_header_ignore_keys.split(','));
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
try{
|
|
349
|
+
step.desc = Object.keys(req.headers).map(function (key) {
|
|
350
|
+
if (!header_ignore_key_set.has(key)) {
|
|
351
|
+
return `${key}=${req.headers[key]}`;
|
|
352
|
+
}
|
|
353
|
+
}).filter(element => {
|
|
354
|
+
if (element) return element
|
|
355
|
+
}).join('\n');
|
|
356
|
+
|
|
357
|
+
DataTextAgent.MESSAGE.add(step.hash, "HTTP-HEADERS");
|
|
358
|
+
ctx.profile.push(step);
|
|
359
|
+
}catch (e) {
|
|
360
|
+
step = null;
|
|
361
|
+
header_ignore_key_set = null;
|
|
362
|
+
Logger.printError('WHATAP-614', 'Header parsing error', e, false);
|
|
363
|
+
}
|
|
331
364
|
}
|
|
332
365
|
/************************************/
|
|
333
366
|
/* Multi Server Transaction Trace */
|
|
@@ -391,21 +424,33 @@ HttpObserver.prototype.__endTransaction = function(error, ctx, req, res) {
|
|
|
391
424
|
}
|
|
392
425
|
}
|
|
393
426
|
|
|
394
|
-
if(param_enabled) {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
427
|
+
if (param_enabled && req.query && Object.keys(req.query).length > 0) {
|
|
428
|
+
const query = req.query;
|
|
429
|
+
let secureMsgStep = new SecureMsgStep(ctx.getElapsedTime());
|
|
430
|
+
secureMsgStep.hash = HashUtil.hashFromString("HTTP-PARAMETERS");
|
|
431
|
+
|
|
432
|
+
const profileHttpParameterKeysSet = profile_http_parameter_keys ? new Set(profile_http_parameter_keys.split(',')) : null;
|
|
433
|
+
|
|
434
|
+
try {
|
|
435
|
+
const desc = Object.entries(query)
|
|
436
|
+
.filter(([key]) => !profileHttpParameterKeysSet || profileHttpParameterKeysSet.has(key))
|
|
437
|
+
.map(([key, value]) => `${key}=${value}`)
|
|
438
|
+
.join('\n');
|
|
439
|
+
|
|
440
|
+
if (desc) {
|
|
441
|
+
const crc = { value: 0 };
|
|
442
|
+
secureMsgStep.value = toParamBytes(desc, crc);
|
|
443
|
+
secureMsgStep.crc = crc.value;
|
|
444
|
+
|
|
445
|
+
DataTextAgent.MESSAGE.add(secureMsgStep.hash, "HTTP-PARAMETERS");
|
|
446
|
+
ctx.profile.push(secureMsgStep);
|
|
447
|
+
} else {
|
|
448
|
+
secureMsgStep = null;
|
|
449
|
+
}
|
|
450
|
+
} catch (e) {
|
|
451
|
+
secureMsgStep = null;
|
|
452
|
+
Logger.printError('WHATAP-613', 'Parameter parsing error', e, false);
|
|
406
453
|
}
|
|
407
|
-
DataTextAgent.MESSAGE.add(step.hash, "HTTP-PARAMETERS");
|
|
408
|
-
ctx.profile.push(step);
|
|
409
454
|
}
|
|
410
455
|
|
|
411
456
|
if(profile_error_step_enabled && ctx.statusMessage){
|
|
@@ -823,7 +868,7 @@ function updateNotFoundIgnoreMap(url, url_hash, currentTime) {
|
|
|
823
868
|
}
|
|
824
869
|
|
|
825
870
|
if (ignore_value.count >= 50) {
|
|
826
|
-
httpc_not_found_ignore_url.
|
|
871
|
+
httpc_not_found_ignore_url.add(url);
|
|
827
872
|
httpc_not_found_ignore_map.remove(url_hash);
|
|
828
873
|
Logger.print('WHATAP-610', "The ignore option for URL " + url + " is applied.", false);
|
|
829
874
|
}
|
|
@@ -839,4 +884,15 @@ function shouldEndCurrentTransaction(not_found_ignore, ctx, res, requestPath) {
|
|
|
839
884
|
return !is_ignore;
|
|
840
885
|
}
|
|
841
886
|
|
|
887
|
+
var toParamBytes = function (p, crc) {
|
|
888
|
+
if (p == null || p.length === 0) {
|
|
889
|
+
return null;
|
|
890
|
+
}
|
|
891
|
+
try {
|
|
892
|
+
return ParamSecurity.encrypt(Buffer.from(p, 'utf8'), crc);
|
|
893
|
+
} catch (e) {
|
|
894
|
+
return null;
|
|
895
|
+
}
|
|
896
|
+
};
|
|
897
|
+
|
|
842
898
|
exports.HttpObserver = HttpObserver;
|
|
@@ -24,6 +24,7 @@ var TraceContextManager = require('../trace/trace-context-manager'),
|
|
|
24
24
|
DateUtil = require('../util/dateutil'),
|
|
25
25
|
Buffer = require('buffer').Buffer,
|
|
26
26
|
MessageStep = require("../step/message-step");
|
|
27
|
+
// const ResourceProfile = require("../util/resourceprofile");
|
|
27
28
|
|
|
28
29
|
var MariaObserver = function (agent) {
|
|
29
30
|
this.agent = agent;
|
|
@@ -145,6 +146,11 @@ var queryHook = function (dbc, agent) {
|
|
|
145
146
|
sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
|
|
146
147
|
ctx.sql_time += sql_step.elapsed;
|
|
147
148
|
|
|
149
|
+
// if(conf.getProperty('profile_sql_resource_enabled', false)){
|
|
150
|
+
// sql_step.start_cpu = ResourceProfile.getCPUTime();
|
|
151
|
+
// sql_step.start_mem = ResourceProfile.getUsedHeapSize();
|
|
152
|
+
// }
|
|
153
|
+
|
|
148
154
|
ctx.footprint('Maria Query Done');
|
|
149
155
|
|
|
150
156
|
MeterSql.add(dbc_hash, sql_step.elapsed, false);
|
|
@@ -136,15 +136,21 @@ MongooseObserver.prototype.inject = function (mod, modName) {
|
|
|
136
136
|
|
|
137
137
|
const mongooseCollection = _ret.mongooseCollection;
|
|
138
138
|
try {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
139
|
+
if(mongooseCollection && mongooseCollection.modelName){
|
|
140
|
+
var sql = mongooseCollection.modelName + ' ' + _ret.op;//+ ': ' + JSON.stringify(Object.keys(args[0]));
|
|
141
|
+
if (_args[0]) {
|
|
142
|
+
sql += ' field=' + JSON.stringify(Object.keys(_args[0]));
|
|
143
|
+
}
|
|
144
|
+
if (_args[1]) {
|
|
145
|
+
sql += ' value=' + JSON.stringify(Object.keys(_args[1]));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
sql_step.hash = HashUtil.hashFromString(sql);
|
|
149
|
+
sql_step.start_time = ctx.getElapsedTime();
|
|
150
|
+
sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
|
|
151
|
+
DataTextAgent.SQL.add(sql_step.hash, sql);
|
|
152
|
+
ctx.profile.push(sql_step);
|
|
153
|
+
}
|
|
148
154
|
} catch(e) {
|
|
149
155
|
Logger.printError("WHATAP-611", "Mongodb query error", e, false);
|
|
150
156
|
sql_step = null;
|
|
@@ -22,6 +22,7 @@ var TraceContextManager = require('../trace/trace-context-manager'),
|
|
|
22
22
|
Logger = require('../logger');
|
|
23
23
|
const DateUtil = require('../util/dateutil');
|
|
24
24
|
const MessageStep = require("../step/message-step");
|
|
25
|
+
// const ResourceProfile = require("../util/resourceprofile");
|
|
25
26
|
|
|
26
27
|
var MssqlObserver = function (agent) {
|
|
27
28
|
this.agent = agent;
|
|
@@ -126,6 +127,11 @@ MssqlObserver.prototype.inject = function (mod, modName) {
|
|
|
126
127
|
StatSql.addSqlTime(ctx.service_hash, sql_step.dbc,
|
|
127
128
|
sql_step.hash, sql_step.elapsed, args[0] != null, 0);
|
|
128
129
|
|
|
130
|
+
// if(conf.getProperty('profile_sql_resource_enabled', false)){
|
|
131
|
+
// sql_step.start_cpu = ResourceProfile.getCPUTime();
|
|
132
|
+
// sql_step.start_mem = ResourceProfile.getUsedHeapSize();
|
|
133
|
+
// }
|
|
134
|
+
|
|
129
135
|
if(psql && psql.type == 'S') {
|
|
130
136
|
var result_step = new ResultSetStep();
|
|
131
137
|
result_step.dbc = sql_step.dbc;
|
|
@@ -24,6 +24,7 @@ var TraceContextManager = require('../trace/trace-context-manager'),
|
|
|
24
24
|
DateUtil = require('../util/dateutil'),
|
|
25
25
|
Buffer = require('buffer').Buffer,
|
|
26
26
|
MessageStep = require("../step/message-step");
|
|
27
|
+
// const ResourceProfile = require('../util/resourceprofile');
|
|
27
28
|
|
|
28
29
|
var MysqlObserver = function (agent) {
|
|
29
30
|
this.agent = agent;
|
|
@@ -167,6 +168,11 @@ var queryHook = function (dbc, agent) {
|
|
|
167
168
|
sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
|
|
168
169
|
ctx.sql_time += sql_step.elapsed;
|
|
169
170
|
|
|
171
|
+
// if(conf.getProperty('profile_sql_resource_enabled', false)){
|
|
172
|
+
// sql_step.start_cpu = ResourceProfile.getCPUTime();
|
|
173
|
+
// sql_step.start_mem = ResourceProfile.getUsedHeapSize();
|
|
174
|
+
// }
|
|
175
|
+
|
|
170
176
|
ctx.footprint('MySql Query Done');
|
|
171
177
|
|
|
172
178
|
MeterSql.add(dbc_hash, sql_step.elapsed, false);
|
|
@@ -360,7 +366,7 @@ MysqlObserver.prototype.inject = function (mod, moduleName) {
|
|
|
360
366
|
|
|
361
367
|
var dbc_pool_hash = 0;
|
|
362
368
|
aop.after(mod, ['createPool', 'createPoolCluster'], function (obj, args, ret) {
|
|
363
|
-
if (dbc_pool_hash == 0) {
|
|
369
|
+
if (dbc_pool_hash == 0 && dbc === 'mysql://') {
|
|
364
370
|
if (args.length > 0) {
|
|
365
371
|
var info = args[0];
|
|
366
372
|
//Open [DatabaseName] connection 메세지 보여줄때 필요함.
|
|
@@ -24,6 +24,7 @@ var TraceContextManager = require('../trace/trace-context-manager'),
|
|
|
24
24
|
Buffer = require('buffer').Buffer,
|
|
25
25
|
DateUtil = require('../util/dateutil'),
|
|
26
26
|
MessageStep = require("../step/message-step");
|
|
27
|
+
// const ResourceProfile = require("../util/resourceprofile");
|
|
27
28
|
|
|
28
29
|
var PgSqlObserver = function (agent) {
|
|
29
30
|
this.agent = agent;
|
|
@@ -134,6 +135,12 @@ var queryHook = function (dbc_local, agent) {
|
|
|
134
135
|
|
|
135
136
|
sql_step.elapsed = ctx.getElapsedTime() - sql_step.start_time;
|
|
136
137
|
ctx.sql_time += sql_step.elapsed;
|
|
138
|
+
|
|
139
|
+
// if(conf.getProperty('profile_sql_resource_enabled', false)){
|
|
140
|
+
// sql_step.start_cpu = ResourceProfile.getCPUTime();
|
|
141
|
+
// sql_step.start_mem = ResourceProfile.getUsedHeapSize();
|
|
142
|
+
// }
|
|
143
|
+
|
|
137
144
|
ctx.footprint('PgSql Query Done');
|
|
138
145
|
|
|
139
146
|
MeterSql.add(dbc_hash, sql_step.elapsed, false);
|
|
@@ -4,51 +4,179 @@
|
|
|
4
4
|
* can be found in the LICENSE file.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
var MeterSocketio = require('../counter/meter/meter-socket.io')
|
|
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', false);
|
|
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
|
+
})
|
|
8
39
|
|
|
9
40
|
var SocketIOObserver = function(agent){
|
|
10
41
|
this.agent = agent;
|
|
11
42
|
this.packages = ['socket.io'];
|
|
12
43
|
};
|
|
13
44
|
|
|
14
|
-
|
|
45
|
+
var socket_count = {
|
|
46
|
+
count: 0,
|
|
47
|
+
start_time: null
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
SocketIOObserver.prototype.inject = function (mod, moduleName) {
|
|
51
|
+
if (mod.__whatap_observe__) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
mod.__whatap_observe__ = true;
|
|
55
|
+
Logger.initPrint("SocketIOObserver");
|
|
56
|
+
|
|
15
57
|
var self = this;
|
|
16
58
|
var aop = self.agent.aop;
|
|
17
59
|
|
|
18
|
-
|
|
19
|
-
|
|
60
|
+
aop.after(mod.Server.prototype, 'on', function (obj, args, ret, lctx) {
|
|
61
|
+
aop.after(mod.Socket.prototype, 'emit', 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
|
+
}
|
|
20
70
|
|
|
21
|
-
|
|
22
|
-
|
|
71
|
+
if ((now - socket_count.start_time) > 5000) {
|
|
72
|
+
socket_count.start_time = now;
|
|
73
|
+
socket_count.count = 0;
|
|
74
|
+
}
|
|
23
75
|
|
|
24
|
-
|
|
25
|
-
|
|
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
|
+
}
|
|
26
82
|
|
|
27
|
-
|
|
28
|
-
|
|
83
|
+
TraceContextManager._asyncLocalStorage.run(initCtx(_obj, _args), () => {
|
|
84
|
+
try{
|
|
85
|
+
var ctx = TraceContextManager._asyncLocalStorage.getStore();
|
|
86
|
+
if (!ctx) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
29
89
|
|
|
30
|
-
|
|
90
|
+
var socket = _obj;
|
|
91
|
+
var host;
|
|
92
|
+
if (socket.handshake && socket.handshake.address && socket.handshake.address.includes(':')) {
|
|
93
|
+
host = socket.handshake.address.substring(socket.handshake.address.lastIndexOf(':') + 1);
|
|
94
|
+
}
|
|
31
95
|
|
|
32
|
-
|
|
96
|
+
ctx.socket_connecting = true;
|
|
97
|
+
ctx.footprint('Socket Connecting: ' + host);
|
|
33
98
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
99
|
+
var step = new SocketStep();
|
|
100
|
+
step.start_time = ctx.getElapsedTime();
|
|
101
|
+
step.ipaddr = Buffer.from(IPUtil.stringToBytes(host));
|
|
102
|
+
// step.port = port;
|
|
37
103
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
});
|
|
104
|
+
ctx.socket_connecting = false;
|
|
105
|
+
step.elapsed = ctx.getElapsedTime() - step.start_time;
|
|
106
|
+
ctx.profile.push(step);
|
|
42
107
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
108
|
+
ctx.footprint('Socket Connecting Done');
|
|
109
|
+
|
|
110
|
+
self.__endTransaction(null, ctx);
|
|
111
|
+
return;
|
|
112
|
+
}catch (e) {
|
|
113
|
+
Logger.printError('WHATAP-616', 'socket.io transaction error..', e, false);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
49
116
|
});
|
|
50
117
|
});
|
|
51
118
|
});
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
SocketIOObserver.prototype.__endTransaction = function(error, ctx) {
|
|
122
|
+
try {
|
|
123
|
+
var profile = new ProfilePack();
|
|
124
|
+
var wtx = new TxRecord();
|
|
125
|
+
wtx.endTime = DateUtil.currentTime();
|
|
126
|
+
profile.time = wtx.endTime;
|
|
127
|
+
wtx.elapsed = ctx.getElapsedTime();
|
|
128
|
+
|
|
129
|
+
DataTextAgent.SERVICE.add(ctx.service_hash, ctx.service_name);
|
|
130
|
+
|
|
131
|
+
wtx.seq = ctx.txid;
|
|
132
|
+
wtx.service = ctx.service_hash;
|
|
133
|
+
wtx.cpuTime = ResourceProfile.getCPUTime() - ctx.start_cpu;
|
|
134
|
+
wtx.malloc = ResourceProfile.getUsedHeapSize()-ctx.start_malloc;
|
|
135
|
+
if(wtx.malloc < 0) { wtx.malloc = 0; }
|
|
136
|
+
wtx.status = 2;
|
|
137
|
+
|
|
138
|
+
wtx.ipaddr = ctx.remoteIp;
|
|
139
|
+
|
|
140
|
+
MeterService.add(wtx.service, wtx.elapsed,
|
|
141
|
+
wtx.errorLevel, ctx.mcaller_pcode, ctx.mcaller_okind, ctx.mcaller_oid);
|
|
142
|
+
|
|
143
|
+
profile.oid = SecurityMaster.OID;
|
|
144
|
+
profile.service = wtx;
|
|
145
|
+
|
|
146
|
+
TraceContextManager.end(ctx._id);
|
|
147
|
+
|
|
148
|
+
setTimeout(function () {
|
|
149
|
+
DataProfileAgent.sendProfile(ctx, profile, false);
|
|
150
|
+
TraceContextManager.end(ctx._id);
|
|
151
|
+
ctx = null;
|
|
152
|
+
}, 100);
|
|
153
|
+
} catch (e) {
|
|
154
|
+
Logger.printError('WHATAP-615', 'Socket.io end transaction error..', e, false);
|
|
155
|
+
TraceContextManager.end(ctx._id);
|
|
156
|
+
ctx = null;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
function initCtx(socket, args) {
|
|
162
|
+
const ctx = TraceContextManager.start();
|
|
163
|
+
if (!ctx) {return;}
|
|
164
|
+
|
|
165
|
+
var remote_addr;
|
|
166
|
+
const address = socket.handshake.address;
|
|
167
|
+
if(address && address.includes(':')){
|
|
168
|
+
remote_addr = address.substring(address.lastIndexOf(':')+1);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
ctx.start_malloc = ResourceProfile.getUsedHeapSize();
|
|
172
|
+
ctx.start_cpu = ResourceProfile.getCPUTime();
|
|
173
|
+
|
|
174
|
+
remote_addr=IPUtil.checkIp4(remote_addr);
|
|
175
|
+
ctx.remoteIp = IPUtil.stringToInt(remote_addr);
|
|
176
|
+
ctx.userid = Long.fromNumber(ctx.remoteIp);
|
|
177
|
+
MeterUsers.add(ctx.userid);
|
|
178
|
+
|
|
179
|
+
return ctx;
|
|
52
180
|
}
|
|
53
181
|
|
|
54
182
|
exports.SocketIOObserver = SocketIOObserver;
|
package/lib/pack/packenum.js
CHANGED
|
@@ -4,58 +4,60 @@
|
|
|
4
4
|
* can be found in the LICENSE file.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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;
|
|
@@ -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, '
|
|
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())) {
|
|
@@ -54,7 +54,7 @@ ParamSecurity.prototype.reload = function () {
|
|
|
54
54
|
var printWriter = fs.createWriteStream(file, {flags : 'w'});
|
|
55
55
|
printWriter.write(self.key);
|
|
56
56
|
self.key = Buffer.from(self.key);
|
|
57
|
-
}
|
|
57
|
+
}
|
|
58
58
|
};
|
|
59
59
|
ParamSecurity.prototype.encrypt = function (b, crc) {
|
|
60
60
|
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