1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 | var nt;
|
26 | var filterKeys;
|
27 | var sampleNum;
|
28 |
|
29 | exports.init = function() {
|
30 | nt = global.nodetime;
|
31 |
|
32 | filterKeys = {};
|
33 | sampleNum = 0;
|
34 |
|
35 | nt.on('sample', function(sample) {
|
36 | if(!nt.headless && nt.sessionId) {
|
37 | collectKeys(undefined, sample, 0);
|
38 |
|
39 | sampleNum++;
|
40 | if(sampleNum == 1 || sampleNum == 10) {
|
41 | sendKeys();
|
42 | }
|
43 | }
|
44 | });
|
45 |
|
46 |
|
47 | setInterval(function() {
|
48 | try {
|
49 | sendKeys();
|
50 | }
|
51 | catch(e) {
|
52 | nt.error(e);
|
53 | }
|
54 | }, 60000);
|
55 | };
|
56 |
|
57 |
|
58 | var collectKeys = function(key, obj, depth) {
|
59 | if(depth > 20) return 0;
|
60 |
|
61 | var isArray = Array.isArray(obj);
|
62 | for(var prop in obj) {
|
63 | if(prop.match(/^\_/)) continue;
|
64 |
|
65 | if(typeof obj[prop] === 'object') {
|
66 | collectKeys(prop, obj[prop], depth + 1);
|
67 | }
|
68 | else {
|
69 | if(!isArray) {
|
70 | filterKeys[prop] = true;
|
71 | }
|
72 | else {
|
73 | filterKeys[key] = true;
|
74 | }
|
75 | }
|
76 | }
|
77 | };
|
78 |
|
79 |
|
80 | var sendKeys = function() {
|
81 | var keys = [];
|
82 | for(var prop in filterKeys) {
|
83 | keys.push(prop);
|
84 | }
|
85 |
|
86 | keys = keys.sort(function(a, b) {
|
87 | a = a.toLowerCase();
|
88 | b = b.toLowerCase();
|
89 |
|
90 | if(a > b) return 1;
|
91 | if(a < b) return -1;
|
92 | return 0;
|
93 | });
|
94 |
|
95 | if(keys.length > 0) {
|
96 | nt.agent.send({cmd: 'updateFilterKeys', args: keys});
|
97 | }
|
98 | };
|
99 |
|
100 |
|
101 | var PredicateFilter = function() {
|
102 | }
|
103 |
|
104 | exports.PredicateFilter = PredicateFilter;
|
105 |
|
106 |
|
107 | PredicateFilter.prototype.preparePredicates = function(preds) {
|
108 | preds.forEach(function(pred) {
|
109 | try{
|
110 | pred.valNum = parseFloat(pred.val)
|
111 | }
|
112 | catch(err) {
|
113 | }
|
114 |
|
115 | try{
|
116 | if(pred.op === 'match') pred.valRe = new RegExp(pred.val);
|
117 | if(typeof pred.val === 'string') pred.valLc = pred.val.toLowerCase();
|
118 | }
|
119 | catch(err) {
|
120 | return nt.error(err);
|
121 | }
|
122 | });
|
123 |
|
124 | this.preds = preds;
|
125 |
|
126 | return true;
|
127 | }
|
128 |
|
129 |
|
130 | PredicateFilter.prototype.filter = function(sample) {
|
131 | var matched = 0;
|
132 |
|
133 | this.preds.forEach(function(pred) {
|
134 | matched += walk(pred, sample, 0);
|
135 | });
|
136 |
|
137 | return (matched > 0);
|
138 | };
|
139 |
|
140 |
|
141 | function walk(pred, obj, depth) {
|
142 | if(depth > 20) return 0;
|
143 |
|
144 | var matched = 0;
|
145 |
|
146 | for(var prop in obj) {
|
147 | var val = obj[prop];
|
148 |
|
149 | if(val === undefined || val === null) {
|
150 | continue;
|
151 | }
|
152 | else if(typeof val === 'object') {
|
153 | matched += walk(pred, val, depth + 1);
|
154 | }
|
155 | else if((pred.key === '*' || pred.key === prop) && test(pred, val)) {
|
156 | matched++;
|
157 | }
|
158 |
|
159 | if(matched) break;
|
160 | }
|
161 |
|
162 | return matched;
|
163 | }
|
164 |
|
165 |
|
166 | function test(pred, val) {
|
167 | var ret = false;
|
168 |
|
169 | if(typeof val === 'number') {
|
170 | if(pred.valNum !== NaN) {
|
171 | if (pred.op === '==') {
|
172 | ret = (val == pred.valNum);
|
173 | }
|
174 | else if (pred.op === '!=') {
|
175 | ret = (val != pred.valNum);
|
176 | }
|
177 | else if (pred.op === '<') {
|
178 | ret = (val < pred.valNum);
|
179 | }
|
180 | else if (pred.op === '>') {
|
181 | ret = (val > pred.valNum);
|
182 | }
|
183 | }
|
184 | }
|
185 | else if(typeof val === 'string') {
|
186 | if(pred.op === 'match' && pred.valRe) {
|
187 | ret = pred.valRe.exec(val);
|
188 | }
|
189 | else if (pred.op === '==') {
|
190 | ret = (val.toLowerCase() == pred.valLc);
|
191 | }
|
192 | else if (pred.op === '!=') {
|
193 | ret = (val.toLowerCase() != pred.valLc);
|
194 | }
|
195 | }
|
196 |
|
197 | return ret;
|
198 | }
|
199 |
|