UNPKG

7.54 kBJavaScriptView Raw
1(function (window) {
2 'use strict';
3
4 function StatfulUtil(config) {
5 config = config || {};
6 var self = this;
7 var logger;
8
9 //Merge configs
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 * Sends HTTP request to the api
27 * @param {string} endpoint - action
28 * @param {string} requestData - request data
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 //Send the proper header information along with the request
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 * Register a new queue
55 * @param {string} queueName - queue name
56 * @param {string} endpoint - endpoint to send requests
57 * @param {int} timeInterval - interval in milliseconds, default 30000 ms
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 * Unregister queue
92 * @param {string} queueName - queue name
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 * Sends an Item to a specific queue
103 * @param {string} queueName - queue name
104 * @param {object} item - object to be sent
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 * Define aggregations for a metric type
120 * @param {Array} methodAggregations - list of method aggregations
121 * @param {Array} globalAggregations - list of global aggregations
122 * @param {Array} typeAggregations - list of type aggregations
123 * @returns {*|Array}
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 * Define tags for a metric type
145 * @param {object} methodTags - list of method tags
146 * @param {object} globalTags - list of global tags
147 * @param {string} typeTags - list of type tags
148 * @param {string} app - app tag value
149 * @returns {*}
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 * Define aggregation frequency
175 * @param {number} methodFrequency - method aggregation frequency
176 * @param {number} globalFrequency - global aggregation frequency
177 * @param {number} typeFrequency - type aggregation frequency
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 * Filter unsupported aggregations
195 * @param {Array} aggregations - list of aggregations
196 * @returns {Array}
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 * Filter unsupported frequencies
210 * @param {number} frequency - aggregation frequency
211 * @returns {*}
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);