A Prometheus metrics middleware plugin for Verdaccio v5. Collects several types of metrics and exposes them at a
configurable metrics endpoint (defaults to /-/metrics
). The metrics are produced in the standard
prometheus metrics text format.
This plugin is capable of collecting three (3) different types of metrics. Further explanation is provided in the sections below.
This plugin will collect default (standard) metrics when the defaultMetrics.enabled
configuration option is set to
true
. More information about default metrics can be found at:
- https://prometheus.io/docs/instrumenting/writing_clientlibs/#standard-and-runtime-collectors
- https://github.com/siimon/prom-client/tree/v14.0.1#default-metrics
This plugin will collect metrics related to incoming HTTP requests when the requestMetrics.enabled
configuration
option is set to true
. A counter metric is used to track
the number of HTTP requests. The following labels are applied to
every request for this metric:
username
- The Verdaccio username of the user attempting to install/download a package. If the request is unauthenticated then the valueUNKNOWN
is used.userAgentName
- The name of the user agent the client used to make the request. It is derived from theuser-agent
header on the request. If nouser-agent
header is provided it defaults toUNKNOWN
.httpMethod
- The HTTP method used in the request.statusCode
- The status code of the response from Verdaccio.
This plugin will collect metrics related to package tarball downloads when the packageMetrics.enabled
configuration
option is set to true
. A counter metric is used to track
the number of package tarball installs/downloads. The following labels
are applied to every request for this metric:
username
- The Verdaccio username of the user attempting to install/download a package. If the request is unauthenticated then the valueUNKNOWN
is used.userAgentName
- The name of the user agent the client used to make the request. It is derived from theuser-agent
header on the request. If nouser-agent
header is provided it defaults toUNKNOWN
.statusCode
- The status code of the response from Verdaccio.
Optionally, an additional packageGroup
label can be applied if a packageMetrics.packageGroups
option is added to
the plugin configuration. Refer to the Package Groups section of this README for more information.
Because Verdaccio automatically prefixes the string verdaccio-
to the directory it looks for when loading a plugin,
this plugin will need to be installed to a directory named verdaccio-metrics
IF your middlewares
configuration
uses metrics
as the configuration key for this plugin (as shown in the Configuration example). Below
is an example Dockerfile
that can be used to build a custom image containing this plugin. The Verdaccio
plugins
configuration option is assumed to be set to
/verdaccio/plugins
.
# Docker multi-stage build - https://docs.docker.com/develop/develop-images/multistage-build/
# Use an alpine node image to install the plugin
FROM node:lts-alpine as builder
# Install the metrics middleware plugin. Replace `x.y.z` with the plugin version.
RUN mkdir -p /verdaccio/plugins \
&& cd /verdaccio/plugins \
&& npm install --global-style --no-bin-links --omit=optional @devintent/verdaccio-prometheus-middleware@x.y.z
# The final built image will be based on the standard Verdaccio docker image.
FROM verdaccio/verdaccio:5
# Copy the plugin files over from the 'builder' node image.
# The `$VERDACCIO_USER_UID` env variable is defined in the base `verdaccio/verdaccio` image.
# Refer to: https://github.com/verdaccio/verdaccio/blob/v5.13.3/Dockerfile#L32
COPY --chown=$VERDACCIO_USER_UID:root --from=builder \
/verdaccio/plugins/node_modules/@devintent/verdaccio-prometheus-middleware \
/verdaccio/plugins/verdaccio-metrics
Complete configuration example with comments:
middlewares:
metrics:
## Optional. Defaults to `/-/metrics`.
metricsPath: /custom/path/metrics
## Optional. If not specified, no default metrics will be collected.
## Refer to: https://github.com/siimon/prom-client/tree/v14.0.1#default-metrics
defaultMetrics:
## Optional. Defaults to `false`. Make sure to set this to `true` if you want to collect default metrics.
enabled: true
## Optional. If not specified, no http request metrics will be collected.
requestMetrics:
## Optional. Defaults to `false`. Make sure to set this to `true` if you want to collect request metrics.
enabled: true
## Optional. Defaults to 'registry_http_requests'.
metricName: 'registry_http_requests'
## Optional. An array of regular expressions used to match and exclude request paths. The default list of paths to
## exclude are shown below. If you override this array of values these default paths will NOT be included and will
## need to be added manually if you still wish to exclude them. The `metricsPath` is **ALWAYS** excluded.
pathExclusions:
- '^/$' # root path to web ui
- '^/[-]/ping' # health endpoint
- '^/[-]/(static|verdaccio|web)' # web ui related paths
- '[.]ico$' # requests for icons (e.g. `favicon.ico`)
## Optional. If not specified, no package download metrics will be collected.
packageMetrics:
## Optional. Defaults to `false`. Make sure to set this to `true` if you want to collect package download metrics.
enabled: true
## Optional. Defaults to 'registry_package_downloads'.
metricName: 'registry_package_downloads'
## Optional. A map of regular expressions to package grouping names.
packageGroups:
## NOTE: The order of items below matters. The first matched regex is the package grouping that will be applied
## to the metric generated for a request.
'@angular/[^/]*': angular
'react': react
'.*': other
The packageMetrics.packageGroups
configuration option accepts an object map whose keys are expected to be a regular
expression string and the value the name of the package group that should be used for the packageGroup
metric label.
If no packageMetrics.packageGroups
are defined, a packageGroup
label
will NOT be applied to the packageMetrics
counter metric.
The regular expression key is evaluated against the request path in the following manner:
// scoped packages generally have the `/` url encoded to `%2f`
new RegExp(packageGroupRegex).test(decodeURIComponent(request.path));
The order of the keys/values in the object map matters. The regular expressions are evaluated from first to last in the
order they are listed under the packageMetrics.packageGroups
configuration option and the first matching regex will
have the corresponding package grouping value applied when the packageMetrics
counter metric is collected.
Given the following example configuration:
# Verdaccio config file
middlewares:
metrics:
packageMetrics:
enabled: true
packageGroups:
'@babel/plugin': 'babel-plugin'
'babel[-]plugin': 'babel-plugin'
'babel': 'babel'
'@.*': scoped
'.*': other
... the following packages would resolve to the packageGroup
as listed in the table:
Package Name | Package Group |
---|---|
@babel/core |
babel |
@babel/parser |
babel |
@babel/plugin-transform-runtime |
babel-plugin |
babel-plugin-istanbul |
babel-plugin |
babel-jest |
babel |
@angular/core |
scoped |
@apollo/client |
scoped |
react |
other |
apollo-server-express |
other |
This project enforces the Angular commit message format.
A husky prepare-commit-msg
hook is used in conjunction with
commitzen in order to automatically prompt for all required fields in the
commit message. The commitzen
prompts can be bypassed and the commit message may still manually be created by
interrupting the commitzen
prompt using ctrl+c
. A valid commit message is still required as each commit message
is linted using commitlint and a husky
commit-msg
hook to ensure the Angular commit message format
is followed.
Prior to opening a pull request, please ensure that you run the command:
npm run release
This will automatically increment the version number in the package.json
based on the types of commits contained in
the pull request and update the CHANGELOG.md
appropriately. If a specific version type needs to be forced, the same
command can be executed with an argument passed:
# force incrementing to a new major version
npm run release -- -r major