2016-10-27 13:13:51 +02:00
|
|
|
'use strict';
|
|
|
|
|
2016-11-04 16:16:55 +01:00
|
|
|
const Projection = require('./projection.js');
|
|
|
|
const TTLList = require('./ttl-list.js');
|
|
|
|
|
2016-10-27 13:13:51 +02:00
|
|
|
module.exports = class UnleashClientMetrics {
|
|
|
|
constructor () {
|
|
|
|
this.globalCount = 0;
|
2016-11-04 16:16:55 +01:00
|
|
|
this.apps = {};
|
2016-10-27 13:13:51 +02:00
|
|
|
this.clients = {};
|
2016-10-27 15:16:27 +02:00
|
|
|
this.buckets = {};
|
2016-11-04 16:16:55 +01:00
|
|
|
|
|
|
|
this.hourProjectionValue = new Projection();
|
|
|
|
this.oneHourLruCache = new TTLList();
|
|
|
|
this.oneHourLruCache.on('expire', (toggles) => {
|
|
|
|
Object.keys(toggles).forEach(toggleName => {
|
|
|
|
this.hourProjectionValue.substract(toggleName, toggles[toggleName]);
|
|
|
|
});
|
|
|
|
});
|
2016-10-27 13:13:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
toJSON () {
|
2016-11-04 16:16:55 +01:00
|
|
|
return JSON.stringify(this.getMetricsOverview(), null, 4);
|
2016-10-27 13:13:51 +02:00
|
|
|
}
|
|
|
|
|
2016-11-04 16:16:55 +01:00
|
|
|
getMetricsOverview () {
|
2016-10-27 13:13:51 +02:00
|
|
|
return {
|
|
|
|
globalCount: this.globalCount,
|
|
|
|
apps: this.apps,
|
|
|
|
clients: this.clients,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-11-04 16:16:55 +01:00
|
|
|
getTogglesMetrics () {
|
|
|
|
return this.hourProjectionValue.getProjection();
|
|
|
|
}
|
|
|
|
|
2016-11-02 12:49:25 +01:00
|
|
|
addPayload (data) {
|
|
|
|
this.addClient(data.appName, data.instanceId);
|
2016-10-27 15:16:27 +02:00
|
|
|
this.addBucket(data.appName, data.instanceId, data.bucket);
|
2016-10-27 13:13:51 +02:00
|
|
|
}
|
|
|
|
|
2016-10-27 15:16:27 +02:00
|
|
|
addBucket (appName, instanceId, bucket) {
|
2016-10-27 13:13:51 +02:00
|
|
|
let count = 0;
|
2016-11-04 16:16:55 +01:00
|
|
|
// TODO stop should be createdAt
|
|
|
|
const { stop, toggles } = bucket;
|
2016-10-27 15:16:27 +02:00
|
|
|
|
2016-11-04 16:16:55 +01:00
|
|
|
Object.keys(toggles).forEach((n) => {
|
|
|
|
const entry = toggles[n];
|
|
|
|
this.hourProjectionValue.add(n, entry);
|
|
|
|
count += (entry.yes + entry.no);
|
2016-10-27 13:13:51 +02:00
|
|
|
});
|
2016-11-04 16:16:55 +01:00
|
|
|
|
|
|
|
this.oneHourLruCache.add(toggles, stop);
|
|
|
|
|
|
|
|
this.addClientCount(appName, instanceId, count);
|
2016-10-27 13:13:51 +02:00
|
|
|
}
|
|
|
|
|
2016-11-04 16:16:55 +01:00
|
|
|
addClientCount (appName, instanceId, count) {
|
2016-10-27 13:13:51 +02:00
|
|
|
if (typeof count === 'number' && count > 0) {
|
|
|
|
this.globalCount += count;
|
|
|
|
if (this.clients[instanceId]) {
|
|
|
|
this.clients[instanceId].count += count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-02 12:49:25 +01:00
|
|
|
addClient (appName, instanceId, started = new Date()) {
|
2016-11-04 16:16:55 +01:00
|
|
|
this.addApp(appName, instanceId);
|
2016-10-27 13:13:51 +02:00
|
|
|
if (instanceId) {
|
|
|
|
if (this.clients[instanceId]) {
|
|
|
|
this.clients[instanceId].ping = new Date();
|
|
|
|
} else {
|
|
|
|
this.clients[instanceId] = {
|
|
|
|
appName,
|
|
|
|
count: 0,
|
2016-11-02 12:49:25 +01:00
|
|
|
started,
|
2016-10-27 13:13:51 +02:00
|
|
|
init: new Date(),
|
|
|
|
ping: new Date(),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-04 16:16:55 +01:00
|
|
|
addApp (appName, instanceId) {
|
|
|
|
if (appName && !this.apps[appName]) {
|
|
|
|
this.apps[appName] = {
|
|
|
|
count: 0,
|
|
|
|
clients: [],
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (instanceId && !this.apps[appName].clients.includes(instanceId)) {
|
|
|
|
this.apps[appName].clients.push(instanceId);
|
2016-10-27 13:13:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|