UNPKG

4.27 kBJavaScriptView Raw
1/*
2 * Copyright (c) 2012 Dmitri Melikyan
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to permit
9 * persons to whom the Software is furnished to do so, subject to the
10 * following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
18 * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24
25var nt;
26var filterKeys;
27var sampleNum;
28
29exports.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
58var 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
80var 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
101var PredicateFilter = function() {
102}
103
104exports.PredicateFilter = PredicateFilter;
105
106
107PredicateFilter.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
130PredicateFilter.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
141function 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
166function 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