@pager/metrics-client
Advanced tools
Comparing version 4.3.0 to 4.3.1
@@ -14,14 +14,2 @@ 'use strict'; | ||
const internals = { | ||
schema: { | ||
interval: Joi.number().integer().positive(), | ||
metrics: Joi.array().items(Joi.string().valid(['cpu', 'evloop', 'gc', 'memory', 'request'])), | ||
endpoint: Joi.object({ | ||
path: Joi.array().items(Joi.string()).single() | ||
}).unknown(), | ||
health: Joi.object({ | ||
path: Joi.array().items(Joi.string()).single(), | ||
auth: Joi.any(), | ||
response: Joi.object().unknown() | ||
}) | ||
}, | ||
defaults: { | ||
@@ -65,2 +53,27 @@ interval: 15 * 1e3, | ||
exports.validateSettings = (settings) => { | ||
const schema = Joi.object({ | ||
interval: Joi.number().integer().positive(), | ||
metrics: Joi.array().items(Joi.string().valid('cpu', 'evloop', 'gc', 'memory', 'request')), | ||
endpoint: Joi.object({ | ||
path: Joi.array().items(Joi.string()).single() | ||
}).unknown(), | ||
health: Joi.object({ | ||
path: Joi.array().items(Joi.string()).single(), | ||
auth: Joi.any(), | ||
response: Joi.object().unknown() | ||
}) | ||
}); | ||
const { error, value } = schema.validate(settings); | ||
if (error) { | ||
throw error; | ||
} | ||
return value; | ||
}; | ||
exports.plugin = { | ||
@@ -73,6 +86,6 @@ name: 'metrics', | ||
Joi.assert(settings, internals.schema, 'Invalid metrics configuration'); | ||
const validatedSettings = this.validateSettings(settings); | ||
const endpointPaths = Array.isArray(settings.endpoint.path) ? settings.endpoint.path : [settings.endpoint.path]; | ||
const nativeMetrics = new NativeMetrics({ timeout: settings.interval }); | ||
const endpointPaths = validatedSettings.endpoint.path; | ||
const nativeMetrics = new NativeMetrics({ timeout: validatedSettings.interval }); | ||
const registry = new Registry(); | ||
@@ -82,3 +95,3 @@ | ||
if (!nativeMetrics.bound) { | ||
nativeMetrics.bind(settings.interval); | ||
nativeMetrics.bind(validatedSettings.interval); | ||
} | ||
@@ -89,7 +102,7 @@ /* $lab:coverage:on$ */ | ||
const initialisedMetrics = settings.metrics.map((metricName) => { | ||
const initialisedMetrics = validatedSettings.metrics.map((metricName) => { | ||
return new internals.metrics[metricName](({ | ||
registry, | ||
interval: settings.interval, | ||
interval: validatedSettings.interval, | ||
nativeMetrics, | ||
@@ -123,3 +136,3 @@ /* $lab:coverage:off$ */ | ||
if (startTime) { | ||
/* $lab:coverage:on$ */ | ||
/* $lab:coverage:on$ */ | ||
@@ -145,3 +158,3 @@ metric.record({ | ||
() => metric.record(), | ||
settings.interval | ||
validatedSettings.interval | ||
).unref(); | ||
@@ -164,3 +177,3 @@ }); | ||
options: { | ||
auth: !!settings.endpoint.auth, | ||
auth: !!validatedSettings.endpoint.auth, | ||
tags: ['metrics'] | ||
@@ -171,8 +184,8 @@ } | ||
for (const path of settings.health.path) { | ||
for (const path of validatedSettings.health.path) { | ||
server.route({ | ||
method: 'GET', path, options: { | ||
auth: !!settings.health.auth, | ||
handler: (request, h) => h.response(settings.health.response), | ||
auth: !!validatedSettings.health.auth, | ||
handler: (request, h) => h.response(validatedSettings.health.response), | ||
response: { | ||
@@ -179,0 +192,0 @@ schema: Joi.object({ |
{ | ||
"name": "@pager/metrics-client", | ||
"version": "4.3.0", | ||
"version": "4.3.1", | ||
"description": "Hapi-centric Prometheus Plugin and optional endpoint", | ||
"main": "lib/index.js", | ||
"scripts": { | ||
"test": "lab -La @hapi/code -t 100" | ||
"test": "lab -La @hapi/code -t 100", | ||
"start": "node ./examples/server.js" | ||
}, | ||
@@ -23,14 +24,14 @@ "repository": { | ||
"dependencies": { | ||
"@newrelic/native-metrics": "4.x.x", | ||
"@hapi/hoek": "8.x", | ||
"@hapi/joi": "15.x", | ||
"@hapi/hoek": "9.x", | ||
"@hapi/joi": "17.x", | ||
"@newrelic/native-metrics": "5.x", | ||
"prom-client": "11.x.x" | ||
}, | ||
"devDependencies": { | ||
"@hapi/code": "6.x", | ||
"eslint-config-hapi": "12.x.x", | ||
"eslint-plugin-hapi": "4.x.x", | ||
"@hapi/hapi": "18.x.x", | ||
"@hapi/lab": "19.x" | ||
"@hapi/code": "8.x", | ||
"@hapi/eslint-config-hapi": "13.x", | ||
"@hapi/eslint-plugin-hapi": "4.x", | ||
"@hapi/hapi": "19.x", | ||
"@hapi/lab": "22.x" | ||
} | ||
} |
113
README.md
# metrics-client | ||
Hapi-centric Prometheus Plugin and optional endpoint | ||
## Usage | ||
Use this plugin to: | ||
@@ -10,1 +8,112 @@ - Add an endpoint for metrics (defaults to `/metrics`) | ||
- Run a server for worker that reports metrics from an endpoint (defaults to `/metrics` on port `3000`) | ||
## Integration | ||
### Modules | ||
Once metric-client is a Hapi-centric Prometheus Plugin. Hapi and metrics-client modules need to be installed. | ||
```bash | ||
npm install -S @hapi/hapi | ||
npm install -S @pager/metrics-client | ||
``` | ||
### Usage | ||
Sample usage for metrics-client server | ||
```js | ||
'use strict'; | ||
const Hapi = require('@hapi/hapi'); | ||
const Metrics = require('@pager/metrics-client'); | ||
const startServer = async () => { | ||
const server = await new Hapi.Server({ | ||
port: 3000 | ||
}); | ||
await server.register([ | ||
{ | ||
plugin: Metrics | ||
} | ||
]); | ||
await server.start(); | ||
console.log( `Server started at ${ server.info.uri }`); | ||
return server; | ||
}; | ||
module.exports = startServer(); | ||
``` | ||
### Annotations | ||
```yaml | ||
annotations: | ||
prometheus.io/scrape: "true" | ||
prometheus.io/port: {{ .Values.service.internalPort | quote }} | ||
``` | ||
### Readiness and Liveness | ||
Readiness probes are designed to let Kubernetes know when your app is ready to serve traffic. Similarly, liveness probes let Kubernetes know if your app is alive or dead. Metric-client plugin is also support health check and needs to be added to the deployment file under container details. | ||
```yaml | ||
livenessProbe: | ||
httpGet: | ||
path: /health | ||
port: {{ .Values.service.internalPort }} | ||
initialDelaySeconds: 15 | ||
timeoutSeconds: 1 | ||
readinessProbe: | ||
httpGet: | ||
path: /health | ||
port: {{ .Values.service.internalPort }} | ||
initialDelaySeconds: 15 | ||
timeoutSeconds: 1 | ||
``` | ||
### Internal Ports | ||
Prometheus server Kubernetes service discovery configuration is going to search running server on kubernetes cluster. It will use default server port `3000`. Thus, metrics-client must start at default port `3000`. If the server is not already running on port `3000`, it should be added on containers details. | ||
```yaml | ||
env: | ||
- name: PORT | ||
value: "3000" | ||
``` | ||
## References | ||
### Health vs Metrics endpoint | ||
Health endpoint is designed to provide information about a readiness and liveness of the server. On the other hand, metrics endpoint provides information about the performance of the server such as load time, response time, memory usage, CPU usage etc. | ||
| Metrics List| | ||
|---| | ||
|cpu_user_time| | ||
|cpu_user_utilization| | ||
|cpu_system_time| | ||
|cpu_system_utilization| | ||
|event_loop_usage| | ||
|event_loop_wait| | ||
|memory_physical| | ||
|memory_heap_used| | ||
|memory_heap_free| | ||
|memory_heap_max| | ||
|memory_nonheap_used| | ||
|http_request_duration_milliseconds| | ||
|http_request_buckets_milliseconds| | ||
|gc_pause_time_min| | ||
|gc_pause_time_max| | ||
|gc_pause_time_total| | ||
|gc_scavenge_min| | ||
|gc_scavenge_max| | ||
|gc_scavenge_total| | ||
|gc_marksweepcompact_min| | ||
|gc_marksweepcompact_max| | ||
|gc_marksweepcompact_total| | ||
|gc_incrementalmarking_min| | ||
|gc_incrementalmarking_max| | ||
|gc_incrementalmarking_total| | ||
23616
495
119
+ Added@hapi/address@4.1.0(transitive)
+ Added@hapi/formula@2.0.0(transitive)
+ Added@hapi/hoek@9.3.0(transitive)
+ Added@hapi/joi@17.1.1(transitive)
+ Added@hapi/pinpoint@2.0.1(transitive)
+ Added@hapi/topo@5.1.0(transitive)
+ Added@newrelic/native-metrics@5.3.0(transitive)
- Removed@hapi/address@2.1.4(transitive)
- Removed@hapi/bourne@1.3.2(transitive)
- Removed@hapi/hoek@8.5.1(transitive)
- Removed@hapi/joi@15.1.1(transitive)
- Removed@hapi/topo@3.1.6(transitive)
- Removed@newrelic/native-metrics@4.1.0(transitive)
Updated@hapi/hoek@9.x
Updated@hapi/joi@17.x
Updated@newrelic/native-metrics@5.x