Skip to content
Snippets Groups Projects
Commit 45d58d0b authored by Sigmund, Dominik's avatar Sigmund, Dominik
Browse files

Basic Tests

parent c158e070
No related branches found
No related tags found
1 merge request!1Master to main
......@@ -20,7 +20,7 @@ A small express middleware to get base metrics for any node.js app.
Note: The options Part may be omitted, as all parts are optional.
Before your Routes:
`router.use(metrics.start.bind(metrics))`
`router.use(metrics.collect)`
And to enable the *_metrics*-Endpoint:
`router.get('/_metrics', metrics.endpoint)`
......
# TODO
- disable default metrics
- tests
- get to gitlab-server
- mutation tests
- publish to npm
This diff is collapsed.
......@@ -21,10 +21,11 @@ class App {
ignore: ['/bar'],
disableErrorCounter: false,
disableRouteCounter: false,
disableDurationCounter: false
disableDurationCounter: false,
disableDefaultMetrics: false
})
this.router.use(this.metrics.start.bind(this.metrics))
this.router.use(this.metrics.collect)
this.router.get('/favicon.ico', (req, res) => res.status(204)) // No Favicon here
......
......@@ -4,3 +4,84 @@
- Call all Routes
- Check if _metrics has a good start
*/
import { Metrics } from './index'
describe('metrics', () => {
beforeEach(() => {
jest.resetModules()
})
describe('constructor / options', () => {
it('should enable all 3 checks and default metrics by default', () => {
const metrics = new Metrics({})
expect(metrics._disableDurationCounter).toBeFalsy()
expect(metrics._disableErrorCounter).toBeFalsy()
expect(metrics._disableRouteCounter).toBeFalsy()
expect(metrics._disableDefaultMetrics).toBeFalsy()
})
it('should disable Route Counter if option is given', () => {
const metrics = new Metrics({
disableRouteCounter: true
})
expect(metrics._disableDurationCounter).toBeFalsy()
expect(metrics._disableErrorCounter).toBeFalsy()
expect(metrics._disableRouteCounter).toBeTruthy()
expect(metrics._disableDefaultMetrics).toBeFalsy()
})
it('should disable Error Counter if option is given', () => {
const metrics = new Metrics({
disableErrorCounter: true
})
expect(metrics._disableDurationCounter).toBeFalsy()
expect(metrics._disableErrorCounter).toBeTruthy()
expect(metrics._disableRouteCounter).toBeFalsy()
expect(metrics._disableDefaultMetrics).toBeFalsy()
})
it('should disable Duration Counter if option is given', () => {
const metrics = new Metrics({
disableDurationCounter: true
})
expect(metrics._disableDurationCounter).toBeTruthy()
expect(metrics._disableErrorCounter).toBeFalsy()
expect(metrics._disableRouteCounter).toBeFalsy()
expect(metrics._disableDefaultMetrics).toBeFalsy()
})
it('should disable Default Metrics if option is given', () => {
const metrics = new Metrics({
disableDefaultMetrics: true
})
expect(metrics._disableDurationCounter).toBeFalsy()
expect(metrics._disableErrorCounter).toBeFalsy()
expect(metrics._disableRouteCounter).toBeFalsy()
expect(metrics._disableDefaultMetrics).toBeTruthy()
})
it('should ignore /_metrics and /favicon.ico by default', () => {
const metrics = new Metrics()
expect(metrics._ignore.length).toBe(2)
expect(metrics._ignore).toContain('/_metrics')
expect(metrics._ignore).toContain('/favicon.ico')
})
it('should ignore given Routes, /_metrics and /favicon.ico by option', () => {
const metrics = new Metrics({
ignore: ['/foo', '/bar']
})
expect(metrics._ignore.length).toBe(4)
expect(metrics._ignore).toContain('/foo')
expect(metrics._ignore).toContain('/bar')
expect(metrics._ignore).toContain('/_metrics')
expect(metrics._ignore).toContain('/favicon.ico')
})
})
describe('collect()', () => {
it.todo('should measure all 3 checks by default')
it.todo('should disable Route Counter if option is given')
it.todo('should disable Error Counter if option is given')
it.todo('should disable Duration Counter if option is given')
})
describe('endpoint()', () => {
it.todo('should display all 3 basic metrics and default metrics by default')
it.todo('should not scrape default metrics if disabled')
})
})
import * as express from 'express'
import Prometheus = require('prom-client')
export interface Options {
ignore: string[]
disableRouteCounter: boolean
disableErrorCounter: boolean
disableDurationCounter: boolean
disableDefaultMetrics: boolean
}
export class Metrics {
private readonly _ignore: string[]
private readonly _disableRouteCounter: boolean
private readonly _disableErrorCounter: boolean
private readonly _disableDurationCounter: boolean
public readonly _ignore: string[]
public readonly _disableRouteCounter: boolean
public readonly _disableErrorCounter: boolean
public readonly _disableDurationCounter: boolean
public readonly _disableDefaultMetrics: boolean
public readonly _client: any
public readonly _collectDefaultMetrics: any
public readonly _httpRequestDurationMicroseconds: any
public readonly _numOfRequests: any
public readonly _numOfErrors: any
constructor (options: Partial<Options> = {}) {
this._client = require('prom-client')
if (typeof options.ignore !== 'undefined') {
this._ignore = options.ignore
this._ignore.push('/_metrics')
......@@ -41,26 +47,34 @@ export class Metrics {
} else {
this._disableDurationCounter = false
}
if (typeof options.disableDefaultMetrics !== 'undefined') {
this._disableDefaultMetrics = options.disableDefaultMetrics
} else {
this._disableDefaultMetrics = false
}
if (this._disableDefaultMetrics) {
this._collectDefaultMetrics = this._client.collectDefaultMetrics
}
this._httpRequestDurationMicroseconds = new Prometheus.Histogram({
this._httpRequestDurationMicroseconds = new this._client.Histogram({
name: 'http_request_duration_ms',
help: 'Duration of HTTP requests in ms',
labelNames: ['method', 'route', 'code'],
buckets: [0.10, 5, 15, 50, 100, 200, 300, 400, 500]
})
this._numOfRequests = new Prometheus.Counter({
this._numOfRequests = new this._client.Counter({
name: 'numOfRequests',
help: 'Number of requests made to a route',
labelNames: ['route']
})
this._numOfErrors = new Prometheus.Counter({
this._numOfErrors = new this._client.Counter({
name: 'numOfErrors',
help: 'Number of errors',
labelNames: ['error']
})
}
public start (req: express.Request, res: express.Response, next: express.NextFunction): void {
public collect = (req: express.Request, res: express.Response, next: express.NextFunction): void => {
res.locals.startEpoch = Date.now()
res.on('finish', () => {
if (!this._ignore.includes(req.originalUrl)) {
......@@ -83,9 +97,12 @@ export class Metrics {
next()
}
public endpoint (req: express.Request, res: express.Response): void {
res.set('Content-Type', Prometheus.register.contentType)
res.end(Prometheus.register.metrics())
public endpoint = (req: express.Request, res: express.Response): void => {
if (!this._disableDefaultMetrics) {
this._collectDefaultMetrics()
}
res.set('Content-Type', this._client.register.contentType)
res.end(this._client.register.metrics())
}
}
export default Metrics
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment