mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	add client-metrics endpoint and in-memory client-metrics
This commit is contained in:
		
							parent
							
								
									bc5a7cd877
								
							
						
					
					
						commit
						44f5d5edd4
					
				
							
								
								
									
										97
									
								
								packages/unleash-api/lib/client-metrics.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								packages/unleash-api/lib/client-metrics.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,97 @@ | |||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | module.exports = class UnleashClientMetrics { | ||||||
|  |     constructor () { | ||||||
|  |         this.globalCount = 0; | ||||||
|  |         this.apps = []; | ||||||
|  |         this.clients = {}; | ||||||
|  |         this.strategies = {}; | ||||||
|  |         this.store = {}; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     toJSON () { | ||||||
|  |         return JSON.stringify(this.getState(), null, 4); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     getState () { | ||||||
|  |         // TODO this payload will be WAY to big, need to flatten the store
 | ||||||
|  |         // and possibly evict/flag stale clients
 | ||||||
|  |         return { | ||||||
|  |             globalCount: this.globalCount, | ||||||
|  |             apps: this.apps, | ||||||
|  |             clients: this.clients, | ||||||
|  |             strategies: this.strategies, | ||||||
|  |             store: this.store, | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     addPayload (data) { | ||||||
|  |         this.addApp(data.appName); | ||||||
|  |         this.addClient(data.appName, data.instanceId, data.clientInitTime); | ||||||
|  |         this.addStrategies(data.appName, data.strategies); | ||||||
|  |         this.addStore(data.appName, data.instanceId, data.store); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     addStore (appName, instanceId, instanceStore) { | ||||||
|  |         // TODO normalize time client-server-time / NTP?
 | ||||||
|  |         const normalizeTimeEntries = (entry) => Object.assign({ appName, instanceId }, entry); | ||||||
|  |         let count = 0; | ||||||
|  | 
 | ||||||
|  |         Object.keys(instanceStore).forEach((n) => { | ||||||
|  |             if (n.startsWith('_')) { | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             if (this.store[n]) { | ||||||
|  |                 this.store[n].yes = this.store[n].yes.concat(instanceStore[n].yes.map(normalizeTimeEntries)); | ||||||
|  |                 this.store[n].no = this.store[n].no.concat(instanceStore[n].no.map(normalizeTimeEntries)); | ||||||
|  |             } else { | ||||||
|  |                 this.store[n] = { | ||||||
|  |                     yes: instanceStore[n].yes.map(normalizeTimeEntries), | ||||||
|  |                     no: instanceStore[n].no.map(normalizeTimeEntries), | ||||||
|  |                 }; | ||||||
|  |             } | ||||||
|  |             count += (instanceStore[n].yes.length + instanceStore[n].no.length); | ||||||
|  |         }); | ||||||
|  |         this.addClientCount(instanceId, count); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     addStrategies (appName, strategyNames) { | ||||||
|  |         strategyNames.forEach((name) => { | ||||||
|  |             if (!this.strategies[name]) { | ||||||
|  |                 this.strategies[name] = {}; | ||||||
|  |             } | ||||||
|  |             this.strategies[name][appName] = true; | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     addClientCount (instanceId, count) { | ||||||
|  |         if (typeof count === 'number' && count > 0) { | ||||||
|  |             this.globalCount += count; | ||||||
|  |             if (this.clients[instanceId]) { | ||||||
|  |                 this.clients[instanceId].count += count; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     addClient (appName, instanceId, clientInitTime) { | ||||||
|  |         if (instanceId) { | ||||||
|  |             if (this.clients[instanceId]) { | ||||||
|  |                 this.clients[instanceId].ping = new Date(); | ||||||
|  |             } else { | ||||||
|  |                 this.clients[instanceId] = { | ||||||
|  |                     appName, | ||||||
|  |                     count: 0, | ||||||
|  |                     clientInit: clientInitTime, | ||||||
|  |                     init: new Date(), | ||||||
|  |                     ping: new Date(), | ||||||
|  |                 }; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     addApp (v) { | ||||||
|  |         if (v && !this.apps.includes(v)) { | ||||||
|  |             this.apps.push(v); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | }; | ||||||
| @ -6,4 +6,5 @@ exports.create = function (app, config) { | |||||||
|     require('./feature-archive')(app, config); |     require('./feature-archive')(app, config); | ||||||
|     require('./strategy')(app, config); |     require('./strategy')(app, config); | ||||||
|     require('./health-check')(app, config); |     require('./health-check')(app, config); | ||||||
|  |     require('./metrics')(app, config); | ||||||
| }; | }; | ||||||
|  | |||||||
							
								
								
									
										24
									
								
								packages/unleash-api/lib/routes/metrics.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								packages/unleash-api/lib/routes/metrics.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | |||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | const logger = require('../logger'); | ||||||
|  | const ClientMetrics = require('../client-metrics'); | ||||||
|  | 
 | ||||||
|  | module.exports = function (app) { | ||||||
|  |     const metrics = new ClientMetrics(); | ||||||
|  | 
 | ||||||
|  |     app.get('/metrics', (req, res) => { | ||||||
|  |         res.json(metrics.getState()); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     app.post('/metrics', (req, res) => { | ||||||
|  |         // TODO: validate input and reply with http errorcode
 | ||||||
|  |         try { | ||||||
|  |             const data = JSON.parse(req.body); | ||||||
|  |             metrics.addPayload(data); | ||||||
|  |         } catch (e) { | ||||||
|  |             logger.error('Error recieving metrics', e); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         res.end(); | ||||||
|  |     }); | ||||||
|  | }; | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user