A minimalistic and opinionated Fastify plugin that collects metrics and dispatches them to statsd.
If you write your services and apps using Fastify and also use statsd, this plugin might be for you!
It automatically collects Node.js process metrics along with routes hit count, timings and errors and uses the dats client to send them to a stasd collector.
It supports Fastify versions >=3.0.0.
# lastest stable version
$ npm i -S @immobiliarelabs/fastify-metrics
# latest development version
$ npm i -S @immobiliarelabs/fastify-metrics@next# lastest stable version
$ yarn add @immobiliarelabs/fastify-metrics
# latest development version
$ yarn @immobiliarelabs/fastify-metrics@nextconst fastify = require('fastify')();
fastify.register(require('@immobiliarelabs/fastify-metrics'), {
host: 'udp://someip:someport',
namespace: 'ns',
});
const route = {
// This is required in order to associate a metric to a route
config: {
routeId: 'root.getStatus',
},
url: '/',
method: 'GET',
handler(request, reply) {
reply.send({ ok: true });
},
};
fastify.route(route);
fastify.listen(3000);The plugin uses the key routeId in the config object of the Reply.context. If none is found a default noId string is used.
See https://github.com/fastify/fastify/blob/master/docs/Routes.md#config.
These are the metrics that are collected automatically.
| Name | Type | Unit of measure | Description |
|---|---|---|---|
<METRICS_NAMESPACE>.process.cpu |
gauge |
percentage | process cpu usage |
<METRICS_NAMESPACE>.process.mem.external |
gauge |
bytes | process external memory |
<METRICS_NAMESPACE>.process.mem.rss |
gauge |
bytes | process rss memory |
<METRICS_NAMESPACE>.process.mem.heapUsed |
gauge |
bytes | process heap used memory |
<METRICS_NAMESPACE>.process.mem.heapTotal |
gauge |
bytes | process heap total memory |
<METRICS_NAMESPACE>.process.eventLoopDelay |
gauge |
milliseconds | process event loop delay |
<METRICS_NAMESPACE>.process.eventLoopUtilization |
gauge |
absolute number between 0 and 1 | process event loop utilization |
<METRICS_NAMESPACE>.api.<routeId>.requests |
counter |
unit | requests count per service route |
<METRICS_NAMESPACE>.api.<routeId>.errors.<statusCode> |
counter |
unit | errors count per service route and status code |
<METRICS_NAMESPACE>.api.<routeId>.response_time |
timing |
milliseconds | response time per service route |
The plugin adds the following decorators.
A dats instance.
A doc sampler instance used to sample process metrics, if options.collect.health is true.
A utility function to convert the legacy process.hrtime([time]) value to nanoseconds.
A utility function to convert the legacy process.hrtime([time]) value to microseconds.
A utility function to convert the legacy process.hrtime([time]) value to milliseconds.
A utility function to convert the legacy process.hrtime([time]) value to seconds.
fn<Function>: the function to time. It can be a sync function, an async function, a function returning a promise, or a constructor. Functions with the callback pattern are not supported.options<Object>: optional configuration options.label<string>: the label of the metric, by default is the function name.onSend<Function>: a custom function to send the timing metric. By default it is a function that send the execution time in millisencods with the passednameas label. See theonSenddefinition.timerifyOptions<Object>: the same options object used to configure the Node coretimerifyfunction.
It creates a new function that automatically tracks its execution time and sends the corresponding metric.
TODO: add examples
This decorator uses the core timerify api in conjunction with a PerformanceObserver to time the execution of a function.
Since the name property of the original function is used to create a PerfomanceEntry in the timeline, passing anonymous functions or using the same name for multiple functions will result in conflicts when the PerformanceObserver callback of this decorator function tries to understand which execution time has been tracked. So, avoid using conflicting names when creating timerified functions whenever possible.
name<string>: the label of the metric.value<PerfomanceEntry>: the performance entry of the function.
A syncronous function to send the function execution time. The function context is bound to the fastify instance that registered the plugin.
TODO: add examples
The plugin uses the following hooks:
onClose: To close the dats instanceonRequest: To count requestsonResponse: To measure response timeonError: To count errors
This module exports a plugin registration function.
The plugin is configured with an object with the following properties
host: String. statsd host. See dats.namespace: String. Metrics namespace. See dats.bufferSize: Number. Metrics buffer size. See dats.bufferFlushTimeout: Number. Metrics buffer flush timeout. See dats.sampleInterval: Number. Optional. Sample interval inmsused to gather process stats. Defaults to1000.onError: Function:(err) => void. Optional. This function to handle possible Dats errors. See dats. Default:(err) => fastify.log.error(err)udpDnsCache: Boolean. Optional. Activate udpDnsCache. Defaulttrue.udpDnsCacheTTL: Number. Optional. DNS cache Time to live of an entry in seconds. Default120.collect: Object. Optional. Which metrics the plugin should track.collect.timings: Boolean. Collect response timings (<METRICS_NAMESPACE>.api.<routeId>). Default:true.collect.hits: Boolean. Collect requests count (<METRICS_NAMESPACE>.api.requests.<routeId>). Default:true.collect.errors: Boolean. Collect errors count (<METRICS_NAMESPACE>.api.errors.<routeId>.<statusCode>). Default:true.collect.health: Boolean. Collect process health data (<METRICS_NAMESPACE>.process.*). Default:true.
fastify-metrics was created by the amazing Node.js team at ImmobiliareLabs, the Tech dept of Immobiliare.it, the #1 real estate company in Italy.
We are currently using fastify-metrics in our products as well as our internal toolings.
If you are using fastify-metrics in production drop us a message.
Made with ❤️ by ImmobiliareLabs & Contributors
We'd love for you to contribute to fastify-metrics!
If you have any questions on how to use fastify-metrics, bugs and enhancement please feel free to reach out by opening a GitHub Issue.
fastify-metrics is licensed under the MIT license.
See the LICENSE file for more information.
