@lokalise/fastify-extras
v26.0.0
Published
Opinionated set of fastify plugins, commonly used in Lokalise
Downloads
11,549
Readme
fastify-extras 🧩
Reusable plugins for Fastify.
Dependency Management
The following needs to be taken into consideration when adding new runtime dependency for the fastify-extras
package:
- If dependency is an implementation detail, and end consumer is not expected to import and use the dependency directly, it should be a
dependency
; - If dependency needs to be imported and used by consumer directly for it to function properly, it should be a
peerDependency
.
Dependencies
@bugsnag/js
;@splitsoftware/splitio
;fastify-metrics
;fastify-plugin
;tslib
.
Peer Dependencies
@fastify/jwt
;fastify
;newrelic
;pino
;bullmq
;
Plugins
RequestContext Provider Plugin
Plugin to:
- extend existing
FastifyRequest
with request context by setting the following:logger
, a child logger of app.log, with prepopulated headerx-request-id
;reqId
, the request-id;
No options are required to register the plugin.
The getRequestIdFastifyAppConfig()
method is exported and returns:
genReqId
, a function for generating the request-id;requestIdHeader
, the header name used to set the request-id.
Which can be passed to Fastify during instantiation.
Public Healthcheck Plugin
Plugin to monitor app status through public healthcheck.
Add the plugin to your Fastify instance by registering it with the following options:
healthChecks
, a list of promises with healthcheck in the callback;responsePayload
(optional), the response payload that the public healthcheck should return. If no response payload is provided, the default response is:{ "heartbeat": "HEALTHY" }
Your Fastify app will reply with the status of the app when hitting the GET /
route.
Common Healthcheck Plugin
Plugin to monitor app status through public and private healthchecks.
Add the plugin to your Fastify instance by registering it with the following options:
healthChecks
, a list of promises with healthcheck in the callback;responsePayload
(optional), the response payload that the healthcheck should return. If no response payload is provided, the default response is:{ "heartbeat": "HEALTHY", "checks": {} }
Your Fastify app will reply with the status of the app when hitting the GET /
public route with aggregated heartbeat from healthchecks provided, example:
{
"heartbeat": "HEALTHY"
}
Your Fastify app will reply with the status of the app when hitting the GET /health
private route with detailed results from healthchecks provided, example:
{
"heartbeat": "PARTIALLY_HEALTHY",
"checks": {
"check1": "HEALTHY",
"check2": "HEALTHY",
"check3": "FAIL"
}
}
Split IO Plugin
Plugin to handle feature flags in Split IO.
Add the plugin to your Fastify instance by registering it with the following options:
isEnabled
, iftrue
the plugin will connect to Split IO using the providedapiKey
and store data in memory with background syncing;apiKey
, your SDK key;debugMode
;localhostFilePath
(optional), used to utilize the SDK in localhost mode. It corresponds to the full path to a file with the mapping of feature flag name to treatment.apiKey
will be automatically replaced withlocalhost
iflocalhostFilePath
is provided.
The plugin decorates your Fastify instance with a SplitIOFeatureManager
, which you can inject and use to leverage the following methods:
init()
, returns a promise that resolves once the SDK has finished loading. It's called automatically when registering the plugin;getTreatment()
, returns the proper treatment based on the feature flag name and the key in input. Expected parameters are:key
, the ID of the user/account/etc. you're trying to evaluate a treatment for;splitName
, the Split IO feature flag name;attributes
(optional), a set of Attributes used in evaluation to further decide whether to show the on or off treatment;
NOTE: If
isEnabled
is false,getTreatement()
will returncontrol
to signal disabled treatment.getTreatmentWithConfig()
, used to leverage dynamic configurations with your treatment. It accepts the same parameters asgetTreatment()
, but the response structure is as follows:type TreatmentResult = { treatment: string config: string | null }
NOTE: If
isEnabled
is false,getTreatementWithConfig()
will returncontrol
astreatment
andnull
asconfig
to signal disabled treatment.track()
, used to record any actions your customers perform. Returns a boolean to indicate whether or not the SDK was able to successfully queue the event. Expected parameters are:key
, the ID of the user/account/etc. you're trying to evaluate a treatment for;trafficType
, the traffic type of the key;eventType
, the event type that this event should correspond to;value
(optional), the value to be used in creating the metric;properties
(optional), an object of key value pairs that represent the properties to be used to filter your metrics;
shutdown()
, gracefully shuts down the client.
More info about Split IO can be checked here.
BugSnag Plugin
Plugin to report errors to BugSnag.
Add the plugin to your Fastify instance by registering it with the following options:
isEnabled
;bugsnag
, a set of customizable xonfiguration options.
Once the plugin has been added to your Fastify instance and loaded, errors will be reported to BugSnag.
Metrics Plugin
Plugin to expose Prometheus metrics.
Add the plugin to your Fastify instance by registering it with the following options:
loggerOptions
, used to configure the internal logger instance. It can be a boolean or a set of Pino options. By default it is set tofalse
and the logger is disabled;disablePrometheusRequestLogging
(optional). By default Fastify will issue aninfo
level log message when a request is received and when the response for that request has been sent. By setting this option totrue
, these log messages will be disabled. Defaults totrue
;bindAddress
(optional). By default, the server will listen on the address(es) resolved by localhost when no specific host is provided. See the possible values for host when targeting localhost here;errorObjectResolver
, a resolver method that, given anerr
and optionally acorrelationID
, it will log the error if something goes wrong.
The plugin exposes a GET /metrics
route in your Fastify app to retrieve Prometheus metrics. If something goes wrong while starting the Prometheus metrics server, an Error
is thrown. Otherwise, a success message is displayed when the plugin has been loaded.
PrometheusCounterTransactionManager
PrometheusCounterTransactionManager
is an implementation of TransactionObservabilityManager
that uses Prometheus
counters to track the number of started, failed, and successful transactions. The results are automatically added to
the /metrics
endpoint exposed by the metrics plugin.
BullMQ Metrics Plugin
Plugin to auto-discover BullMQ queues which can regularly collect metrics for them and expose via fastify-metrics
global Prometheus registry. If used together with metricsPlugin
, it will show these metrics on GET /metrics
route.
This plugin depends on the following peer-installed packages:
bullmq
ioredis
Add the plugin to your Fastify instance by registering it with the following possible options:
redisConfigs
, Redis configurations used for BullMQ. Plugin uses them to discover the queues.bullMqPrefix
(optional, default:bull
). The prefix used by BullMQ to store the queues in Redis;metricsPrefix
(optional, default:bullmq
). The prefix for the metrics in Prometheus;queueDiscoverer
(optional, default:BackgroundJobsBasedQueueDiscoverer
). The queue discoverer to use. The default one relies on the logic implemented by@lokalise/background-jobs-common
where queue names are registered by the background job processors; If you are not using@lokalise/background-jobs-common
, you can use your own queue discoverer by instantiating aRedisBasedQueueDiscoverer
or implementing aQueueDiscoverer
interface;excludedQueues
(optional, default:[]
). An array of queue names to exclude from metrics collection;histogramBuckets
(optional, default:[20, 50, 150, 400, 1000, 3000, 8000, 22000, 60000, 150000]
). Buckets for the histogram metrics (such as job completion or overall processing time).collectionOptions
(optional, default:{ type: 'interval', intervalInMs: 5000 }
). Allows to configure how metrics are collected. Supports the following properties:type
. Can be eitherinterval
ormanual
.- With
interval
type, plugin automatically loops and updates metrics at the specified interval. - With
manual
type, you need to callapp.bullMqMetrics.collect()
to update the metrics; that allows you to build your own logic for scheduling the updates.
- With
intervalInMs
(only fortype: 'interval'
). The interval in milliseconds at which the metrics are collected;
This plugin exposes bullMqMetrics.collect()
method on the Fastify instance to manually trigger the metrics collection.
If something goes wrong while starting the BullMQ metrics plugin, an Error
is thrown.
NewRelic Transaction Manager Plugin
Plugin to create custom NewRelic spans for background jobs.
Add the plugin to your Fastify instance by registering it with the following options:
isEnabled
.
The plugin decorates your Fastify instance with a NewRelicTransactionManager
, which you can inject and use to leverage the following methods:
start()
, which takes ajobName
, and starts a background transaction with the provided name;stop()
, which takes ajobId
, and ends the background transaction referenced by the ID;addCustomAttribute()
, which takesattrName
andattrValue
and adds the custom attribute to the current transaction.attrValue
can be a string, a number, or a boolean.addCustomAttributes()
, which passesatts
map of the custom attributes to the current transaction._uniqueTransactionKey
argument is not used (because New Relic doesn't support setting custom attributes directly on the transaction handle), any string can be passed.
Amplitude Plugin
This plugin facilitates the transmission of events to Amplitude.
To add this plugin to your Fastify instance, register it with the following configurations:
isEnabled
: A flag utilized to activate or de-activate the plugin.apiKey
(optional): This refers to the Amplitude API key which can be procured from your respective Amplitude project.options
(optional): To configure Amplitude, please refer to this documentation.apiUsageTracking
(optional): You can use this callback to generate an event that will automatically be sent for tracking API usage. Non-specification of this feature will lead to disabling of API tracking.plugins
(optional): This feature allows you to expand the plugin's functionality, from altering event properties to relaying to third-party APIs. To learn more, visit this link.
The plugin decorates your Fastify instance with a Amplitude
, which you can inject and use the track
method on it to send events whenever you need
📘 To ensure optimal functionality with this plugin, you may need to incorporate Amplitude types into your development dependencies.
"@amplitude/analytics-types": "*"
Additionally, you have the option to enhance the safety and accuracy of your events and properties by wrapping your Amplitude
instance with AmplitudeAdapter
.
📘Check `AmplitudeAdapter.spec.ts for a practical example
UnhandledException Plugin
This plugin provides a mechanism for handling uncaught exceptions within your Fastify application, ensuring that such exceptions are logged and reported. It's especially useful for capturing unforeseen exceptions and provides a controlled shutdown of the Fastify server, thereby ensuring no potential data corruption.
Setup & Configuration
To integrate this plugin into your Fastify instance, follow these steps:
- First, import the necessary types and the plugin:
import { FastifyInstance } from 'fastify'
import { unhandledExceptionPlugin, ErrorObjectResolver } from '@lokalise/fastify-extras'
- Configure the plugin:
Define your own ErrorObjectResolver
to dictate how the uncaught exceptions will be structured for logging. Here's an example:
const myErrorResolver: ErrorObjectResolver = (err, correlationID) => {
return {
error: err,
id: correlationID,
}
}
You'll also need to provide an ErrorReporter
instance. This instance should have a report
method to handle the error reporting logic. For example:
import { ErrorReporter } from '@lokalise/node-core'
const myErrorReporter = new ErrorReporter(/* initialization params */)
- Register the plugin with your Fastify instance:
const fastify = Fastify()
fastify.register(unhandledExceptionPlugin, {
errorObjectResolver: myErrorResolver,
errorReporter: myErrorReporter,
})
Options
The plugin accepts the following options:
errorObjectResolver
(required): This function determines the structure of the error object which will be logged in case of an uncaught exception.errorReporter
(required): An instance of the ErrorReporter which will handle reporting of the uncaught exceptions.
Working Principle
When an uncaught exception occurs, the plugin:
Logs the exception using the provided
errorObjectResolver
.Reports the exception using the
ErrorReporter
.Shuts down the Fastify server gracefully.
Exits the process with exit code
1
.
Dependencies
@lokalise/node-core
: For error reporting.fastify
: The framework this plugin is designed for.
🚨 It's critical to note that this plugin listens to the process's 'uncaughtException' event. Multiple listeners on this event can introduce unpredictable behavior in your application. Ensure that this is the sole listener for this event or handle interactions between multiple listeners carefully.
Utilities
route-utilities
authPreHandlers
createStaticTokenAuthPreHandler
- creates pre handler tha expects a static token in theAuthorization
header. If value is different from the expected token, it will return a 401 response.