whatap 0.4.95 → 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.
- package/lib/conf/config-default.js +4 -2
- package/lib/core/agent.js +2 -0
- package/lib/observers/http-observer.js +25 -12
- package/lib/observers/socket.io-observer.js +1 -1
- package/lib/observers/websocket-observer.js +195 -0
- package/lib/trace/trace-context-manager.js +2 -0
- package/lib/util/paramsecurity.js +2 -1
- package/package.json +2 -2
|
@@ -65,7 +65,7 @@ var ConfigDefault = {
|
|
|
65
65
|
"profile_http_header_url_prefix": "/",
|
|
66
66
|
"profile_connection_open_enabled": true,
|
|
67
67
|
"profile_zip_enabled": bool('profile_zip_enabled', false),
|
|
68
|
-
"profile_zip_queue_size": num('profile_zip_queue_size',
|
|
68
|
+
"profile_zip_queue_size": num('profile_zip_queue_size', 500),
|
|
69
69
|
"profile_zip_max_buffer_size": num('profile_zip_max_buffer_size', 1024*1024),
|
|
70
70
|
"profile_zip_min_size": num('profile_zip_min_size', 100),
|
|
71
71
|
"debug_profile_zip_enabled": bool('debug_profile_zip_enabled', false),
|
|
@@ -107,7 +107,7 @@ var ConfigDefault = {
|
|
|
107
107
|
"trace_sql_error_depth": num('trace_sql_error_depth', 50),
|
|
108
108
|
"transaction_status_error_enable": bool("transaction_status_error_enable", true),
|
|
109
109
|
|
|
110
|
-
"trace_sampling_enabled": bool("trace_sampling_enabled",
|
|
110
|
+
"trace_sampling_enabled": bool("trace_sampling_enabled", true),
|
|
111
111
|
"trace_sampling_tps": bool("trace_sampling_tps", 1000),
|
|
112
112
|
|
|
113
113
|
"profile_error_sql_time_max": num("profile_error_sql_time_max", 30000),
|
|
@@ -154,6 +154,8 @@ var ConfigDefault = {
|
|
|
154
154
|
"httpc_not_found_ignore": bool('httpc_not_found_ignore', false),
|
|
155
155
|
"httpc_not_found_ignore_time": num('httpc_not_found_ignore', 300000),
|
|
156
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/'),
|
|
157
159
|
|
|
158
160
|
//2017.05.02 AUTO ONAME
|
|
159
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);
|
|
@@ -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
|
|
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
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
}
|
|
819
|
-
|
|
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',
|
|
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;
|
|
@@ -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; }
|
|
@@ -50,7 +50,8 @@ 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);
|
package/package.json
CHANGED