json_exporter icon indicating copy to clipboard operation
json_exporter copied to clipboard

[FR] Extend JSONPath syntax to get object names

Open ivanov17 opened this issue 1 year ago • 3 comments

Hello community,

At the moment we don't have a way to get JSON object names using JSONPath syntax. But some programs send statistics as objects that contain other objects rather than arrays. For example, this is the NGINX Unit statistics output:

{
    "connections": {
        "accepted": 1067,
        "active": 13,
        "idle": 4,
        "closed": 1050
    },

    "requests": {
        "total": 1307
    },

    "applications": {
        "wp": {
            "processes": {
                "running": 14,
                "starting": 0,
                "idle": 4
            },

            "requests": {
                "active": 10
            }
        },
        "mw": {
            "processes": {
                "running": 15,
                "starting": 0,
                "idle": 3
            },
            "requests": {
                "active": 12
            }
        }
    }
}

In this case we need to iterate over the applications object and get the name for each application object to use it as the metric label.

It seems that this problem should be solved by the exporter, not the application itself, because we can't control the output of each API. See also the case with another API in #250.

There is a practice to extend the JSONPath syntax to get the object names, parent elements, etc. For example, to get the name of an object, a tilde (~) is typically used. This syntax is used by the widely used JSONPath-Plus JS library and by the yaml-jsonpath Go library created by VMWare.

Using this syntax we could get the metrics for applications running by NGINX Unit like this:

---
modules:
  default:
    metrics:
      - name: "unit_app"
        type: "object"
        valuetype: "gauge"
        path: "{ .applications.* }"
        labels:
          app: "{ @~ }"
        values:
          processes_running: "{ .processes.running }"
          processes_starting: "{ .processes.starting }"
          processes_idle: "{ .processes.idle }"
          requests_active: "{ .requests.active }"

I think we don't need to switch from the current library or send a syntax-extending patch to the upstream, we need to add it just for this exporter.

For now, anyone experiencing this issue will need to fork the project just to add this feature and maintain it themselves. Or this can also be solved by creating an exporter that uses JMESPath. But simply extending the existing syntax seems preferable.

ivanov17 avatar Jun 15 '24 20:06 ivanov17

+1 to this!

silveraignacio avatar Jul 01 '24 19:07 silveraignacio

Yes, this is very useful and necessary!

raccoon4x avatar Jul 16 '24 01:07 raccoon4x

+1 - I have a similar use case

askfongjojo avatar Sep 20 '24 00:09 askfongjojo