prometheus / jmx_exporter

A process for exposing JMX Beans via HTTP for Prometheus consumption
Apache License 2.0
3.03k stars 1.2k forks source link

Add support for default values of regex match groups in rules #905

Open EconomicTouristsArmLate opened 8 months ago

EconomicTouristsArmLate commented 8 months ago

To properly consume some metrics, I need to set a default value on a label. This label value is defined by an optional match group, example config (ref label version):

---
lowercaseOutputLabelNames: true
lowercaseOutputName: true
whitelistObjectNames: ["java.lang:type=OperatingSystem", "Catalina:*"]
blacklistObjectNames: []
rules:
  - pattern: 'Catalina<j2eeType=WebModule, name=//(?:localhost/)?([-a-zA-Z0-9+&@/%?=~_|!:.,;]*[-a-zA-Z0-9+&@/%=~_|])(?:##(.+))?, J2EEApplication=none, J2EEServer=none><>startTime:'
    name: tomcat_module_started_at
    labels:
      module: "$1"
      version: "$2"
    help: Tomcat WebModule startTime (unix time)
    type: GAUGE

Note that version is fed by an optional regex match. I'd love to be able to write something along the lines of

    labels:
      module: "$1"
      version: "${2:-unversioned}"

though I don't care much about the specific syntax (using bash syntax here, which is also commonly used in ENV substitions, eg in docker compose files).

dhoard commented 8 months ago

@EconomicTouristsArmLate I believe I understand what you are trying to accomplish, but don't fully follow the use case.

The MBean should be providing a label. Is there a reason that a lack of a label (i.e. empty string) can't be handled downstream?

EconomicTouristsArmLate commented 8 months ago

The problem I'm trying to solve is dumb: I need to sort versions via string comparison (this is how tomcat determines the latest / active version of an app). And an empty label value does sort higher than any other value, but it should sort lowest.

This use case is slightly ridiculous, but I'm sure there are other use cases that benefit from a default label value. Providing a default label value simply improves readability of metrics, which is a benefit in its own.

For now I workaround this problem with multiple, more specific match rules, but this is quite cumbersome and error prone:

rules:
  # first rule with only matches `name` with a version, second rule matches without. only first match is used.
  # this is, so that we always have a value in the version label, so that we can string sort by this, in order to find the latest version
  # in the same way tomcat does... the default version string must thus be sorted before numbers, '-' does that.
  - pattern: 'Catalina<j2eeType=WebModule, name=//(?:localhost/)?([-a-zA-Z0-9+&@/%?=~_|!:.,;]*[-a-zA-Z0-9+&@/%=~_|])(?:##(.+)), J2EEApplication=none, J2EEServer=none><>startTime:'
    name: tomcat_module_started_at
    labels:
      module: "$1"
      version: "$2"
    help: Tomcat WebModule startTime (unix time)
    type: GAUGE
  - pattern: 'Catalina<j2eeType=WebModule, name=//(?:localhost/)?([-a-zA-Z0-9+&@/%?=~_|!:.,;]*[-a-zA-Z0-9+&@/%=~_|]), J2EEApplication=none, J2EEServer=none><>startTime:'
    name: tomcat_module_started_at
    labels:
      module: "$1"
      version: '-'          # ← ← ← ← ← ←  note the default value here
    help: Tomcat WebModule startTime (unix time)
    type: GAUGE