Giter Club home page Giter Club logo

promster's Introduction

Logo

⏰ Promster - Measure metrics from Hapi, express, Marble.js, Apollo or Fastify servers with Prometheus 🚦

Promster is an Prometheus Exporter for Node.js servers written for Express, Hapi, Marble.js, Apollo or Fastify.

❀️ Hapi Β· Express Β· Marble.js Β· Fastify Β· Apollo Β· Prettier Β· TypeScript Β· Jest Β· ESLint Β· Changesets Β· Prometheus πŸ™

Test & build status Codecov Coverage Status Known Vulnerabilities Made with Coffee

❯ Package Status

Package Version Downloads
promster/hapi hapi Version hapi Downloads
promster/express express Version express Downloads
promster/marblejs marblejs Version marblejs Downloads
promster/fastify fastify Version fastify Downloads
promster/apollo apollo Version apollo Downloads
promster/server server Version server Downloads
promster/metrics metrics Version metrics Downloads

❯ Why another Prometheus exporter for Express and Hapi?

These packages are a combination of observations and experiences I have had with other exporters which I tried to fix.

  1. 🏎 Use process.hrtime.bigint() for high-resolution real time in metrics in seconds (converting from nanoseconds)
    • process.hrtime.bigint() calls libuv's uv_hrtime, without system call like new Date
  2. βš”οΈ Allow normalization of all pre-defined label values
  3. πŸ–₯ Expose Garbage Collection among other metric of the Node.js process by default
  4. 🚨 Expose a built-in server to expose metrics quickly (on a different port) while also allowing users to integrate with existing servers
  5. πŸ“Š Define two metrics one histogram for buckets and a summary for percentiles for performant graphs in e.g. Grafana
  6. πŸ‘©β€πŸ‘©β€πŸ‘§ One library to integrate with Hapi, Express and potentially more (managed as a mono repository)
  7. πŸ¦„ Allow customization of labels while sorting them internally before reporting
  8. 🐼 Expose Prometheus client on Express locals or Hapi app to easily allow adding more app metrics

❯ Installation

This is a mono repository maintained using changesets. It currently contains four packages in a metrics, a hapi or express integration, and a server exposing the metrics for you if you do not want to do that via your existing server.

Depending on the preferred integration use:

yarn add @promster/express or npm i @promster/express --save

or

yarn add @promster/hapi or npm i @promster/hapi --save

Please additionally make sure you have a prom-client installed. It is a peer dependency of @promster as some projects might already have an existing prom-client installed. Which otherwise would result in different default registries.

yarn add prom-client or npm i prom-client --save

❯ Documentation

Promster has to be setup with your server. Either as an Express middleware of an Hapi plugin. You can expose the gathered metrics via a built-in small server or through our own.

Please, do not be scared by the variety of options. @promster can be setup without any additional configuration options and has sensible defaults. However, trying to suit many needs and different existing setups (e.g. metrics having recording rules over histograms) it comes with all those options listed below.

The following metrics are exposed

Garbage Collection

  • nodejs_up: an indication if the nodejs server is started: either 0 (not up) or 1 (up)
  • nodejs_gc_runs_total: total garbage collections count
  • nodejs_gc_pause_seconds_total: time spent in garbage collection
  • nodejs_gc_reclaimed_bytes_total: number of bytes reclaimed by garbage collection

With all garbage collection metrics a gc_type label with one of: unknown, scavenge, mark_sweep_compact, scavenge_and_mark_sweep_compact, incremental_marking, weak_phantom or all will be recorded.

