From 98d3384b33cf54c3e773b0d1c996552348809db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Soko=C5=82owski?= Date: Thu, 15 Nov 2018 14:47:49 +0100 Subject: [PATCH] add a /metrics call for all counts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jakub SokoĊ‚owski --- src/app.js | 20 ++++++++++++++------ src/counter.js | 22 ++++++++++++++++++---- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/app.js b/src/app.js index 069a12b..cfa49fc 100644 --- a/src/app.js +++ b/src/app.js @@ -12,21 +12,29 @@ const App = (counter) => { app.on('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 => { - counter.incr(ctx.params.id) - ctx.body = { [ctx.params.id]: await counter.state(ctx.params.id) } + ctx.body = { [ctx.params.id]: await counter.incr(ctx.params.id) } ctx.status = 201 - }); + }) router.get('/clicks', async ctx => { ctx.body = await counter.list() - }); + }) router.get('/clicks/:id', async ctx => { ctx.body = { [ctx.params.id]: await counter.state(ctx.params.id) } - }); + }) return app } diff --git a/src/counter.js b/src/counter.js index 344c802..7cb5c08 100644 --- a/src/counter.js +++ b/src/counter.js @@ -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 { constructor(redis, name) { this.redis = redis - /* assume the key is called "clicks" */ - this.name = name == undefined ? "clicks" : name /* make sure we don't miss errors */ this.redis.on("error", (err) => { console.log("Error: " + err) }) } @@ -11,11 +16,12 @@ class Counter { /* default to incrementing by one */ val = val == undefined ? 1 : val /* increment */ - this.redis.incr(key ? key : this.name) + await this.redis.incr(key) + return await this.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 */ return count == null ? 0 : count } @@ -27,6 +33,14 @@ class Counter { /* combine list of keys and values into an object */ 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