add a /metrics call for all counts

Signed-off-by: Jakub Sokołowski <jakub@status.im>
This commit is contained in:
Jakub Sokołowski 2018-11-15 14:47:49 +01:00
parent 1d115164f0
commit 98d3384b33
No known key found for this signature in database
GPG Key ID: 4EF064D0E6D63020
2 changed files with 32 additions and 10 deletions

View File

@ -12,21 +12,29 @@ const App = (counter) => {
app.on('error', (err, ctx) => { app.on('error', (err, ctx) => {
console.error('server error', err, ctx) console.error('server error', err, ctx)
}); })
router.get('/health', async (ctx) => {
ctx.body = 'OK'
})
/* Metrics related handlers */
router.get('/metrics', async (ctx) => {
ctx.body = await counter.metrics()
})
router.put('/clicks/:id', async ctx => { router.put('/clicks/:id', async ctx => {
counter.incr(ctx.params.id) ctx.body = { [ctx.params.id]: await counter.incr(ctx.params.id) }
ctx.body = { [ctx.params.id]: await counter.state(ctx.params.id) }
ctx.status = 201 ctx.status = 201
}); })
router.get('/clicks', async ctx => { router.get('/clicks', async ctx => {
ctx.body = await counter.list() ctx.body = await counter.list()
}); })
router.get('/clicks/:id', async ctx => { router.get('/clicks/:id', async ctx => {
ctx.body = { [ctx.params.id]: await counter.state(ctx.params.id) } ctx.body = { [ctx.params.id]: await counter.state(ctx.params.id) }
}); })
return app return app
} }

View File

@ -1,8 +1,13 @@
const metricsName = 'clicks_counter'
const metricsHeader = `
# Counts of clicks for every key available in the service store.
# HELP ${metricsName} List of clicks for counted for every key.
# TYPE ${metricsName} counter
`
class Counter { class Counter {
constructor(redis, name) { constructor(redis, name) {
this.redis = redis this.redis = redis
/* assume the key is called "clicks" */
this.name = name == undefined ? "clicks" : name
/* make sure we don't miss errors */ /* make sure we don't miss errors */
this.redis.on("error", (err) => { console.log("Error: " + err) }) this.redis.on("error", (err) => { console.log("Error: " + err) })
} }
@ -11,11 +16,12 @@ class Counter {
/* default to incrementing by one */ /* default to incrementing by one */
val = val == undefined ? 1 : val val = val == undefined ? 1 : val
/* increment */ /* increment */
this.redis.incr(key ? key : this.name) await this.redis.incr(key)
return await this.state(key)
} }
async state (key) { async state (key) {
let count = await this.redis.get(key ? key : this.name) let count = await this.redis.get(key)
/* keys in redis are set to null by default */ /* keys in redis are set to null by default */
return count == null ? 0 : count return count == null ? 0 : count
} }
@ -27,6 +33,14 @@ class Counter {
/* combine list of keys and values into an object */ /* combine list of keys and values into an object */
return keys.reduce((obj, k, i) => ({...obj, [k]: vals[i] }), {}) return keys.reduce((obj, k, i) => ({...obj, [k]: vals[i] }), {})
} }
async metrics () {
let metrics = await this.list()
let metricsFormatted = Object.keys(metrics).map((key) => (
`${metricsName}{key="${key}"} ${metrics[key]}`
))
return metricsHeader + metricsFormatted.join('\n')
}
} }
module.exports = Counter module.exports = Counter