Prometheus metrics best practices

Hi, what is the standard way to collect Prometheus metrics across different endpoints with different labels

  • using a giant MetricLabels class that contains all possible labels for every endpoint?
  • grouping endpoints with the same MetricLabels and then have a metric collector for each group ?

For instance say I have the following endpoints

  • POST customers/
  • GET customer/
  • PUT customer/address
  • PUT products/
  • etc …

What pattern should I use:


// default metric labels
lazy val Default: MetricLabels = MetricLabels(
    forRequest = List(
      "path" -> { case (ep, _) => ep.showPathTemplate(showQueryParam = None) },
      "method" -> { case (_, req) => req.method.method }
    ),
    forResponse = List(
      "status" -> {
        case Right(r) =>
          r.code match {
            case c if c.isInformational => "1xx"
            case c if c.isSuccess       => "2xx"
            case c if c.isRedirect      => "3xx"
            case c if c.isClientError   => "4xx"
            case c if c.isServerError   => "5xx"
            case _                      => ""
          }
        case Left(_) => "5xx"
      }
    )
  )


// separating customer & product labels to be registered with different metric collectors (i.e. different Counters)
val Customer = Default.copy(...) => // add logic to grab customer info
val Product = Default.copy(...) => // add logic to grab product info

//OR

// merging customer & product labels. Only a single metric collector will be registered (i.e. unique Counter)
// val CustomerAndProduct =  Default.copy(...) => // add logic to grab customer & product info

A Prometheus metric is created with a fixed set of label names, and then you have to provide values for each label. So if you want to have different labels for different endpoints, I think you should register separate metrics (both in the Tapir model, and in the Prometheus model) for both cases?

Then, if you have a customer-endpoint, you increment or otherwise modify the customer metric. Same with the product one.

I’m not a prometheus expert, but if you want to use a single metric, then it seems you always need to provide all values for all labels. So a product-request would have to use some default/empty values for the customer labels, and vice versa. I guess that’s also an option.

1 Like