HTTP Timings (Hapi, Express, Marble.js and Fastify)

  • http_requests_total: a Prometheus counter for the http request total
    • This metric is also exposed on the following histogram and summary which both have a _sum and _count and enabled for ease of use. It can be disabled by configuring with metricTypes: Array<String>.
  • http_request_duration_seconds: a Prometheus histogram with request time buckets in seconds (defaults to [ 0.05, 0.1, 0.3, 0.5, 0.8, 1, 1.5, 2, 3, 5, 10 ])
    • A histogram exposes a _sum and _count which are a duplicate to the above counter metric.
    • A histogram can be used to compute percentiles with a PromQL query using the histogram_quantile function. It is advised to create a Prometheus recording rule for performance.
  • http_request_duration_per_percentile_seconds: a Prometheus summary with request time percentiles in seconds (defaults to [ 0.5, 0.9, 0.99 ])
    • This metric is disabled by default and can be enabled by passing metricTypes: ['httpRequestsSummary]. It exists for cases in which the above histogram is not sufficient, slow or recording rules can not be set up.
  • http_request_content_length_bytes: a Prometheus histogram with the request content length in bytes (defaults to [ 100000, 200000, 500000, 1000000, 1500000, 2000000, 3000000, 5000000, 10000000, ])
    • This metric is disabled by default and can be enabled by passing metricTypes: ['httpContentLengthHistogram].
  • http_response_content_length_bytes: a Prometheus histogram with the request content length in bytes (defaults to [ 100000, 200000, 500000, 1000000, 1500000, 2000000, 3000000, 5000000, 10000000, ])
    • This metric is disabled by default and can be enabled by passing metricTypes: ['httpContentLengthHistogram].

In addition with each http request metric the following default labels are measured: method, status_code and path. You can configure more labels (see below).

  • http_requests_total: a Prometheus counter for the total amount of http requests

You can also opt out of either the Prometheus summary or histogram by passing in { metricTypes: ['httpRequestsSummary'] }, { metricTypes: ['httpRequestsHistogram'] } or { metricTypes: ['httpRequestsTotal'] }.

GraphQL Timings (Apollo)

  • graphql_parse_duration_seconds: a Prometheus histogram with the request parse duration in seconds.
  • graphql_validation_duration_seconds: a Prometheus histogram with the request validation duration in seconds.
  • graphql_resolve_field_duration_seconds: a Prometheus histogram with the field resolving duration in seconds.
  • graphql_request_duration_seconds: a Prometheus histogram with the request duration in seconds.
  • graphql_errors_total: a Prometheus counter with the errors occurred during parsing, validation or field resolving.

In addition with each GraphQL request metric the following default labels are measured: operation_name and field_name. For errors a phase label is present.

Customizing buckets and percentiles

Each Prometheus histogram or summary can be customized in regard to its bucket or percentile values. While @promster offers some defaults, these might not always match your needs. To customize the metrics you can pass a metricBuckets or metricPercentiles object whose key is the metric name you intend to customize the the value is the percentile or bucket value passed to the underlying Prometheus metric.

To illustrate this, we can use the @promster/express middleware:

const middleware = createMiddleware({
  app,
  options: {
    metricBuckets: {
      httpRequestContentLengthInBytes: [
        100000, 200000, 500000, 1000000, 1500000, 2000000, 3000000, 5000000,
        10000000,
      ],
      httpRequestDurationInSeconds: [
        0.05, 0.1, 0.3, 0.5, 0.8, 1, 1.5, 2, 3, 10,
      ],
    },
    metricPercentiles: {
      httpRequestDurationPerPercentileInSeconds: [0.5, 0.9, 0.95, 0.98, 0.99],
      httpResponseContentLengthInBytes: [
        100000, 200000, 500000, 1000000, 1500000, 2000000, 3000000, 5000000,
        10000000,
      ],
    },
  },
});

@promster/express

const app = require('./your-express-app');
const { createMiddleware } = require('@promster/express');

// Note: This should be done BEFORE other routes
// Pass 'app' as middleware parameter to additionally expose Prometheus under 'app.locals'
app.use(createMiddleware({ app, options }));

Passing the app into the createMiddleware call attaches the internal prom-client to your Express app's locals. This may come in handy as later you can:

// Create an e.g. custom counter
const counter = new app.locals.Prometheus.Counter({
  name: 'metric_name',
  help: 'metric_help',
});

// to later increment it
counter.inc();

@promster/fastify

const app = require('./your-fastify-app');
const { plugin: promsterPlugin } = require('@promster/fastify');

fastify.register(promsterPlugin);

Plugin attaches the internal prom-client to your Fastify instance. This may come in handy as later you can:

// Create an e.g. custom counter
const counter = new fastify.Prometheus.Counter({
  name: 'metric_name',
  help: 'metric_help',
});

// to later increment it
counter.inc();

@promster/hapi

const { createPlugin } = require('@promster/hapi');
const app = require('./your-hapi-app');

app.register(createPlugin({ options }));

Here you do not have to pass in the app into the createPlugin call as the internal prom-client will be exposed onto Hapi as in:

// Create an e.g. custom counter
const counter = new app.Prometheus.Counter({
  name: 'metric_name',
  help: 'metric_help',
});

// to later increment it
counter.inc();

@promster/marblejs

const promster = require('@promster/marblejs');

const middlewares = [
  promster.createMiddleware(),
  //...
];

const serveMetrics$ = r
  .matchPath('/metrics')
  .matchType('GET')
  .use(async (req$) =>
    req$.pipe(
      mapTo({
        headers: { 'Content-Type': promster.getContentType() },
        body: await promster.getSummary(),
      })
    )
  );

@promster/apollo

const {
  createPlugin: createPromsterMetricsPlugin,
} = require('@promster/apollo');

const server = new ApolloServer({
  typeDefs,
  resolvers,
  plugins: [createPromsterMetricsPlugin()],
});

await server.listen();

When creating either the Express middleware or Hapi plugin the following options can be passed:

  • labels: an Array<String> of custom labels to be configured both on all metrics mentioned above
  • metricPrefix: a prefix applied to all metrics. The prom-client's default metrics and the request metrics
  • metricTypes: an Array<String> containing one of histogram, summary or both
  • metricNames: an object containing custom names for one or all metrics with keys of up, countOfGcs, durationOfGc, reclaimedInGc, httpRequestDurationPerPercentileInSeconds, httpRequestDurationInSeconds
    • Note that each value can be an Array<String> so httpRequestDurationInSeconds: ['deprecated_name', 'next_name'] which helps when migrated metrics without having gaps in their intake. In such a case deprecated_name would be removed after e.g. Recording Rules and dashboards have been adjusted to use next_name. During the transition each metric will be captured/recorded twice.
  • getLabelValues: a function receiving req and res on reach request. It has to return an object with keys of the configured labels above and the respective values
  • normalizePath: a function called on each request to normalize the request's path. Invoked with (path: string, { request, response })
  • normalizeStatusCode: a function called on each request to normalize the respond's status code (e.g. to get 2xx, 5xx codes instead of detailed ones). Invoked with (statusCode: number, { request, response })
  • normalizeMethod: a function called on each request to normalize the request's method (to e.g. hide it fully). Invoked with (method: string, { request, response })
  • skip: a function called on each response giving the ability to skip a metric. The method receives req, res and labels and returns a boolean: skip(req, res, labels) => Boolean
  • detectKubernetes: a boolean defaulting to false. Whenever trueis passed the process does not run within Kubernetes any metric intake is skipped (good e.g. during testing).
  • disableGcMetrics: a boolean defaulted to false to indicate if Garbage Collection metric should be disabled and hence not collected.

Moreover, both @promster/hapi and @promster/express expose the request recorder configured with the passed options and used to measure request timings. It allows easy tracking of other requests not handled through express or Hapi for instance calls to an external API while using promster's already defined metric types (the httpRequestsHistogram etc).

// Note that a getter is exposed as the request recorder is only available after initialisation.
const { getRequestRecorder, timing } = require('@promster/express');

const async fetchSomeData = () => {
  const recordRequest = getRequestRecorder();
  const requestTiming = timing.start();

  const data = await fetch('https://another-api.com').then(res => res.json());

  recordRequest(requestTiming, {
    other: 'label-values'
  });

  return data;
}

Lastly, both @promster/hapi and @promster/express expose setters for the up Prometheus gauge. Whenever the server finished booting and is ready you can call signalIsUp(). Given the server goes down again you can call signalIsNotUp() to set the gauge back to 0. There is no standard hook in both express and Hapi to tie this into automatically. Other tools to indicate service health such as lightship indicating Kubernetes Pod liveliness and readiness probes also offer setters to alter state.

@promster/server

In some cases you might want to expose the gathered metrics through an individual server. This is useful for instance to not have GET /metrics expose internal server and business metrics to the outside world. For this you can use @promster/server:

const { createServer } = require('@promster/server');

// NOTE: The port defaults to `7788`.
createServer({ port: 8888 }).then((server) =>
  console.log(`@promster/server started on port 8888.`)
);

Options with their respective defaults are port: 7788, hostname: '0.0.0.0' and detectKubernetes: false. Whenever detectKubernetes is passed as true and the server will not start locally.

@promster/{express,hapi}

You can use the express or hapi package to expose the gathered metrics through your existing server. To do so just:

const app = require('./your-express-app');
const { getSummary, getContentType } = require('@promster/express');

app.use('/metrics', async (req, res) => {
  req.statusCode = 200;

  res.setHeader('Content-Type', getContentType());
  res.end(await getSummary());
});

This may slightly depend on the server you are using but should be roughly the same for all.

The packages re-export most things from the @promster/metrics package including two other potentially useful exports in Prometheus (the actual client) and defaultRegister which is the default register of the client. After all you should never really have to install @promster/metrics as it is only and internally shared packages between the others.

Additionally you can import the default normalizers via const { defaultNormalizers } = require('@promster/express) and use normalizePath, normalizeStatusCode and normalizeMethod from you getLabelValues. A more involved example with getLabelValues could look like:

app.use(
  createMiddleware({
    app,
    options: {
      labels: ['proxied_to'],
      getLabelValues: (req, res) => {
        if (res.proxyTo === 'someProxyTarget')
          return {
            proxied_to: 'someProxyTarget',
            path: '/',
          };
        if (req.get('x-custom-header'))
          return {
            path: null,
            proxied_to: null,
          };
      },
    },
  })
);

Note that the same configuration can be passed to @promster/hapi.

Example PromQL queries

In the past we have struggled and learned a lot getting appropriate operational insights into our various Node.js based services. PromQL is powerful and a great tool but can have a steep learning curve. Here are a few queries per metric type to maybe flatten that curve. Remember that you may need to configure the metricTypes: Array<String> to e.g. metricTypes: ['httpRequestsTotal', 'httpRequestsSummary', 'httpRequestsHistogram'] }.

http_requests_total

HTTP requests averaged over the last 5 minutes

rate(http_requests_total[5m])

A recording rule for this query could be named http_requests:rate5m

HTTP requests averaged over the last 5 minutes by Kubernetes pod

sum by (kubernetes_pod_name) (rate(http_requests_total[5m]))

A recording rule for this query could be named kubernetes_pod_name:http_requests:rate5m

Http requests in the last hour

increase(http_requests_total[1h])

Average Http requests by status code over the last 5 minutes

sum by (status_code) (rate(http_requests[5m]))

A recording rule for this query could be named status_code:http_requests:rate5m

Http error rates as a percentage of the traffic averaged over the last 5 minutes

rate(http_requests_total{status_code=~"5.*"}[5m]) / rate(http_requests_total[5m])

A recording rule for this query could be named http_requests_per_status_code5xx:ratio_rate5m

http_request_duration_seconds

Http requests per proxy target

sum by (proxied_to) (increase(http_request_duration_seconds_count{proxied_to!=""}[2m]))

A recording rule for this query should be named something like proxied_to_:http_request_duration_seconds:increase2m.

99th percentile of http request latency per proxy target

histogram_quantile(0.99, sum by (proxied_to,le) (rate(http_request_duration_seconds_bucket{proxied_to!=""}[5m])))

A recording rule for this query could be named proxied_to_le:http_request_duration_seconds_bucket:p99_rate5m

http_request_duration_per_percentile_seconds

Maximum 99th percentile of http request latency by Kubernetes pod

max(http_request_duration_per_percentile_seconds{quantile="0.99") by (kubernetes_pod_name)

nodejs_eventloop_lag_seconds

Event loop lag averaged over the last 5 minutes by release

sum by (release) (rate(nodejs_eventloop_lag_seconds[5m]))

network_concurrent_connections_count

Concurrent network connections

sum(rate(network_concurrent_connections_count[5m]))

A recording rule for this query could be named network_concurrent_connections:rate5m

nodejs_gc_reclaimed_bytes_total

Bytes reclaimed in garbage collection by type

sum by (gc_type) (rate(nodejs_gc_reclaimed_bytes_total[5m]))

nodejs_gc_pause_seconds_total

Time spend in garbage collection by type

sum by (gc_type) (rate(nodejs_gc_pause_seconds_total[5m]))

promster's People

Contributors

aizerin avatar apascal avatar dependabot[bot] avatar dhs3000 avatar dunklestoast avatar earnubs avatar iiroj avatar jasonyihk avatar jozefflakus avatar kppullin avatar makepanic avatar morriskimani avatar natoehv avatar pmudra avatar r4j4h avatar raviqqe avatar renovate-bot avatar renovate[bot] avatar roikoren755 avatar roumigus avatar santiagopoli avatar tdeekens avatar todd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

promster's Issues

Error: Added label "field_name" is not included in initial labelset

Describe the bug

Errors thrown in GraphQL execute phase are not handled:

node_1               | Error: Added label "field_name" is not included in initial labelset: [ 'operation_name', 'operation_name', 'phase' ]
node_1               |     at validateLabel (/opt/node_app/node_modules/prom-client/lib/validation.js:20:10)
node_1               |     at Counter.inc (/opt/node_app/node_modules/prom-client/lib/counter.js:24:4)
node_1               |     at /opt/node_app/node_modules/@promster/apollo/dist/promster-apollo.cjs.dev.js:164:28
node_1               |     at Array.forEach (<anonymous>)
node_1               |     at /opt/node_app/node_modules/@promster/apollo/dist/promster-apollo.cjs.dev.js:163:160
node_1               |     at /opt/node_app/node_modules/apollo-server-core/dist/utils/dispatcher.js:57:17
node_1               |     at /opt/node_app/node_modules/apollo-server-core/dist/utils/schemaInstrumentation.js:76:56
node_1               |     at processTicksAndRejections (node:internal/process/task_queues:96:5)

To Reproduce
Steps to reproduce the behavior:

And directive which throws an error in execute phase won't be handled / counted.

Expected behavior

Expect graphql_errors_total to increment

Additional context

Attempted to write a test for the issue here, not sure if the solution is correct https://github.com/tdeekens/promster/compare/main...earnubs:errors-in-execution-phase?expand=1

Splitting duration and size buckets in configuration

Is your feature request related to a problem? Please describe.

  • Currently, we can configure only one bucket used for both HTTP request durations and sizes.
  • This leads really rough metrics or max values of metrics being cut off.
    • For example, a max bucket of 60 seconds for request durations corresponds to the one of 60 bytes for request sizes. The former is too large but the latter is too small for their common values.

Describe the solution you'd like

  • Split duration and size buckets in configurations.
  • Name them like requestBucket and sizeBucket?
  • I'm personally not sure if we should split the ones for request sizes and response sizes though.

Describe alternatives you've considered

We can also set up one big bucket that ranges from a very small unit (e.g. 0.01) to a very large unit (e.g. 1000000.) However, that leads to unnecessarily large metrics storage sizes.

Additional context

N/A

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: Cannot find preset's package (github>whitesource/merge-confidence:beta)

'@promster/express' is not in the npm registry

Describe the bug
Hey

$ npm info @promster/express returns:

npm ERR! code E404
npm ERR! 404 '@promster/express' is not in the npm registry.
npm ERR! 404 You should bug the author to publish it
npm ERR! 404 (or use the name yourself!)
npm ERR! 404 
npm ERR! 404 Note that you can also install from a
npm ERR! 404 tarball, folder, http url, or git url.
npm ERR! 404 
npm ERR! 404  '@promster/express@latest' is not in the npm registry.
npm ERR! 404 You should bug the author to publish it (or use the name yourself!)
npm ERR! 404 
npm ERR! 404 Note that you can also install from a
npm ERR! 404 tarball, folder, http url, or git url.

Was the package removed from npm registry or it's a npm issue?

Additional context
node v12.13.1 (npm v6.12.1)

Also https://registry.npmjs.com/@promster/express and https://registry.yarnpkg.com/@promster/express return 404

Provide default Grafana dashboard

Is your feature request related to a problem? Please describe.

PromQL is powerful and a great tool but can have a steep learning curve.

I totally agree with this statement in the readme as I am very new to Prometheus and Grafana.
For me it was easy to include promster into a hapi server app.
But building a Grafana dashboard is a little more complicated than I thought.

Describe the solution you'd like

I would appreciate an example Grafana dashboard definition as a starting point.

Describe alternatives you've considered

Well, building one on my own obviously πŸ˜„

Additional context

n/a

pass req to normalizePath() to allow for more flexibility

I was wondering whether passing the full req object to the normalizePath (as second argument) would be a nice addition to ease path normalization; for example, if using express one could use the req.route info to map paths like /a/666/store/22334455 into '/a/:areaId/id/:storeId', thus reducing cardinality a lot

Hapi plugin package.json require path is wrong

npm i @promster/hapi --save
npm install

added this to my Hapi17 project
const { createPlugin } = require('@promster/hapi');

started the app:
-> error:

 Error: Cannot find module '../package.json'
    at Function.Module._resolveFilename (module.js:547:15)
     at Function.Module._load (module.js:474:25)
     at Module.require (module.js:596:17)
     at require (internal/module.js:11:18)
     at Object.<anonymous> (/home/project/node_modules/@promster/hapi/modules/plugin/plugin.js:1:75)

comes from this line:

const pkg = require('../package.json');

Error accessing `request.promster.start` in hapi

Describe the bug

To Reproduce
Steps to reproduce the behavior:

  1. Given a server as follows:
  import { createPlugin } from '@promster/hapi'
  import { createServer as createMetricsServer } from '@promster/server'
  import Hapi from '@hapi/hapi'

  const server = Hapi.server({
    port: 4000,
    host: process.env.HOST,
  })

  await server.register(createPlugin())

  server.route({
    method: 'GET',
    path: '/',
    handler: (request, h) => {
      return 'hello!'
    }
  })

  await server.start()
  console.log('Server running on %s', server.info.uri)

  await createMetricsServer({ port: 4001 })
  console.log(`@promster/server started on port ${process.env.METRICS_PORT}.`)

  await server.register(createPlugin())
  1. Then 'curl localhost:4000'
TypeError: Cannot read property 'start' of undefined
    at Object.onResponseHandler [as listener] (/...../myserver/node_modules/@promster/hapi/modules/plugin/plugin.js:54:40)

Expected behavior

  • No error and request.promster available in onResponseHandler

Additional context

Plugin-specific state. Provides a place to store and pass request-level plugin data. The

  • Strangely, when debugging, the onRequestHandler wouldn't get called on incoming requests.

`process.hrtime([time])` is no longer recommended for use

Node.js documentation lists process.hrtime([time]) as a legacy feature. It is no longer recommended for use, and should be avoided.

Documentation recommends the use of process.hrtime.bigint(), that works slightly different. It does not support an additional time argument since bigint that it returns can easily be subtracted to find the difference.

Example from the documentation:

import { hrtime } from 'process';

const start = hrtime.bigint();
// 191051479007711n

setTimeout(() => {
  const end = hrtime.bigint();
  // 191052633396993n

  console.log(`Benchmark took ${end - start} nanoseconds`);
  // Benchmark took 1154389282 nanoseconds
}, 1000);

Typescript error with createMidleware function

Hi everybody!

I started to work with the new typescript integration (I'm using Express), and I got an error with the createMidleware function
image
theapp variable is defined as Express.Application,

TS Error:
Type 'Application' is missing the following properties from type 'TApp': setTimeout, maxHeadersCount, timeout, headersTimeout, and 9 more.ts(2740)

Should I change the typing of the application?

thanks you!

Add native support for GraphQL servers

Is your feature request related to a problem? Please describe.
any thoughts on supporting a graphql framework running on express or other servers?

Describe the solution you'd like
bring in the best prometheus implementations for graphql setups to present data in a comparable way or build out similar implementations

Clarification Needed (normalizePaths)

In path normalizer in @promster/metrics, url-value-parser is being used to prevent duplicate paths. /path/1 and /path/2 both map to /path/#val. However, url-value-parser has some issues. It doesn't detect every pattern, only certain (UUID, decimal, etc). So, if somebody hits the server with randomized urls (undetected by url-value-parser), it should go out of memory. In fact, the /metrics call can become so big it can timeout. How do I handle this?

urlValueParser.replacePathValues(url.parse(path).pathname);

Can't create middleware twice

Describe the bug
Calling promster.createMiddleware() twice results in an error being thrown: A metric with the name up has already been registered.

To Reproduce

  1. Create a simple test.js file:
const promster = require('@promster/express');
promster.createMiddleware({});
promster.createMiddleware({});
  1. Run it: node test.js

The following error occurs:

/path/to/node_modules/prom-client/lib/registry.js:85
			throw new Error(
			^

Error: A metric with the name up has already been registered.
    at Registry.registerMetric (/Users/jburn9/projects/eap/dam-common/node_modules/prom-client/lib/registry.js:85:10)
    at Gauge.config.registers.forEach.registryInstance (/Users/jburn9/projects/eap/dam-common/node_modules/prom-client/lib/gauge.js:76:21)
    at Array.forEach (<anonymous>)
    at new Gauge (/Users/jburn9/projects/eap/dam-common/node_modules/prom-client/lib/gauge.js:75:20)
    at getDefaultMetrics (/Users/jburn9/projects/eap/dam-common/node_modules/@promster/metrics/modules/create-metric-types/create-metric-types.js:80:7)
    at createMetricTypes (/Users/jburn9/projects/eap/dam-common/node_modules/@promster/metrics/modules/create-metric-types/create-metric-types.js:156:26)
    at Object.createMiddleware (/Users/jburn9/projects/eap/dam-common/node_modules/@promster/express/modules/middleware/middleware.js:30:23)
    at Object.<anonymous> (/Users/jburn9/projects/eap/dam-common/test.js:4:10)
    at Module._compile (internal/modules/cjs/loader.js:721:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:732:10)

Additional context
This isn't particularly a problem at runtime because I only instantiate one of these middleware per service. But it's an issue in unit testing. I want to call a function which instantiates this middleware multiple times to test with different parameters, but I can't because this call blows up.

Socket level events are not detected

Describe the bug
We've noticed that our log entries describe cases where we receive a 400 response (Or 404 as the default in Koa) but they are not logged in the metrics.
This seems to happen when there are errors in the form of ECONNRESET - when the underlying socket of the request throws some error.

To Reproduce
Using express, we can imitate this behavior using the following code

const express = require('express')
const app = express();
const { createMiddleware, getSummary, getContentType } = require('@promster/express');

const port = 3000;

app.use('/metrics', async (req, res) => {
  req.statusCode = 200;

  res.setHeader('Content-Type', getContentType());
  res.end(await getSummary());
});

app.use(createMiddleware({ app }));

app.get('/', (req, res) => {
  res.send('Hello World!')
});

app.get('/error', (req, res) => {
  req.socket.emit('error', new Error('boom'));
});

app.listen(port);

Expected behavior
The /metrics route to record the request to the /error route.

Additional context
It seems that the response finished event does not trigger in such cases (code)
Using a module such as https://www.npmjs.com/package/on-finished does trigger the callback and record the request correctly

Default registry does not work with prom-client AggregatorRegistry

Describe the bug
Using prom-client AggregatorRegistry.setRegistries with promster defaultRegister throws an error.

TypeError: Expected Registry, got object
    at node_modules/prom-client/lib/cluster.js:140:11
    at Array.forEach (<anonymous>)
    at Function.setRegistries (node_modules/prom-client/lib/cluster.js:138:8)
    at Object.<anonymous> (test.js:4:20)
    at Module._compile (internal/modules/cjs/loader.js:774:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:785:10)
    at Module.load (internal/modules/cjs/loader.js:641:32)
    at Function.Module._load (internal/modules/cjs/loader.js:556:12)
    at Function.Module.runMain (internal/modules/cjs/loader.js:837:10)
    at internal/main/run_main_module.js:17:11

To Reproduce

  1. Install prom-client and @promster/express
npm install prom-client @promster/express
  1. Run
const { AggregatorRegistry } = require('prom-client');
const { defaultRegister } = require('@promster/express');

AggregatorRegistry.setRegistries(defaultRegister);

Expected behavior
defaultRegister can be used with AggregatorRegistry.

Minimist dependency fails package audit

Describe the bug
After installation of package, audit checks in our pipelines fail.
The culprit are several minimist dependencies from gc-stats

To Reproduce
Steps to reproduce the behavior:

  1. Install @promster/[email protected]
  2. Run npm audit --registry=https://registry.npmjs.org

Expected behavior
No error. found 0 vulnerabilities

Screenshots
Screenshot 2020-11-17 at 07 38 13

More information
Reproduced in MacOS.
❯ node --version
v14.8.0
❯ npm --version
6.14.7
Also reproduces in Azure pipelines agent, Ubuntu 18.04

Expose prom client registry

Is your feature request related to a problem? Please describe.

I wanna enrich my application with further custom metrics which are very business specific (e. g. consumed messages from a message queue). Therefore I am not in the right context to get the prom client registry instance to add my own metrics. Additionally I want to avoid "lazy metrics" which means I wanna initialize them with 0, so that Grafana shows the data is 0 and not "unknown".

Is there any chance we can get the registry or do I need to create a second prom-client registry to solve this?

Even easier: Make promster accept a prom-client registry :-).

Expose in-built _request-observer_

Is your feature request related to a problem? Please describe.
I'm trying to implement Prometheus according to my company's standard requirements, but this requires me to also provide details of outbound client network requests using the same metric as is used for in-bound server network requests -- using a role label of client instead of the server value used for in-bound requests.

Describe the solution you'd like
In just 3 hours I've been able to configure promster to meet the fairly exacting standards docs at my company except this one small detail πŸ™Œ. If the observeRequest request-observer was exposed on app.locals in the same way as prom-client is, then I'd now be fully compliant πŸ˜„.

Any chance you'd consider exposing this observer too? Thanks in advance, Dominic.

Describe alternatives you've considered
The only alternative I can think of is to fork as I don't think it's possible for me to grab this reference any other way.

Additional context
None.

Error in @promster/metrics doc?

After reading the section https://github.com/tdeekens/promster#promstermetrics of the readme.md I'm a little bit confused: The section is called @promster/metrics, but in the example snippet you do:

const { getSummary, getContentType } = require('@promster/express');

I've seen that @promster/express and @promster/hapi export these functions too. But why do I then have to use/install @promster/metrics at all?

Promster hapi plugin throws errors on requests

Describe the bug
The hapi plugin throws errors on every request with current version (2.2.6) and hapi 18.3

To Reproduce
please look at additional context.

Expected behavior
no errors are fine

Screenshots

Additional context

The handler onResponseHandler uses the reply argument, but the hapi api does not have this argument in the signature (Hapi-API). I think the return statement is not needed, but i'am not sure.

UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'continue' of undefined
at Object.onResponseHandler [as listener] (/app/node_modules/@promster/hapi/modules/plugin/plugin.js:75:67)
at module.exports.internals.Podium.internals.Podium.emit (/app/node_modules/podium/lib/index.js:228:107)
at Request._finalize (/app/node_modules/hapi/lib/request.js:447:27)
at Request._reply (/app/node_modules/hapi/lib/request.js:391:14)
at process._tickCallback (internal/process/next_tick.js:68:7)

Version after 4.1.2 added a dependency on tslib?

After upgrading from 4.1.2 -> 4.1.9 of @promster/express, my application encountered the following error:

internal/modules/cjs/loader.js:796
    throw err;
    ^
Error: Cannot find module 'tslib'
Require stack:
- /usr/src/app/node_modules/@promster/express/dist/modules/middleware/middleware.js
- /usr/src/app/node_modules/@promster/express/dist/modules/middleware/index.js
- /usr/src/app/node_modules/@promster/express/dist/modules/index.js
- SNIP
- SNIP
- /usr/src/app/src/app.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:793:17)
    at Function.Module._load (internal/modules/cjs/loader.js:686:27)
    at Module.require (internal/modules/cjs/loader.js:848:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/usr/src/app/node_modules/@promster/express/dist/modules/middleware/middleware.js:3:17)
    at Module._compile (internal/modules/cjs/loader.js:955:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
    at Module.load (internal/modules/cjs/loader.js:811:32)
    at Function.Module._load (internal/modules/cjs/loader.js:723:14)
    at Module.require (internal/modules/cjs/loader.js:848:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/usr/src/app/node_modules/@promster/express/dist/modules/middleware/index.js:3:22)
    at Module._compile (internal/modules/cjs/loader.js:955:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
    at Module.load (internal/modules/cjs/loader.js:811:32)
    at Function.Module._load (internal/modules/cjs/loader.js:723:14) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/usr/src/app/node_modules/@promster/express/dist/modules/middleware/middleware.js',
    '/usr/src/app/node_modules/@promster/express/dist/modules/middleware/index.js',
    '/usr/src/app/node_modules/@promster/express/dist/modules/index.js',
    SNIP,
    SNIP,
    SNIP
  ]

tslib is not listed as a dependency in https://github.com/tdeekens/promster/blob/master/packages/express/package.json, but in the compiled code under node_modules/@promster/express/dist/modules/middleware/middleware.js, there is

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const http_1 = require("http");

I can work around this by requiring tslib in my own application, but shouldn't @promster/express require its own dependencies?

`@promster/hapi` in version `6.1.0` causes an unhandled promise rejection

Describe the bug

@promster/hapi in version 6.1.0 causes an unhandled promise rejection when using raw response object to build response in hapi:

TypeError: Cannot read properties of undefined (reading 'content-length')
    at Object.onResponseHandler [as listener] (/home/stefan/tmp/promster-issue/node_modules/@promster/hapi/dist/promster-hapi.cjs.dev.js:162:33)
    at module.exports.internals.Podium.emit (/home/stefan/tmp/promster-issue/node_modules/@hapi/podium/lib/index.js:221:110)
    at Request._finalize (/home/stefan/tmp/promster-issue/node_modules/@hapi/hapi/lib/request.js:514:27)
    at Request._abort (/home/stefan/tmp/promster-issue/node_modules/@hapi/hapi/lib/request.js:492:14)
    at Request._reply (/home/stefan/tmp/promster-issue/node_modules/@hapi/hapi/lib/request.js:446:18)
    at Request._execute (/home/stefan/tmp/promster-issue/node_modules/@hapi/hapi/lib/request.js:282:14)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

This can be a problem for integration with other libraries (e.g. NextJS or Apollo) as those might use the raw response to write their responses.

To Reproduce
Steps to reproduce the behavior: Run the minimal example code from below.

  1. Given I request /does-not-work
  2. Then an unhandled rejection is thrown
  3. That might crash the application (depending how unhandled promise rejections are handled)

Expected behavior
Promster does not include the response in the response size metric, or reads the header from the raw response.

Additional context

Minimal example:

const { createPlugin } = require('@promster/hapi');
const Hapi = require('@hapi/hapi');

process.on('unhandledRejection', (err) => {
    console.log(err);
    process.exit(1);
});

(async () => {
    const server = Hapi.server({
        port: 3000,
        host: 'localhost'
    });
    
    await server.register(createPlugin());

    // Default way to render route response works fine
    server.route({
        method: 'GET',
        path: '/works',
        handler: (request, h) => {
            return 'Hello World!';
        }
    });

    // Using raw reponse causes unhandled promise rejection
    server.route({
        method: 'GET',
        path: '/does-not-work',
        handler: (request, h) => {
            request.raw.res.statusCode = 200;
            request.raw.res.write("Hello World!");
            return h.close;
        }
    });
    
    await server.start();
})();

metricPrefix is not applied on the http_requests_total metric

Describe the bug
It seems that metricPrefix option is not applied consistently on all collected metrics. Specifically, the prefix is not applied on the http_requests_total metric.

To Reproduce
Steps to reproduce the behavior:

  1. Given 'You have created middleware with metricPrefix set to my_nice_prefix_'
  2. Then 'Start the app and make a GET request to the /metrics endpoint'

Expected behavior
I would expect all metrics to be prefixed with the provided prefix i.e. my_nice_prefix_. This happens for all metrics apart from the http_requests_total metric. See annotated screenshot below:

Screenshots
Screenshot 2019-11-04 at 17 22 50
Additional context
I am using @promster/express

[QUESTION] Misunderstanding about accuracies

According to Prometheus Best Practices, unit for time is "seconds".

To mesure duration under the second, we need to use float with suffisant level of precision.

The choice to implement different units, each one of them, mapped to a specific level of precision make impossible to follow Prometheus Best Practices.

What do you think about de-couple precision and unit ?

Fractional second values are truncated

Describe the bug
After #791, fractional values are truncated (i.e. http_request_duration_seconds does not record fractional seconds).

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt

The / operator also works as expected with whole numbers β€” but operations with a fractional result will be truncated when used with a BigInt value β€” they won’t return any fractional digits.

To Reproduce
Steps to reproduce the behavior:

  1. clone repo
  2. run demo
  3. make some requests
  4. check metrics endpoint

Expected behavior
http_request_duration_seconds_sum should show fractional seconds.

Promster hapi plugin not working with hapi V-13

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Given '...'
  2. Then '....'
  3. That '....'

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.
image

Additional context
Add any other context about the problem here.
image

@promster/hapi has warning about unmet peer dependency

Describe the bug
When using @promster/hapi, which depends on @promster/metrics the following warning is outputted via yarn.

warning "@promster/hapi > @promster/metrics > [email protected]" has unmet peer dependency "typescript@>=4.1.0".

To Reproduce
Steps to reproduce the behavior:

  1. Given I have a package.json depending on @promster/hapi, e.g.:
{
  "name": "example",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "@promster/hapi": "^6.1.3"
  }
}
  1. Then I run yarn
  2. That gives the following warnings:
yarn add v1.22.17
info No lockfile found.
[1/4] πŸ”  Resolving packages...
warning @promster/hapi > @promster/metrics > url > [email protected]: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
[2/4] 🚚  Fetching packages...
[3/4] πŸ”—  Linking dependencies...
warning "@promster/hapi > @promster/[email protected]" has unmet peer dependency "[email protected] || 14.x".
warning "@promster/hapi > @promster/metrics > [email protected]" has unmet peer dependency "typescript@>=4.1.0".

Expected behavior
Peer dependencies would be met by @promster/hapi or redeclared as a needed peer dependency of the package, so it's obvious that consumers of the package need to add the dependency themselves.

TPromsterOptions incorrect property

Describe the bug
I did not deep-dive here but it looks like the property "buckets" on TPromsterOptions in the typings package might have the incorrect type. Should it not be number[] or Array<number> as opposed to [number]?

https://github.com/tdeekens/promster/blob/main/packages/types/src/index.ts#L20

https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgILIN4Chm+XALmQG0QBXAWwCNoBdHPKo866Y+vZBI1KKOAJ4AeFjSgA+LAF8sWBAHsQAZzD4eyALyYGuQiQCMAGgBMhgMy1DO5EwMnzl69zumL0oA

To Reproduce
Steps to reproduce the behavior:

  1. Given '...'
  2. Then '....'
  3. That '....'

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Additional context
Add any other context about the problem here.

10 High Severity vulnerabilities reported from node-gcstats dependency

Describe the bug
This library currently causes 10 high severity vulnerabilities to be reported by npm audit due to the node-gcstats dependency which it includes.

PR #703 recently attempted to address this by moving to a more up-to-date fork, @sematext/node-gcstats. Unfortunately, this fork is also somewhat behind. It still includes the deprecated node-pre-gyp package.

For what it's worth, I've submitted a PR to that fork to update it but we'll see if it gets a response: adnanrahic/node-gcstats#4

To Reproduce
Here's what npm audit shows currently:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ High          β”‚ Arbitrary File Creation/Overwrite due to insufficient        β”‚
β”‚               β”‚ absolute path sanitization                                   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Package       β”‚ tar                                                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Patched in    β”‚ >=3.2.2 <4.0.0 || >=4.4.14  <5.0.0 || >=5.0.6 <6.0.0 ||      β”‚
β”‚               β”‚ >=6.1.1                                                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Dependency of β”‚ @promster/express                                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Path          β”‚ @promster/express > @promster/metrics > @sematext/gc-stats > β”‚
β”‚               β”‚ node-pre-gyp > tar                                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ More info     β”‚ https://npmjs.com/advisories/1770                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ High          β”‚ Arbitrary File Creation/Overwrite due to insufficient        β”‚
β”‚               β”‚ absolute path sanitization                                   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Package       β”‚ tar                                                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Patched in    β”‚ >=3.2.2 <4.0.0 || >=4.4.14  <5.0.0 || >=5.0.6 <6.0.0 ||      β”‚
β”‚               β”‚ >=6.1.1                                                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Dependency of β”‚ @promster/server                                             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Path          β”‚ @promster/server > @promster/metrics > @sematext/gc-stats >  β”‚
β”‚               β”‚ node-pre-gyp > tar                                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ More info     β”‚ https://npmjs.com/advisories/1770                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ High          β”‚ Arbitrary File Creation/Overwrite via insufficient symlink   β”‚
β”‚               β”‚ protection due to directory cache poisoning                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Package       β”‚ tar                                                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Patched in    β”‚ >=3.2.3 <4.0.0 || >=4.4.15  <5.0.0 || >=5.0.7 <6.0.0 ||      β”‚
β”‚               β”‚ >=6.1.2                                                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Dependency of β”‚ @promster/express                                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Path          β”‚ @promster/express > @promster/metrics > @sematext/gc-stats > β”‚
β”‚               β”‚ node-pre-gyp > tar                                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ More info     β”‚ https://npmjs.com/advisories/1771                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ High          β”‚ Arbitrary File Creation/Overwrite via insufficient symlink   β”‚
β”‚               β”‚ protection due to directory cache poisoning                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Package       β”‚ tar                                                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Patched in    β”‚ >=3.2.3 <4.0.0 || >=4.4.15  <5.0.0 || >=5.0.7 <6.0.0 ||      β”‚
β”‚               β”‚ >=6.1.2                                                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Dependency of β”‚ @promster/server                                             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Path          β”‚ @promster/server > @promster/metrics > @sematext/gc-stats >  β”‚
β”‚               β”‚ node-pre-gyp > tar                                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ More info     β”‚ https://npmjs.com/advisories/1771                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ High          β”‚ Arbitrary File Creation/Overwrite via insufficient symlink   β”‚
β”‚               β”‚ protection due to directory cache poisoning using symbolic   β”‚
β”‚               β”‚ links                                                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Package       β”‚ tar                                                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Patched in    β”‚ >=4.4.16 <5.0.0 || >=5.0.8 <6.0.0 || >=6.1.7                 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Dependency of β”‚ @promster/express                                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Path          β”‚ @promster/express > @promster/metrics > @sematext/gc-stats > β”‚
β”‚               β”‚ node-pre-gyp > tar                                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ More info     β”‚ https://npmjs.com/advisories/1779                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ High          β”‚ Arbitrary File Creation/Overwrite via insufficient symlink   β”‚
β”‚               β”‚ protection due to directory cache poisoning using symbolic   β”‚
β”‚               β”‚ links                                                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Package       β”‚ tar                                                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Patched in    β”‚ >=4.4.16 <5.0.0 || >=5.0.8 <6.0.0 || >=6.1.7                 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Dependency of β”‚ @promster/server                                             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Path          β”‚ @promster/server > @promster/metrics > @sematext/gc-stats >  β”‚
β”‚               β”‚ node-pre-gyp > tar                                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ More info     β”‚ https://npmjs.com/advisories/1779                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ High          β”‚ Arbitrary File Creation/Overwrite via insufficient symlink   β”‚
β”‚               β”‚ protection due to directory cache poisoning using symbolic   β”‚
β”‚               β”‚ links                                                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Package       β”‚ tar                                                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Patched in    β”‚ >=4.4.18 <5.0.0 || >=5.0.10 <6.0.0 || >=6.1.9                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Dependency of β”‚ @promster/express                                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Path          β”‚ @promster/express > @promster/metrics > @sematext/gc-stats > β”‚
β”‚               β”‚ node-pre-gyp > tar                                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ More info     β”‚ https://npmjs.com/advisories/1780                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ High          β”‚ Arbitrary File Creation/Overwrite via insufficient symlink   β”‚
β”‚               β”‚ protection due to directory cache poisoning using symbolic   β”‚
β”‚               β”‚ links                                                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Package       β”‚ tar                                                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Patched in    β”‚ >=4.4.18 <5.0.0 || >=5.0.10 <6.0.0 || >=6.1.9                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Dependency of β”‚ @promster/server                                             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Path          β”‚ @promster/server > @promster/metrics > @sematext/gc-stats >  β”‚
β”‚               β”‚ node-pre-gyp > tar                                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ More info     β”‚ https://npmjs.com/advisories/1780                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ High          β”‚ Arbitrary File Creation/Overwrite on Windows via             β”‚
β”‚               β”‚ insufficient relative path sanitization                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Package       β”‚ tar                                                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Patched in    β”‚ >=4.4.18 <5.0.0 || >=5.0.10 <6.0.0 || >=6.1.9                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Dependency of β”‚ @promster/express                                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Path          β”‚ @promster/express > @promster/metrics > @sematext/gc-stats > β”‚
β”‚               β”‚ node-pre-gyp > tar                                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ More info     β”‚ https://npmjs.com/advisories/1781                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ High          β”‚ Arbitrary File Creation/Overwrite on Windows via             β”‚
β”‚               β”‚ insufficient relative path sanitization                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Package       β”‚ tar                                                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Patched in    β”‚ >=4.4.18 <5.0.0 || >=5.0.10 <6.0.0 || >=6.1.9                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Dependency of β”‚ @promster/server                                             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Path          β”‚ @promster/server > @promster/metrics > @sematext/gc-stats >  β”‚
β”‚               β”‚ node-pre-gyp > tar                                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ More info     β”‚ https://npmjs.com/advisories/1781                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Additional context

While we wait for the node-gcstats problem child to be updated, is there anything that can be done to reduce the number of audit problems that Promster is inheriting from this unmaintained dependency? Even the person who forked it says they aren't really maintaining the code. They just bumped dependencies. So it seems likely that this will continue to be a problem.

Exploring options:

  • Can this dependency (and the corresponding functionality) be removed from Promster?
  • Can this dependency be refactored into a peer-dependency that people who want it can choose to install? (e.g. @promster/gcstats)
  • Is there any way for teams using package.json and package-lock.json files to express in those manifests that the optional node-gcstats dependency should be omitted? I'm only aware of global flags on npm install and npm ci to globally omit all optional dependencies in all packages. A workable solution for clients would get the manifests into a shape that npm ci can be used as normal without any global flags being applied.

Up gauge

The up metric is created, but it is never set nor exposed to be set?

Am i missing something?

Implement http_server_requests_total metric

While the current metrics can be used for almost any use case, it would be nice to provide this metric to be more consistent with other prometheus exporters.

Prometheus official docs also use this metric as an example:

https://prometheus.io/docs/prometheus/latest/querying/examples/
https://github.com/prometheus/docs/blob/master/content/docs/practices/naming.md#metric-names

While the official docs use http_requests_total, a lot of libraries are using http_server_requests_total as an alternative because it's more declarative. Either way, this can be solved with relabeling configs.

Some insights about this can be found on https://www.robustperception.io/on-the-naming-of-things

A lot of projects leverage on Grafana Dashboards which display graphs and values based on this metric. For example, we have a dashboard which provides metrics for all of our services. Having to add a second query only to provide compatibility with our NodeJS services seems very odd.

As satated by @tdeekens in #12, the requests/s example provided in the prometheus docs can be achieved by doing

sum(rate(http_request_duration_buckets_milliseconds_count[1m])) * 60)

Do you think it would be relevant to add this metric? We can provide an option to disable it as well.

Cheers!

MaxListenersExceededWarning during test runs

I'm trying to use promster in a large hapi server with a lot of tests. The tests keep making and destroying lots of hapi server instances. For some subset of it, the promster plugin gets loaded. After a few tests, we get

(node:55880) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 stats listeners added to [EventEmitter]. Use emitter.setMaxListeners() to increase limit
    at _addListener (events.js:281:17)
    at EventEmitter.addListener (events.js:297:10)
    at /redacted/node_modules/@promster/metrics/modules/create-gc-observer/create-gc-observer.js:20:8

My guess is that this is because of

It adds an event listener, but nothing ever cleans that up again.

This is probably only a problem during testing because normally in production code you're only going to make one hapi server and register promster once.

average response time last minute

like micrometer with spring boot,
It will be a great feature to get how long the longest request took in the last minute

ex:
http_server_requests_seconds_max{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/blah",} 0.040648985
http_server_requests_seconds_max{exception="ResourceNotFoundException",method="GET",outcome="CLIENT_ERROR",status="404",uri="/blahblah",} 0.0

5 low vulnerabilities caused by optional dependency gc-stats

Describe the bug
get below vulnerabilities reports, caused by gc-stats, and I find that gc-stats is optional dependency.

https://github.com/tdeekens/promster/blob/main/packages/metrics/package.json#L53-L55


β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                Manual Review                                 β”‚
β”‚            Some vulnerabilities require your attention to resolve            β”‚
β”‚                                                                              β”‚
β”‚         Visit https://go.npm.me/audit-guide for additional guidance          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Low           β”‚ Regular Expression Denial of Service                         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Package       β”‚ braces                                                       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Patched in    β”‚ >=2.3.1                                                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Dependency of β”‚ cpx [dev]                                                    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Path          β”‚ cpx > chokidar > anymatch > micromatch > braces              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ More info     β”‚ https://npmjs.com/advisories/786                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Low           β”‚ Prototype Pollution                                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Package       β”‚ minimist                                                     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Patched in    β”‚ >=0.2.1 <1.0.0 || >=1.2.3                                    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Dependency of β”‚ @promster/express                                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Path          β”‚ @promster/express > @promster/metrics > gc-stats >           β”‚
β”‚               β”‚ node-pre-gyp > mkdirp > minimist                             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ More info     β”‚ https://npmjs.com/advisories/1179                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Low           β”‚ Prototype Pollution                                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Package       β”‚ minimist                                                     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Patched in    β”‚ >=0.2.1 <1.0.0 || >=1.2.3                                    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Dependency of β”‚ @promster/express                                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Path          β”‚ @promster/express > @promster/metrics > gc-stats >           β”‚
β”‚               β”‚ node-pre-gyp > tar > mkdirp > minimist                       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ More info     β”‚ https://npmjs.com/advisories/1179                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Low           β”‚ Prototype Pollution                                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Package       β”‚ minimist                                                     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Patched in    β”‚ >=0.2.1 <1.0.0 || >=1.2.3                                    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Dependency of β”‚ @promster/express                                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Path          β”‚ @promster/express > @promster/metrics > gc-stats >           β”‚
β”‚               β”‚ node-pre-gyp > rc > minimist                                 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ More info     β”‚ https://npmjs.com/advisories/1179                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Low           β”‚ Prototype Pollution                                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Package       β”‚ ini                                                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Patched in    β”‚ >1.3.6                                                       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Dependency of β”‚ @promster/express                                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Path          β”‚ @promster/express > @promster/metrics > gc-stats >           β”‚
β”‚               β”‚ node-pre-gyp > rc > ini                                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ More info     β”‚ https://npmjs.com/advisories/1589                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜


To Reproduce
Steps to reproduce the behavior:
npm audit --registry=https://registry.npmjs.org

Expected behavior
Is it possible to remove gc-stats?

Screenshots
image

Additional context
Add any other context about the problem here.

Build error without `allowSyntheticDefaultImports: true`

Describe the bug
This lib causes typescript project builds to fail unless enabling the allowSyntheticDefaultImports flag.

The build error:

node_modules/@promster/server/dist/modules/server/server.d.ts:1:8 - error TS1192: Module '"http"' has no default export.

1 import http from 'http';

To Reproduce

  1. Create a typescript project with a tsconfig.json file that does not have either of these options enabled:
{
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true
}
  1. Import the promster/server lib:
import { createServer } from '@promster/server';
  1. Run typescript build. See error.

Expected behavior
Properly typed libraries should not require the allowSyntheticDefaultImports or esModuleInterop flags to be enabled.

Screenshots
image

Add Typescript definitions

While trying to integrate promster with our service written in TypeScript I noticed that there don't seem to be typings for @promster/express. So needless to say, I'd love to see Typescript support for this.

Use NodeJS url module instead of deprecated transitive dependency

Describe the bug
I get the following warning when using promster:

npm WARN deprecated [email protected]: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.

This is due to promster/metrics using the (external) url package. NodeJS provides the same functionality which was deprecated for some time, but that has been revoked.

To Reproduce
Steps to reproduce the behavior:

  1. Add promster to a project, for example "@promster/express"
  2. Run npm. install
  3. See the printed warning
npm WARN deprecated [email protected]: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.

Expected behavior
No deprecation warnings when using promster.

Additional context

  • I tried to create a pull request and remove the dependency, but cannot get commitizen / the pre-commit hook to work
  • The tests still run when just removing the dependency from metrics/package.json
  • I used Node 16 (LTS)

TYPE up gauge always returns 0

Describe the bug
A clear and concise description of what the bug is.
Does TYPE up gauge always return 0 whether server is started or not?

To Reproduce
Steps to reproduce the behavior:

  1. clone the repo
  2. cd to demo
  3. npm install : express、@promster/express、@promster/server
  4. node ./express.js

Expected behavior
A clear and concise description of what you expected to happen.

❯ node ./express.js
Prometheus metrics available on http://localhost:8080
Express app listening at http://localhost:80

http://localhost/ ----> I am the server!
http://localhost:8080/ -----> as Screenshots, TYPE up gauge returns 0

Screenshots
If applicable, add screenshots to help explain your problem.
image

Additional context
Add any other context about the problem here.

feature-request: Measure metrics from Electron

Is your feature request related to a problem? Please describe.
β€” Empty
Describe the solution you'd like
β€” Empty

Describe alternatives you've considered
β€” Empty

Additional context
Could add package to measure metrics from Electron

Express middleware skipping by request generates a TS error

Describe the bug
skip in TMiddlewareOptions requires 2 generic Q and S that can't be extended with Request and Response from express.

I might be using it wrong, a helpful usage example would be greatly appreciated πŸ™

To Reproduce
Steps to reproduce the behavior:

  1. Given
import type { Request } from 'express';
import { createMiddleware as createPrometheusMiddleware } from '@promster/express';

app.use(
  createPrometheusMiddleware({
    app,
    options: {
      skip: <Q extends Request>(req: Q) =>
        req.url.includes('products') || req.url.includes('carts'),
    },
  })
);
  1. Then I receive a TS error
Types of parameters 'req' and 'request' are incompatible.
    Type 'Q' is not assignable to type 'Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>'


This type parameter might need an `extends e.Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>` constraint.

Expected behavior
I expect the skip method to work without TS error or even better to have a different signature for example like this without the use of generics

app.use(
  createPrometheusMiddleware({
    app,
    options: {
      skip: (req: Request) =>
        req.url.includes('products') || req.url.includes('carts'),
    },
  })
);

Additional context
Versions installed

    "prom-client": "^14.2.0",
    "@promster/express": "^7.0.6",
    "@promster/server": "^7.0.8",
    "@promster/types": "^3.2.5",

One an unrelated note, it would be really nice if the express middleware exports the types as well so we don't have to install @promster/types to get typing for TMiddlewareOptions πŸ˜…

Content length histograms for requests and responses

Is your feature request related to a problem? Please describe.

  • Currently, we do not have a default way to track request and response body sizes of HTTP requests.

Describe the solution you'd like

  • Metrics for histograms of the content-length header for requests and responses.

Describe alternatives you've considered

  • Custom metrics by using prom-client or equivalent directly

Additional context

We want this feature as part of our monitoring system. While we've implemented this manually, that would be great if promster supports this out of the box. Are there any needs by others?

BTW, thank you for this great tool!

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Awaiting Schedule

These updates are awaiting their schedule. Click on a checkbox to get an update now.

  • chore(deps): update dependency @types/node to v20.12.8
  • fix(deps): update babel monorepo to v7.24.5 (@babel/core, @babel/eslint-parser, @babel/preset-env)
  • chore(deps): update dependency @graphql-tools/utils to v10.2.0
  • fix(deps): update typescript-eslint monorepo to v7.8.0 (@typescript-eslint/eslint-plugin, @typescript-eslint/parser)
  • fix(deps): update dependency ts-essentials to v10
  • chore(deps): lock file maintenance

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Ignored or Blocked

These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.

Detected dependencies

github-actions
.github/workflows/release.yml
  • actions/checkout v4
  • pnpm/action-setup v3.0.0
  • actions/setup-node v4
  • dotansimha/changesets-action v1.5.2
.github/workflows/test.yml
  • actions/checkout v4
  • pnpm/action-setup v3.0.0
  • actions/setup-node v4
npm
package.json
  • @babel/core 7.24.4
  • @babel/eslint-parser 7.24.1
  • @babel/preset-env 7.24.4
  • @babel/preset-typescript 7.24.1
  • @changesets/changelog-github 0.5.0
  • @changesets/cli 2.27.1
  • @commitlint/cli 19.3.0
  • @commitlint/config-conventional 19.2.2
  • @manypkg/cli 0.21.4
  • @preconstruct/cli 2.8.3
  • @tsconfig/node18 18.2.4
  • @types/node 20.12.7
  • @types/semver 7.5.8
  • @typescript-eslint/eslint-plugin 7.7.1
  • @typescript-eslint/parser 7.7.1
  • check-node-version 4.2.1
  • codecov 3.8.3
  • cross-env 7.0.3
  • eslint 8.57.0
  • eslint-config-prettier 9.1.0
  • eslint-config-xo 0.44.0
  • eslint-config-xo-typescript 4.0.0
  • eslint-formatter-pretty 5.0.0
  • eslint-plugin-jest 28.3.0
  • eslint-plugin-prettier 5.1.3
  • husky 9.0.11
  • jest 29.7.0
  • jest-runner-eslint 2.2.0
  • jest-watch-typeahead 2.2.2
  • lint-staged 15.2.2
  • prettier 3.2.5
  • rimraf 5.0.5
  • ts-jest 29.1.2
  • typescript 5.4.5
  • node >=20
  • npm >=8
  • pnpm >=8
  • pnpm 9.0.6
packages/apollo/package.json
  • @apollo/server 4.10.4
  • merge-options 3.0.4
  • tslib 2.6.2
  • @graphql-tools/schema 10.0.3
  • @graphql-tools/utils 10.1.3
  • apollo-server 3.13.0
  • graphql 16.8.1
  • parse-prometheus-text-format 1.1.1
  • node >=20
  • npm >=8
packages/express/package.json
  • merge-options 3.0.4
  • tslib 2.6.2
  • @types/express 4.17.21
  • express 4.19.2
  • parse-prometheus-text-format 1.1.1
  • node >=20
  • npm >=8
packages/fastify/package.json
  • fastify-plugin ^4.5.1
  • merge-options 3.0.4
  • parse-prometheus-text-format 1.1.1
  • fastify 4.26.2
  • node >=20
  • npm >=8
packages/hapi/package.json
  • merge-options 3.0.4
  • semver 7.6.0
  • tslib 2.6.2
  • @hapi/boom 10.0.1
  • @hapi/hapi 21.3.9
  • @types/hapi__hapi 21.0.0
  • @types/semver 7.5.8
  • parse-prometheus-text-format 1.1.1
  • node >=20
  • npm >=8
packages/marblejs/package.json
  • merge-options 3.0.4
  • rxjs ^7.8.1
  • tslib 2.6.2
  • @marblejs/core 4.1.0
  • @marblejs/http 4.1.0
  • fp-ts 2.16.5
  • parse-prometheus-text-format 1.1.1
  • node >=20
  • npm >=8
packages/metrics/package.json
  • lodash.memoize 4.1.2
  • lodash.once 4.1.1
  • merge-options 3.0.4
  • prometheus-gc-stats 1.1.0
  • tslib 2.6.2
  • url-value-parser 2.2.0
  • @types/lodash.once 4.1.9
  • @types/node 20.12.7
  • prom-client 15.1.2
  • typescript 5.4.5
  • prom-client 13.x.x || 14.x || 15.x
  • node >=20
  • npm >=8
packages/server/package.json
  • tslib 2.6.2
  • @types/node 20.12.7
  • node >=20
  • npm >=8
packages/types/package.json
  • ts-essentials 9.4.2
  • prom-client 15.1.2
  • prom-client 13.x.x || 14.x || 15.x
  • node >=20
  • npm >=8
nvm
.nvmrc
  • node 21

  • Check this box to trigger a request for Renovate to run again on this repository

TPromsterOptions not allowing for default options

Describe the bug
I'm trying to create a middleware for an express app, using @promster/express' createMiddleware function. Before the package moved to TS, the following worked

createMiddleware({ options: { metricTypes: ['countOfGcs', 'durationOfGc', 'reclaimedInGc'] } });

and gave me the metrics I wanted. Now, however, after the move, I get an error from TS stating that buckets and percentiles are missing.

To Reproduce
Steps to reproduce the behavior:

Using TS 3.9, the following shows the error

import { createMiddleware } from '@promster/express';

createMiddleware({ options: { metricTypes: ['countOfGcs', 'durationOfGc', 'reclaimedInGc'] } });

Expected behavior
No TypeScript errors should occur

Additional context
Any place I found in the source code that uses either of these values has a fallback default value, so shouldn't these two be optional?

Right now, TPromsterOptions is defined with

    buckets: [number];
    percentiles: [number];
}

From what I saw, these can be optional in the interface. I can open a PR with this small change, if that would be deemed appropriate, and would help

Metrics per endpoint(group)

Is your feature request related to a problem? Please describe.

I'd like to expose metrics (e. g. request duration by status code, by method, by path) for a specific endpoint or endpoint group. Of course this requires the package to know what dynamic parts of the URL exist. One could solve this by passing a list of to be monitored URLs including wildcards. See how express-prom-bundle handles this:

https://github.com/jochen-schweizer/express-prom-bundle#more-details-on-includepath-option

Describe the solution you'd like

One solution could be this:
https://github.com/jochen-schweizer/express-prom-bundle#more-details-on-includepath-option

Describe alternatives you've considered

Getting endpoints from swagger definitions - I dislike the idea though because not everyone has or wanna use swagger. Personally I am using NestJS for swagger docs so I don't even have a swagger definition file.

@hapi/[email protected] breaking change in patch release when converting to TypeScript

A patch version increase in @promster/hapi from 4.1.3 to 4.1.10 changed the signature of the hapi's decoration, making the static Promster property instead a function that returns the Promster instance. This seems to have been done in the PR that converted the package to TypeScript.

I added a comment to the PR on the affected line: #352 (review)

packages/hapi/modules/plugin/plugin.ts 
--- server.decorate('server', 'Prometheus', Prometheus);
+++ server.decorate('server', 'Prometheus', () => Prometheus);

Since our software specificed @promster/hapi version ^4.0.0, updating to this broke our application, since previously accessing server.Promster didn't require an additional invocation:

const { Prometheus } = server // the hapi server instance
const reportingService = new ReportingService(Prometheus)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.