1 | (function (window) {
|
2 | 'use strict';
|
3 |
|
4 | function StatfulUtil(config) {
|
5 | config = config || {};
|
6 | var self = this;
|
7 | var logger;
|
8 |
|
9 |
|
10 | this.config = {};
|
11 |
|
12 | this.constants = {
|
13 | aggregationList: ['avg', 'count', 'sum', 'first', 'last', 'p90', 'p95', 'min', 'max'],
|
14 | aggregationFrequencyList: [10, 30, 60, 120, 180, 300]
|
15 | };
|
16 |
|
17 | Object.keys(config).forEach(function (key) {
|
18 | self.config[key] = config[key];
|
19 | });
|
20 |
|
21 | this.listQueues = [];
|
22 |
|
23 | logger = new StatfulLogger(self.config.debug);
|
24 |
|
25 | |
26 |
|
27 |
|
28 |
|
29 |
|
30 | this.sendRequest = function (endpoint, requestData) {
|
31 | var requestArr = [this.config.apiAddress, endpoint];
|
32 | var requestUrl = requestArr.join('/');
|
33 |
|
34 | logger.debug('Request: ' + requestUrl, requestData);
|
35 |
|
36 | var xmlHttp = new XMLHttpRequest();
|
37 | xmlHttp.open('POST', requestUrl, true);
|
38 | xmlHttp.timeout = config.timeout;
|
39 |
|
40 |
|
41 | xmlHttp.setRequestHeader('Content-type', 'application/json');
|
42 | xmlHttp.send(requestData);
|
43 |
|
44 | xmlHttp.onreadystatechange = function () {
|
45 | if (xmlHttp.status == 200 || xmlHttp.status == 201) {
|
46 | logger.debug('Successfully send metric');
|
47 | } else {
|
48 | logger.debug('Error send metric', requestUrl, xmlHttp.status);
|
49 | }
|
50 | };
|
51 | };
|
52 |
|
53 | |
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 | this.registerQueue = function (queueName, endpoint, timeInterval) {
|
60 | timeInterval = timeInterval || this.config.flushInterval;
|
61 |
|
62 | if (typeof queueName === 'string' && typeof timeInterval === 'number') {
|
63 | var self = this;
|
64 |
|
65 | this.listQueues[queueName] = {
|
66 | data: [],
|
67 | endpoint: endpoint
|
68 | };
|
69 |
|
70 | this.listQueues[queueName].timer = setInterval(function () {
|
71 | var queue = self.listQueues[queueName];
|
72 |
|
73 | if (queue.data.length > 0) {
|
74 | if (!self.config.dryrun) {
|
75 | self.sendRequest(queue.endpoint, JSON.stringify(queue.data));
|
76 | } else {
|
77 | logger.debug('Dryrun data', queue.endpoint, queue.data);
|
78 | }
|
79 | queue.data = [];
|
80 | }
|
81 |
|
82 | }, timeInterval);
|
83 |
|
84 | return true;
|
85 | } else {
|
86 | return false;
|
87 | }
|
88 | };
|
89 |
|
90 | |
91 |
|
92 |
|
93 |
|
94 | this.unregisterQueue = function (queueName) {
|
95 | if (this.listQueues[queueName]) {
|
96 | clearInterval(this.listQueues[queueName].timer);
|
97 | this.listQueues[queueName] = undefined;
|
98 | }
|
99 | };
|
100 |
|
101 | |
102 |
|
103 |
|
104 |
|
105 |
|
106 | this.addItemToQueue = function (queueName, item) {
|
107 | var sampleRateNormalized = (item.sampleRate || this.config.sampleRate || 100) / 100;
|
108 |
|
109 | if (this.listQueues[queueName] && Math.random() <= sampleRateNormalized) {
|
110 | this.listQueues[queueName].data.push(item);
|
111 | return true;
|
112 | } else {
|
113 | logger.debug('Metric was discarded due to sample rate.');
|
114 | return false;
|
115 | }
|
116 | };
|
117 |
|
118 | |
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 | this.setAggregations = function (methodAggregations, globalAggregations, typeAggregations) {
|
126 | function uniq(item, index, array) {
|
127 | return item && array.indexOf(item) === index;
|
128 | }
|
129 |
|
130 | var aggregations = globalAggregations;
|
131 |
|
132 | aggregations = aggregations.concat(typeAggregations).filter(uniq);
|
133 |
|
134 | if (!methodAggregations) {
|
135 | aggregations = aggregations || [];
|
136 | } else {
|
137 | aggregations = aggregations.concat(methodAggregations).filter(uniq);
|
138 | }
|
139 |
|
140 | return this.filterAggregations(aggregations);
|
141 | };
|
142 |
|
143 | |
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 |
|
150 |
|
151 | this.setTags = function (methodTags, globalTags, typeTags, app) {
|
152 | var tags = {};
|
153 |
|
154 | Object.keys(globalTags).forEach(function (key) {
|
155 | tags[key] = globalTags[key];
|
156 | });
|
157 |
|
158 | Object.keys(typeTags).forEach(function (key) {
|
159 | tags[key] = typeTags[key];
|
160 | });
|
161 |
|
162 | Object.keys(methodTags).forEach(function (key) {
|
163 | tags[key] = methodTags[key];
|
164 | });
|
165 |
|
166 | if (!tags.app && app) {
|
167 | tags.app = app;
|
168 | }
|
169 |
|
170 | return tags;
|
171 | };
|
172 |
|
173 | |
174 |
|
175 |
|
176 |
|
177 |
|
178 |
|
179 | this.setAggregationFrequency = function (methodFrequency, globalFrequency, typeFrequency) {
|
180 | var frequency = globalFrequency;
|
181 |
|
182 | if (typeFrequency) {
|
183 | frequency = typeFrequency;
|
184 | }
|
185 |
|
186 | if (methodFrequency) {
|
187 | frequency = methodFrequency;
|
188 | }
|
189 |
|
190 | return this.filterAggregationFrequency(frequency);
|
191 | };
|
192 |
|
193 | |
194 |
|
195 |
|
196 |
|
197 |
|
198 | this.filterAggregations = function (aggregations) {
|
199 | var agg = this.constants.aggregationList;
|
200 |
|
201 | aggregations = aggregations || [];
|
202 |
|
203 | return aggregations.filter(function (item) {
|
204 | return agg.indexOf(item) !== -1;
|
205 | });
|
206 | };
|
207 |
|
208 | |
209 |
|
210 |
|
211 |
|
212 |
|
213 | this.filterAggregationFrequency = function (frequency) {
|
214 | var frequencyList = this.constants.aggregationFrequencyList;
|
215 | var freq = 10;
|
216 |
|
217 | if (frequencyList.indexOf(frequency) > -1) {
|
218 | freq = frequency;
|
219 | }
|
220 |
|
221 | return freq;
|
222 | };
|
223 | }
|
224 |
|
225 | window.StatfulUtil = StatfulUtil;
|
226 |
|
227 | })(window);
|