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

Added more custom metrics

parent 6c9fcbd1
No related branches found
No related tags found
1 merge request!1Master to main
......@@ -9,7 +9,7 @@ A small express middleware to get base metrics for any node.js app.
## Usage
`import { Metrics } from '@plastdev/metrics'`
`import { Metrics, MetricType } from '@plastdev/metrics'`
`let metrics = new Metrics(options)`
Note: The options Part may be omitted, as all parts are optional.
......@@ -20,16 +20,93 @@ Before your Routes:
And to enable the *_metrics*-Endpoint:
`router.get('/_metrics', metrics.endpoint)`
### Custom Metrics
To Add your own custom Metrics:
`metrics.addCustomMetric({
name: 'test',
help: 'Some Test Metric',
labelNames: ['tester']
})`
help: 'Some Test Metric'
}, TYPE)`
where TYPE is one of:
- `MetricType.COUNTER`
- `MetricType.GAUGE`
- `MetricType.HISTOGRAM`
- `MetricType.SUMMARY`
All metrics can take a labelNames property in the configuration object. All labelNames that the metric support needs to be declared here. There are 2 ways to add values to the labels
```js
metrics.addCustomMetric({
name: 'metric_name',
help: 'metric_help',
labelNames: ['method', 'statusCode'],
}, MetricType.GAUGE);
metrics.customMetrics["NAME"].set({ method: 'GET', statusCode: '200' }, 100); // 1st version, Set value 100 with method set to GET and statusCode to 200
metrics.customMetrics["NAME"].labels('GET', '200').set(100); // 2nd version, Same as above
```
It is also possible to use timers with labels, both before and after the timer is created:
```js
const end = metrics.customMetrics["NAME"].startTimer({ method: 'GET' }); // Set method to GET, we don't know statusCode yet
xhrRequest(function (err, res) {
if (err) {
end({ statusCode: '500' }); // Sets value to xhrRequest duration in seconds with statusCode 500
} else {
end({ statusCode: '200' }); // Sets value to xhrRequest duration in seconds with statusCode 200
}
});
```
#### Counter
Counters go up, and reset when the process restarts.
- `metrics.customMetrics["NAME"].inc(); // Inc with 1`
- `metrics.customMetrics["NAME"].inc(10); // Inc with 10`
#### Gauge
Gauges are similar to Counters but Gauges value can be decreased.
- `metrics.customMetrics["NAME"].set(10); // Set to 10`
- `metrics.customMetrics["NAME"].inc(); // Inc with 1`
- `metrics.customMetrics["NAME"].inc(10); // Inc with 10`
- `metrics.customMetrics["NAME"].dec(); // Dec with 1`
- `metrics.customMetrics["NAME"].dec(10); // Dec with 10`
#### Histograms
Histograms track sizes and frequency of events.
`metrics.customMetrics["NAME"].observe(10); // Observe value in histogram`
Utility to observe request durations
```js
const end = metrics.customMetrics["NAME"].startTimer();
xhrRequest(function (err, res) {
const seconds = end(); // Observes and returns the value to xhrRequests duration in seconds
});
```
#### Summary
Summaries calculate percentiles of observed values.
`metrics.customMetrics["NAME"].observe(10);`
Utility to observe request durations
then you may increase or decrease the value at any given point:
`this.metrics.incCustomMetric('test', 'tester', 'called_bar')`
`this.metrics.decCustomMetric('test', 'tester', 'called_bar')`
```js
const end = metrics.customMetrics["NAME"].startTimer();
xhrRequest(function (err, res) {
end(); // Observes the value to xhrRequests duration in seconds
});
```
### Options
......
This diff is collapsed.
......@@ -3,7 +3,7 @@
import * as http from 'http'
import * as express from 'express'
import { Metrics } from '../../dist/index'
import { Metrics, MetricType } from '../../dist/index'
class App {
public app: express.Application
......@@ -27,9 +27,8 @@ class App {
this.metrics.addCustomMetric({
name: 'test',
help: 'Some Test Metric',
labelNames: ['tester']
})
help: 'Some Test Metric'
}, MetricType.COUNTER)
this.router.use(this.metrics.collect)
......@@ -39,7 +38,7 @@ class App {
res.status(200).send('foo')
})
this.router.get('/bar', (req:express.Request, res:express.Response) => {
this.metrics.incCustomMetric('test', 'tester', 'called_bar')
this.metrics["test"].inc()
res.status(200).send('bar')
})
this.router.get('/404', (req:express.Request, res:express.Response) => {
......
......@@ -11,7 +11,14 @@ export interface Options {
export interface CustomMetric {
name: string
help: string
labelNames: string[]
labelNames?: string[]
}
export enum MetricType {
GAUGE,
COUNTER,
HISTOGRAM,
SUMMARY
}
export class Metrics {
......@@ -27,11 +34,11 @@ export class Metrics {
public readonly _numOfRequests: any
public readonly _numOfErrors: any
public readonly _customMetrics: any
public readonly customMetrics: any
constructor (options: Partial<Options> = {}) {
this._client = require('prom-client')
this._customMetrics = {}
this.customMetrics = {}
if (typeof options.ignore !== 'undefined') {
this._ignore = options.ignore
......@@ -87,24 +94,23 @@ export class Metrics {
}
}
public addCustomMetric = (options: CustomMetric): void => {
this._customMetrics[options.name] = new this._client.Gauge({
name: options.name,
help: options.help,
labelNames: options.labelNames
})
}
public incCustomMetric = (name: string, label: string, value: string): void => {
const inc: any = {}
inc[label] = value
this._customMetrics[name].inc(inc)
}
public decCustomMetric = (name: string, label: string, value: string): void => {
const dec: any = {}
dec[label] = value
this._customMetrics[name].dec(dec)
public addCustomMetric = (options: CustomMetric, type: MetricType): void => {
switch (type) {
case MetricType.COUNTER:
this.customMetrics[options.name] = new this._client.Counter(options)
break
case MetricType.GAUGE:
this.customMetrics[options.name] = new this._client.Gauge(options)
break
case MetricType.HISTOGRAM:
this.customMetrics[options.name] = new this._client.Histogram(options)
break
case MetricType.SUMMARY:
this.customMetrics[options.name] = new this._client.Summary(options)
break
default:
break
}
}
public collect = (req: express.Request, res: express.Response, next: express.NextFunction): void => {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment