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

Almost Done

parent 1d9b1808
Branches
No related tags found
1 merge request!1Master to main
include:
- project: 'general/templates'
file: '/cicd/SAST-nodejs.gitlab-ci.yml'
- project: 'general/templates'
file: '/cicd/npm-audit.gitlab-ci.yml'
- project: 'general/templates'
file: '/cicd/sonarqube.gitlab-ci.yml'
- project: 'general/templates'
file: '/cicd/npm-outdated.gitlab-ci.yml'
variables:
SONAR_PROJECT_KEY: metrics
SONAR_TOKEN: 11922a8e774494f51e1d2f0e695949e4073e7df8
NPM_REGISTRY: https://npm.br-edv.brnet.int
NPM_TOKEN: 5w2Gy80rdH+2Tch0afNI6Q==
cache:
paths:
- node_modules/
- docs/
stages:
- build
- test
- quality
- publish
build:
stage: build
script:
- npm install
- npm run build
test:
stage: test
before_script:
- npm install -g jest
script:
- jest
artifacts:
paths:
- docs/test-report.html
- docs/coverage/lcov.info
publish:
stage: publish
script:
- npm config set strict-ssl false
- npm config set //${NPM_REGISTRY}/:_authToken ${NPM_TOKEN}
- npm publish --registry $NPM_REGISTRY
src/
docs/
examples/
\ No newline at end of file
......@@ -27,4 +27,24 @@ And to enable the *_metrics*-Endpoint:
### Options
TODO: fill options
\ No newline at end of file
The Following Options may be used to configure the behaviour.
- ignore: A String Array with routes to ignore, e.g. ['/foo'] . Default: []. Important: */_metrics* and */favicon.ico* are always ignored
- disableErrorCounter: Disable the Error Counter. Default: false
- disableRouteCounter: Disable the Route Counter. Default: false
- disableDurationCounter: Disable the Duration Counter. Default: false
## Examples
You can find prebuilt examples in the fitting folder.
Just call `node examples/dist/server.js 3000` to start a Test-Server on Port 3000.
Then use your Browser to call the Endpoints:
- /foo
- /bar
- /404
- /401
And check the results on the Endpoint */_metrics*
# TODO
- config
- tests
- README: options, examples
\ No newline at end of file
- get to gitlab-server
- publish to npm
......@@ -17,7 +17,12 @@ class App {
this.router = express.Router()
this.metrics = new Metrics({})
this.metrics = new Metrics({
ignore: ['/bar'],
disableErrorCounter: false,
disableRouteCounter: false,
disableDurationCounter: false
})
this.router.use(this.metrics.start.bind(this.metrics))
......
......@@ -5,6 +5,7 @@
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"prepublish":"npm run build",
"test": "jest",
"test:mutation": "stryker run",
"lint": "eslint src/**/*.ts",
......@@ -55,5 +56,8 @@
"pre-push": "npm run lint",
"post-commit": "./ho-copy"
}
},
"publishConfig": {
"@br:registry": "https://npm.br-edv.brnet.int"
}
}
/*
Import.
- Start with different option packages.
- Call all Routes
- Check if _metrics has a good start
*/
import * as express from 'express'
import Prometheus = require('prom-client')
export interface Options {
ignore: string[]
disableRouteCounter: boolean
disableErrorCounter: boolean
disableDurationCounter: boolean
}
export class Metrics {
private readonly _options: any
private readonly _ignore: string[]
private readonly _disableRouteCounter: boolean
private readonly _disableErrorCounter: boolean
private readonly _disableDurationCounter: boolean
public readonly _httpRequestDurationMicroseconds: any
public readonly _numOfRequests: any
public readonly _numOfErrors: any
constructor (options: any) {
this._options = options
constructor (options: Partial<Options> = {}) {
if (typeof options.ignore !== 'undefined') {
this._ignore = options.ignore
this._ignore.push('/_metrics')
this._ignore.push('/favicon.ico')
} else {
this._ignore = ['/_metrics', '/favicon.ico']
}
if (typeof options.disableRouteCounter !== 'undefined') {
this._disableRouteCounter = options.disableRouteCounter
} else {
this._disableRouteCounter = false
}
if (typeof options.disableErrorCounter !== 'undefined') {
this._disableErrorCounter = options.disableErrorCounter
} else {
this._disableErrorCounter = false
}
if (typeof options.disableDurationCounter !== 'undefined') {
this._disableDurationCounter = options.disableDurationCounter
} else {
this._disableDurationCounter = false
}
this._httpRequestDurationMicroseconds = new Prometheus.Histogram({
name: 'http_request_duration_ms',
help: 'Duration of HTTP requests in ms',
......@@ -25,22 +58,27 @@ export class Metrics {
help: 'Number of errors',
labelNames: ['error']
})
// TODO: config: ignore routes, disable metrics
}
public start (req: express.Request, res: express.Response, next: express.NextFunction): void {
res.locals.startEpoch = Date.now()
res.on('finish', () => {
if (req.originalUrl !== '/_metrics' && req.originalUrl !== './favicon.ico') {
if (!this._ignore.includes(req.originalUrl)) {
const responseTimeInMs = Date.now() - res.locals.startEpoch
if (!this._disableDurationCounter) {
this._httpRequestDurationMicroseconds
.labels(req.method, req.originalUrl, res.statusCode.toString())
.observe(responseTimeInMs)
}
if (!this._disableRouteCounter) {
this._numOfRequests.inc({ route: req.originalUrl })
}
if (res.statusCode >= 400) {
if (!this._disableErrorCounter) {
this._numOfErrors.inc({ error: res.statusCode })
}
}
}
})
next()
}
......@@ -50,5 +88,4 @@ export class Metrics {
res.end(Prometheus.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