You need to sign in or sign up before continuing.
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