Commit 911b60de authored by Nilanjan Daw's avatar Nilanjan Daw

Longterm metrics DB

Added support to save long term metrics to couchDB
parent 4cc7e9e3
...@@ -4,7 +4,8 @@ ...@@ -4,7 +4,8 @@
"master_address": "localhost", "master_address": "localhost",
"grunt_host": "https://www.namandixit.net/lovecraftian_nightmares/grunt", "grunt_host": "https://www.namandixit.net/lovecraftian_nightmares/grunt",
"couchdb_host": "localhost:5984", "couchdb_host": "localhost:5984",
"couchdb_db_name": "serverless", "function_db_name": "serverless",
"metrics_db_name": "metrics",
"network": { "network": {
"network_bridge": "hybrid_kafka-serverless", "network_bridge": "hybrid_kafka-serverless",
"internal": { "internal": {
......
...@@ -11,7 +11,7 @@ const fs = require('fs') ...@@ -11,7 +11,7 @@ const fs = require('fs')
const fetch = require('node-fetch'); const fetch = require('node-fetch');
let metadataDB = `http://${secrets.couchdb_username}:${secrets.couchdb_password}@${constants.couchdb_host}` let metadataDB = `http://${secrets.couchdb_username}:${secrets.couchdb_password}@${constants.couchdb_host}`
metadataDB = metadataDB + "/" + constants.couchdb_db_name + "/" metadataDB = metadataDB + "/" + constants.function_db_name + "/"
const kafka = require('kafka-node') const kafka = require('kafka-node')
const logger = libSupport.logger const logger = libSupport.logger
......
...@@ -8,7 +8,7 @@ const fetch = require('node-fetch') ...@@ -8,7 +8,7 @@ const fetch = require('node-fetch')
const constants = require('../constants.json') const constants = require('../constants.json')
const secrets = require('./secrets.json') const secrets = require('./secrets.json')
let metadataDB = `http://${secrets.couchdb_username}:${secrets.couchdb_password}@${constants.couchdb_host}` let metadataDB = `http://${secrets.couchdb_username}:${secrets.couchdb_password}@${constants.couchdb_host}`
metadataDB = metadataDB + "/" + constants.couchdb_db_name + "/" metadataDB = metadataDB + "/" + constants.function_db_name + "/"
const logger = libSupport.logger const logger = libSupport.logger
const registry_url = constants.registry_url const registry_url = constants.registry_url
......
...@@ -17,7 +17,7 @@ const apiSpec = require('./swagger.json'); ...@@ -17,7 +17,7 @@ const apiSpec = require('./swagger.json');
* URL to the couchdb database server used to store function metadata * URL to the couchdb database server used to store function metadata
*/ */
let metadataDB = `http://${secrets.couchdb_username}:${secrets.couchdb_password}@${constants.couchdb_host}` let metadataDB = `http://${secrets.couchdb_username}:${secrets.couchdb_password}@${constants.couchdb_host}`
metadataDB = metadataDB + "/" + constants.couchdb_db_name + "/" metadataDB = metadataDB + "/" + constants.function_db_name + "/"
const app = express() const app = express()
const libSupport = require('./lib') const libSupport = require('./lib')
...@@ -553,18 +553,7 @@ function autoscalar() { ...@@ -553,18 +553,7 @@ function autoscalar() {
} }
function periodicMetricBroadcast() {
let message = {}, flag = false
functionToResource.forEach((functionHeap, functionHash) => {
if (functionHeap.length > 0) {
message[functionHash] = functionHeap.length
libSupport.metrics.collectMetrics({type: "scale", value: functionHeap.length, functionHash: functionHash})
}
})
}
setInterval(libSupport.viterbi, 1000, functionBranchTree) setInterval(libSupport.viterbi, 1000, functionBranchTree)
setInterval(autoscalar, 1000); setInterval(autoscalar, 1000);
setInterval(dispatch, 1000); setInterval(dispatch, 1000);
// setInterval(periodicMetricBroadcast, 5000)
app.listen(port, () => logger.info(`Server listening on port ${port}!`)) app.listen(port, () => logger.info(`Server listening on port ${port}!`))
\ No newline at end of file
const constants = require('.././constants.json'); const constants = require('.././constants.json');
const secrets = require('./secrets.json')
const fetch = require('node-fetch');
const alpha = 0.99 const alpha = 0.99
let log_channel = constants.topics.log_channel, let log_channel = constants.topics.log_channel,
metrics = { } metrics = { }
let metricsDB = `http://${secrets.couchdb_username}:${secrets.couchdb_password}@${constants.couchdb_host}`
metricsDB = metricsDB + "/" + constants.metrics_db_name + "/"
let kafka = require('kafka-node'), let kafka = require('kafka-node'),
Producer = kafka.Producer, Producer = kafka.Producer,
client = new kafka.KafkaClient({ client = new kafka.KafkaClient({
...@@ -53,20 +58,15 @@ function collectMetrics(metric) { ...@@ -53,20 +58,15 @@ function collectMetrics(metric) {
* longterm - longterm data is held and averaged out over a period of time. * longterm - longterm data is held and averaged out over a period of time.
* longterm data is calculated using Expontential Moving Average (EMA) * longterm data is calculated using Expontential Moving Average (EMA)
*/ */
function broadcastMetrics() { async function broadcastMetrics() {
if (Object.keys(metrics).length !== 0) { if (Object.keys(metrics).length !== 0) {
for (let [functionHash, metric] of Object.entries(metrics)) { for (let [functionHash, metricData] of Object.entries(metrics)) {
let {metric, revision} = await fetchData(functionHash, metricData)
if (metric.longterm === undefined) {
metric.longterm = {
coldstart: 0,
warmstart: 0
}
}
/** /**
* Shortterm moving average * Shortterm moving average
*/ */
metric.shortterm.coldstart /= (metric.shortterm.coldstart_total_request != 0) ? metric.shortterm.coldstart /= (metric.shortterm.coldstart_total_request != 0) ?
metric.shortterm.coldstart_total_request : 1 metric.shortterm.coldstart_total_request : 1
metric.shortterm.warmstart /= (metric.shortterm.warm_total_request != 0) ? metric.shortterm.warmstart /= (metric.shortterm.warm_total_request != 0) ?
...@@ -75,12 +75,26 @@ function broadcastMetrics() { ...@@ -75,12 +75,26 @@ function broadcastMetrics() {
* Longterm exponential moving average * Longterm exponential moving average
*/ */
if (metric.shortterm.coldstart != 0) if (metric.shortterm.coldstart != 0)
metric.longterm.coldstart = (metric.longterm.coldstart != 0)? metric.longterm.coldstart * alpha metric.longterm.coldstart = (metric.longterm.coldstart != 0) ? metric.longterm.coldstart * alpha
+ metric.shortterm.coldstart * (1 - alpha) : metric.shortterm.coldstart + metric.shortterm.coldstart * (1 - alpha) : metric.shortterm.coldstart
if (metric.shortterm.warmstart != 0) if (metric.shortterm.warmstart != 0)
metric.longterm.warmstart = (metric.longterm.warmstart != 0)? metric.longterm.warmstart * alpha metric.longterm.warmstart = (metric.longterm.warmstart != 0) ? metric.longterm.warmstart * alpha
+ metric.shortterm.warmstart * (1 - alpha) : metric.shortterm.warmstart + metric.shortterm.warmstart * (1 - alpha) : metric.shortterm.warmstart
let payload = {
method: 'put',
body: JSON.stringify({
coldstart: metric.longterm.coldstart,
warmstart: metric.longterm.warmstart,
_rev: revision
}),
headers: { 'Content-Type': 'application/json' }
}
console.log(payload);
await fetch(metricsDB + functionHash, payload)
metric.timestamp = Date.now() metric.timestamp = Date.now()
} }
...@@ -105,6 +119,38 @@ function broadcastMetrics() { ...@@ -105,6 +119,38 @@ function broadcastMetrics() {
} }
} }
/**
* Function to fetch the latest data from metric DB
* @param {String} functionHash
* @param {JSON} metric
*/
async function fetchData(functionHash, metric) {
let revision
let res = await fetch(metricsDB + functionHash)
let json = await res.json()
console.log(json);
if (json.error === "not_found") {
metric.longterm = {
coldstart: 0,
warmstart: 0
}
} else {
metric.longterm = {
coldstart: json.coldstart,
warmstart: json.warmstart,
}
revision = json._rev
}
console.log(metric);
return {
metric,
revision
}
}
module.exports = { module.exports = {
collectMetrics, broadcastMetrics collectMetrics, broadcastMetrics
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment