UNPKG

@apio/express-prometheus

Version:

Express middleware to provide basic metrics to Prometheus.

227 lines (196 loc) 6.5 kB
const supertest = require('supertest') const express = require('express') const expressPrometheus = require('./index') describe('index', () => { let sut describe('options', () => { beforeEach(() => { sut = express() }) test('When not given url, should default to metrics', () => { // Arrange expressPrometheus.instrument(sut) // Act return supertest(sut) .get('/metrics') .then(result => { // Assert expect(result.statusCode).toBe(200) }) }) test('When given url, should default to url value', () => { // Arrange const options = { url: '/metric-route' } expressPrometheus.instrument(sut, options) // Act return supertest(sut) .get(options.url) .then(result => { // Assert expect(result.statusCode).toBe(200) }) }) }) describe('metrics', () => { let agent beforeEach(() => { sut = express() expressPrometheus.instrument(sut) sut.get('/resource', (req, res) => { res.send() }) sut.get('/resource/:id', (req, res) => { res.send() }) agent = supertest.agent(sut) }) describe('http_requests_processing', () => { test('Given metrics are running, should include http_requests_processing', () => { // Arrange // Act return agent.get('/resource').then(() => { return agent.get('/metrics').then(result => { expect(result.statusCode).toBe(200) expect(result.headers['content-type']).toBe( 'text/plain; charset=utf-8' ) expect(result.text).toContain('http_requests_processing 0') }) }) }) }) describe('http_requests_total', () => { test('Given resource has been request, should being included in http_requests_total', () => { // Arrange // Act return agent.get('/resource').then(() => { return agent.get('/metrics').then(result => { expect(result.statusCode).toBe(200) expect(result.headers['content-type']).toBe( 'text/plain; charset=utf-8' ) expect(result.text).toContain( 'http_requests_total{method="GET",path="/resource",status="200"} 2' ) }) }) }) test('Given resource/:id has been request, should being included in http_requests_total', () => { // Arrange const id = 8 // Act return agent.get(`/resource/${id}`).then(() => { return agent.get('/metrics').then(result => { expect(result.statusCode).toBe(200) expect(result.headers['content-type']).toBe( 'text/plain; charset=utf-8' ) expect(result.text).toContain( 'http_requests_total{method="GET",path="/resource/:id",status="200"} 1' ) }) }) }) }) describe('http_request_duration_seconds', () => { test('Given resource has been request, should being included in http_request_duration_seconds', () => { // Arrange // Act return agent.get('/resource').then(() => { return agent.get('/metrics').then(result => { expect(result.statusCode).toBe(200) expect(result.headers['content-type']).toBe( 'text/plain; charset=utf-8' ) expect(result.text).toContain( 'http_request_duration_seconds_bucket{le="10",method="GET",path="/resource",status="200"} 3' ) }) }) }) test('Given resource/:id has been request, should being included in http_request_duration_seconds', () => { // Arrange const id = 3 // Act return agent.get(`/resource/${id}`).then(() => { return agent.get('/metrics').then(result => { expect(result.statusCode).toBe(200) expect(result.headers['content-type']).toBe( 'text/plain; charset=utf-8' ) expect(result.text).toContain( 'http_request_duration_seconds_bucket{le="10",method="GET",path="/resource/:id",status="200"} 2' ) }) }) }) }) describe('third party metrics', () => { test('Given metrics running, should include default node metrics', () => { // Arrange // Act return agent.get('/metrics').then(result => { // Assert expect(result.text).toContain('nodejs_active_handles_total') expect(result.text).toContain('nodejs_active_requests_total') expect(result.text).toContain('nodejs_external_memory_bytes') }) }) }) }) describe('labels', () => { let agent beforeEach(() => { sut = express() expressPrometheus.instrument(sut) const router = express.Router() router.get('/', (req, res) => { res.send() }) router.get('/:id', (req, res) => { res.send() }) sut.use('/resource-1', router) sut.use('/resource-2', router) sut.get('/resource-3/', (req, res) => { res.send() }) sut.get('/resource-3/:id', (req, res) => { res.send() }) agent = supertest.agent(sut) }) test('Given a router route is called, should calculate path correctly', () => { // Arrange // Act return agent.get('/resource-1/id-thing').then(() => { return agent.get('/metrics').then(result => { expect(result.statusCode).toBe(200) expect(result.headers['content-type']).toBe( 'text/plain; charset=utf-8' ) expect(result.text).toContain( 'http_requests_total{method="GET",path="/resource-1/:id",status="200"} 1' ) }) }) }) test('Given a app route is called, should calculate path correctly', () => { // Arrange // Act return agent.get('/resource-3/id-thing-3').then(() => { return agent.get('/metrics').then(result => { expect(result.statusCode).toBe(200) expect(result.headers['content-type']).toBe( 'text/plain; charset=utf-8' ) expect(result.text).toContain( 'http_requests_total{method="GET",path="/resource-3/:id",status="200"} 1' ) }) }) }) }) })