APM for NodeJS using Prometheus
An APM solution based on metrics and open-source tools such as Prometheus and Grafana for NodeJs-based applications.
npm install --save @last9/openapm@latest
const express = require('express');
const { OpenAPM } = require('@last9/openapm');
const app = express();
const openapm = new OpenAPM();
// Instrument services
app.listen(3000);
const gracefullyShutdown = () => {
app.close(() => {
openapm
.shutdown()
.then(() => {
console.log('OpenAPM shutdown successful.');
})
.catch((err) => {
console.log('Error shutting down OpenAPM', err);
});
});
};
process.on('SIGINT', gracefullyShutdown);
process.on('SIGTERM', gracefullyShutdown);
In the example below, the metrics will be served on localhost:9097/metrics
. To
change the port, you can update it through the options
(See the options documentation).
const { OpenAPM } = require('@last9/openapm');
const openapm = new OpenAPM();
openapm.instrument('express');
This currently supports instrumentation for all Node.js ORMs, which are mysql2 compatible.
Ensure to add this line of code before you initialize db connection/pool/poolCluster
.
openapm.instrument('mysql');
OpenAPM currently supports RED Metrics for NestJS v4 and above.
openapm.instrument('nestjs');
OpenAPM supports RED metrics for both pages and app router in a Next.js application.
openapm.instrument('nextjs');
Note: You can only use the library if Next.js runs in a Node.js environment. Since OpenAPM relies on prom-client for capturing metrics data, a serverless environment might not be able persist them.
const openapm = new OpenAPM({
// Options go here
});
path
: The path at which the metrics will be served. For eg. /metrics
metricsServerPort
: (Optional) The port at which the metricsServer will run.
environment
: (Optional) The application environment. Defaults to
production
.
defaultLabels
: (Optional) Any default labels to be included.
requestsCounterConfig
: (Optional) Requests counter configuration, same as
Counter in prom-client
.
Defaults to
{
name: 'http_requests_total',
help: 'Total number of requests',
labelNames: ['path', 'method', 'status'],
}
requestDurationHistogramConfig
: (Optional) Requests Duration histogram
configuration, the same as
Histogram in
prom-client
. Defaults to
{
name: 'http_requests_duration_milliseconds',
help: 'Duration of HTTP requests in milliseconds',
labelNames: ['path', 'method', 'status'],
buckets: promClient.exponentialBuckets(0.25, 1.5, 31),
}
extractLabels
: (Optional) Extract labels from URL params (WIP: Headers, Subdomain)
// To extract from the URL params
{
...
extractLabels: {
tenant: { // Here 'tenant' is the label name
from : 'params',
key: 'org' // Which key to extract from the params
mask: ':org' // Replacement string
}
}
}
excludeDefaultLabels
: (Optional) Provide labels to exclude from the default labels
{
...
excludeDefaultLabels: ['environment', 'version']
}
levitateConfig
: (Optional) Configuration for Levitate TSDB. Adding this configuration will enable the Change Events.
enableMetricsServer
: (Optional) Defaults to true
. When set to false
the OpenAPM won't start a metrics server. To get the metrics users can rely on the .getMetrics()
function.
{
...
levitateConfig: {
host: 'https://app.last9.io',
orgSlug: 'last9', /** The slug can be obtained from the Last9 dashboard.*/
dataSourceName: 'data-source', /** The data source can be obtained from the data source pages in the Last9 dashboard*/
refreshTokens: {
write: '0d2a1a9a45XXXXXXXXXXXXXX3f1342790d2a1a9a45XXXXXXXXXXXXXX3f1342790d2a1a9a45XXXXXXXXXXXXXX3f134279' /** You can get this from the API access page on Last9 dashboard*/
}
}
}
enabled
: (Optional) Defaults to true
. When set to false
OpenAPM will be disabled and no metrics will be collected or emitted.const openapm = new OpenAPM({
enabled: process.env.NODE_ENV === 'production'
})
instrument
: Used to instrument supported technologies. Refer the usage section.
getMetrics
: Returns a Promise of string which contains metrics in Prometheus exposition format. You can use this function to expose a metrics endpoint if enableMetricsServer
is set to false. For example,
const openapm = new OpenAPM({
enableMetricsServer: false
});
openapm.instrument('express');
const app = express();
app.get('/metrics', async (_, res) => {
const metrics = await openapm.getMetrics();
res.setHeader('Content-Type', 'text/plain; version=0.0.4; charset=utf-8');
res.end(metrics);
});
shutdown
: Returns a promise which is resolved after the cleanup in OpenAPM. The cleanup includes closing the metrics server if it has started and cleared the prom-client register.const gracefullyShutdown = () => {
server.close(() => {
openapm
.shutdown()
.then(() => {
console.log('OpenAPM shutdown successful.');
})
.catch((err) => {
console.log('Error shutting down OpenAPM', err);
});
});
};
process.on('SIGINT', gracefullyShutdown);
process.on('SIGTERM', gracefullyShutdown);
Make sure you are in the express directory.
npm install
Build package
dist
folder.npm run build
Last9 builds reliability tools for SRE and DevOps.