Add compatibility with Koa v1, fix tests and edit README

This commit is contained in:
Danijel Hrvacanin
2016-10-14 14:32:39 +02:00
parent 36c40daa5d
commit 66e1fca8dd
4 changed files with 67 additions and 20 deletions

View File

@@ -7,7 +7,7 @@ express middleware with popular prometheus metrics in one bundle.
Internally it uses **prom-client**. See: https://github.com/siimon/prom-client Internally it uses **prom-client**. See: https://github.com/siimon/prom-client
Included metrics: Included metrics:
* `up`: normally is just 1 * `up`: normally is just 1
* `nodejs_memory_heap_total_bytes` and `nodejs_memory_heap_used_bytes` * `nodejs_memory_heap_total_bytes` and `nodejs_memory_heap_used_bytes`
* `http_request_seconds`: http latency histogram labeled with `status_code` * `http_request_seconds`: http latency histogram labeled with `status_code`
@@ -22,13 +22,25 @@ npm install express-prom-bundle
```javascript ```javascript
const promBundle = require("express-prom-bundle"), const promBundle = require("express-prom-bundle"),
const metricsMiddleware = promBundle({/* options */ }); metricsMiddleware = promBundle({/* options */ });
app.use(metricsMiddleware); app.use(metricsMiddleware);
app.use(/* your middleware */); app.use(/* your middleware */);
app.listen(3000); app.listen(3000);
``` ```
**Usage Koa Framework (currently only v1)**
```javascript
const promBundle = require("express-prom-bundle"),
c2k = require("koa-connect"),
metricsMiddleware = promBundle({/* options */ });
app.use(c2k(metricsMiddleware));
app.use(/* your middleware */);
app.listen(3000);
```
* call your endpoints * call your endpoints
* see your metrics here: [http://localhost:3000/metrics](http://localhost:3000/metrics) * see your metrics here: [http://localhost:3000/metrics](http://localhost:3000/metrics)
@@ -56,8 +68,8 @@ setup std. metrics but exclude `up`-metric:
"use strict"; "use strict";
const express = require("express"), const express = require("express"),
app = express(), app = express(),
promBundle = require("express-prom-bundle"); promBundle = require("express-prom-bundle");
// calls to this route will not appear in metrics // calls to this route will not appear in metrics

View File

@@ -1,6 +1,6 @@
{ {
"name": "express-prom-bundle", "name": "express-prom-bundle",
"version": "1.1.7", "version": "1.1.8",
"description": "express middleware with popular prometheus metrics in one bundle", "description": "express middleware with popular prometheus metrics in one bundle",
"main": "src/index.js", "main": "src/index.js",
"keywords": [ "keywords": [
@@ -24,7 +24,10 @@
"express": "^4.13.4", "express": "^4.13.4",
"istanbul": "^0.4.4", "istanbul": "^0.4.4",
"jasme": "^4.1.2", "jasme": "^4.1.2",
"supertest": "^1.2.0" "koa": "^1.2.4",
"koa-connect": "^1.0.0",
"supertest": "^1.2.0",
"supertest-koa-agent": "^0.3.0"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View File

@@ -3,7 +3,10 @@
let express = require("express"), let express = require("express"),
supertest = require("supertest"), supertest = require("supertest"),
bundle = require("../"); bundle = require("../"),
koa = require("koa"),
c2k = require("koa-connect"),
supertestKoa = require("supertest-koa-agent");
describe("index", () => { describe("index", () => {
it("metrics returns up=1", done => { it("metrics returns up=1", done => {
@@ -137,4 +140,31 @@ describe("index", () => {
}); });
}); });
}); });
it("Koa: metrics returns up=1", done => {
const app = koa();
const bundled = bundle({
prefix: "hello:",
whitelist: ["up"]
});
app.use(c2k(bundled));
app.use(function*(next) {
if (this.path !== "test") {
return yield next;
}
this.body = "it worked";
});
const agent = supertestKoa(app);
agent.get("/test").end(() => {
agent
.get("/metrics")
.end((err, res) => {
expect(res.status).toBe(200);
expect(res.text).toMatch(/hello:up\s1/);
done();
});
});
});
}); });

View File

@@ -1,8 +1,8 @@
"use strict"; "use strict";
const const PromFactory = require("./PromFactory"),
PromFactory = require("./PromFactory"), onFinished = require("on-finished"),
onFinished = require("on-finished"); url = require("url");
function matchVsRegExps(element, regexps) { function matchVsRegExps(element, regexps) {
for (let regexp of regexps) { for (let regexp of regexps) {
@@ -17,7 +17,6 @@ function matchVsRegExps(element, regexps) {
return false; return false;
} }
function filterArrayByRegExps(array, regexps) { function filterArrayByRegExps(array, regexps) {
return array.filter(element => { return array.filter(element => {
return matchVsRegExps(element, regexps); return matchVsRegExps(element, regexps);
@@ -78,9 +77,8 @@ function main(opts) {
} }
}; };
const const metrics = {},
metrics = {}, names = prepareMetricNames(opts, metricTemplates);
names = prepareMetricNames(opts, metricTemplates);
for (let name of names) { for (let name of names) {
@@ -100,20 +98,23 @@ function main(opts) {
metrics["nodejs_memory_heap_used_bytes"].set(memoryUsage.heapUsed); metrics["nodejs_memory_heap_used_bytes"].set(memoryUsage.heapUsed);
} }
res.contentType("text/plain").send(factory.promClient.register.metrics()); res.writeHead(200, {"Content-Type": "text/plain"});
return; res.end(factory.promClient.register.metrics());
}; };
const middleware = function (req, res, next) { const middleware = function (req, res, next) {
if (opts.autoregister && req.path == "/metrics") {
const path = req.path || url.parse(req.url).pathname;
let labels;
if (opts.autoregister && path == "/metrics") {
return metricsMiddleware(req,res); return metricsMiddleware(req,res);
} }
if (opts.excludeRoutes && matchVsRegExps(req.path, opts.excludeRoutes)) { if (opts.excludeRoutes && matchVsRegExps(path, opts.excludeRoutes)) {
return next(); return next();
} }
let labels;
if (metrics["http_request_seconds"]) { if (metrics["http_request_seconds"]) {
labels = {"status_code": 0}; labels = {"status_code": 0};
let timer = metrics["http_request_seconds"].startTimer(labels); let timer = metrics["http_request_seconds"].startTimer(labels);
@@ -123,7 +124,8 @@ function main(opts) {
}); });
} }
next(); next();
}; };
middleware.factory = factory; middleware.factory = factory;