npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@hono/prometheus

v1.0.1

Published

Prometheus metrics middleware for Hono

Downloads

25,264

Readme

Prometheus middleware for Hono

This middleware adds basic RED metrics to your Hono application, and exposes them on the /metrics endpoint for Prometheus to scrape.

Installation

This package depends on prom-client, so you need to install that as well:

npm install -S @hono/prometheus prom-client
# or
yarn add @hono/prometheus prom-client

Usage

import { prometheus } from '@hono/prometheus'
import { Hono } from 'hono'

const app = new Hono()

const { printMetrics, registerMetrics } = prometheus()

app.use('*', registerMetrics)
app.get('/metrics', printMetrics)
app.get('/', (c) => c.text('foo'))

export default app

Making a GET request to /metrics returns the string representation of the metrics:

# HELP http_request_duration_seconds Duration of HTTP requests in seconds
# TYPE http_request_duration_seconds histogram
http_request_duration_seconds_bucket{le="0.005",method="GET",route="/",status="200",ok="true"} 2
http_request_duration_seconds_bucket{le="0.01",method="GET",route="/",status="200",ok="true"} 2
http_request_duration_seconds_bucket{le="0.025",method="GET",route="/",status="200",ok="true"} 2
http_request_duration_seconds_bucket{le="0.05",method="GET",route="/",status="200",ok="true"} 2
http_request_duration_seconds_bucket{le="0.075",method="GET",route="/",status="200",ok="true"} 2
http_request_duration_seconds_bucket{le="0.1",method="GET",route="/",status="200",ok="true"} 2
http_request_duration_seconds_bucket{le="0.25",method="GET",route="/",status="200",ok="true"} 2
http_request_duration_seconds_bucket{le="0.5",method="GET",route="/",status="200",ok="true"} 2
http_request_duration_seconds_bucket{le="0.75",method="GET",route="/",status="200",ok="true"} 2
http_request_duration_seconds_bucket{le="1",method="GET",route="/",status="200",ok="true"} 2
http_request_duration_seconds_bucket{le="2.5",method="GET",route="/",status="200",ok="true"} 2
http_request_duration_seconds_bucket{le="5",method="GET",route="/",status="200",ok="true"} 2
http_request_duration_seconds_bucket{le="7.5",method="GET",route="/",status="200",ok="true"} 2
http_request_duration_seconds_bucket{le="10",method="GET",route="/",status="200",ok="true"} 2
http_request_duration_seconds_bucket{le="+Inf",method="GET",route="/",status="200",ok="true"} 2
http_request_duration_seconds_sum{method="GET",route="/",status="200",ok="true"} 0.000251125
http_request_duration_seconds_count{method="GET",route="/",status="200",ok="true"} 2
http_request_duration_seconds_bucket{le="0.005",method="GET",route="/user/:id",status="200",ok="true"} 3
http_request_duration_seconds_bucket{le="0.01",method="GET",route="/user/:id",status="200",ok="true"} 3
http_request_duration_seconds_bucket{le="0.025",method="GET",route="/user/:id",status="200",ok="true"} 3
http_request_duration_seconds_bucket{le="0.05",method="GET",route="/user/:id",status="200",ok="true"} 3
http_request_duration_seconds_bucket{le="0.075",method="GET",route="/user/:id",status="200",ok="true"} 3
http_request_duration_seconds_bucket{le="0.1",method="GET",route="/user/:id",status="200",ok="true"} 3
http_request_duration_seconds_bucket{le="0.25",method="GET",route="/user/:id",status="200",ok="true"} 3
http_request_duration_seconds_bucket{le="0.5",method="GET",route="/user/:id",status="200",ok="true"} 3
http_request_duration_seconds_bucket{le="0.75",method="GET",route="/user/:id",status="200",ok="true"} 3
http_request_duration_seconds_bucket{le="1",method="GET",route="/user/:id",status="200",ok="true"} 3
http_request_duration_seconds_bucket{le="2.5",method="GET",route="/user/:id",status="200",ok="true"} 3
http_request_duration_seconds_bucket{le="5",method="GET",route="/user/:id",status="200",ok="true"} 3
http_request_duration_seconds_bucket{le="7.5",method="GET",route="/user/:id",status="200",ok="true"} 3
http_request_duration_seconds_bucket{le="10",method="GET",route="/user/:id",status="200",ok="true"} 3
http_request_duration_seconds_bucket{le="+Inf",method="GET",route="/user/:id",status="200",ok="true"} 3
http_request_duration_seconds_sum{method="GET",route="/user/:id",status="200",ok="true"} 0.000391333
http_request_duration_seconds_count{method="GET",route="/user/:id",status="200",ok="true"} 3

# HELP http_requests_total Total number of HTTP requests
# TYPE http_requests_total counter
http_requests_total{method="GET",route="/",status="200",ok="true"} 2
http_requests_total{method="GET",route="/user/:id",status="200",ok="true"} 3

Options

An options object can be passed in the prometheus() middleware factory to configure the metrics:

prefix

Type: string

Prefix all metrics with this string.

registry

Type: Registry

A prom-client Registry instance to store the metrics. If not provided, a new one will be created.

Useful when you want to register some custom metrics while exposing them on the same /metrics endpoint that this middleware creates. In this case, you can create a Registry instance, register your custom metrics on that, and pass that into this option.

collectDefaultMetrics

Type: boolean | CollectDefaultMetricsOptions

There are some default metrics recommended by prom-client, like event loop delay, garbage collection statistics etc.

To enable these metrics, set this option to true. To configure the default metrics, pass an object with the configuration options.

metricOptions

Type: object (see below)

Modify the standard metrics (requestDuration and requestsTotal) with any of the Counter / Histogram metric options, including:

disabled

Type: boolean

Disables the metric.

customLabels

Type: Record<string, (context) => string>

A record where the keys are the labels to add to the metrics, and the values are functions that receive the Hono context and return the value for that label. This is useful when adding labels to the metrics that are specific to your application or your needs. These functions are executed after all the other middlewares finished.

The following example adds a label to the requestsTotal metric with the contentType name where the value is the content type of the response:

app.use('*', prometheus({
  metricOptions: {
    requestsTotal: {
      customLabels: {
        content_type: (c) => c.res.headers.get('content-type'),
      }
    },
  }
}))

Examples

Adding custom metrics

If you want to expose custom metrics on the /metrics endpoint, you can create a Registry instance and pass it to the prometheus() factory function using the registry property:

import { prometheus } from '@hono/prometheus'
import { Hono } from 'hono'
import { Counter, Registry } from 'prom-client'

const registry = new Registry()
const customCounter = new Counter({
  name: 'custom_counter',
  help: 'A custom counter',
  registers: [registry],
})

const app = new Hono()

const { printMetrics, registerMetrics } = prometheus({
  registry,
})

app.use('*', registerMetrics)
app.get('/metrics', printMetrics)
app.get('/', (c) => c.text('foo'))

export default app

// Somewhere in your application you can increment the custom counter:
customCounter.inc()

Author

David Dios https://github.com/dios-david

License

MIT