prometheus-community / json_exporter

A prometheus exporter which scrapes remote JSON by JSONPath
Apache License 2.0
632 stars 196 forks source link

Parsing, splitting etc... strings #63

Open sarcalier opened 3 years ago

sarcalier commented 3 years ago

Hello, dear team

Trying to utilize your handy exporter to parse some monitoring data from some app. Having an a issue while trying to parse this sample json output, e.g: { "Timestamp": "2020-Nov-10 04:15:38", "ProcessInfo": { "started": "2020-Oct-05 21:57:42", "uptime": "846:17:56", "cpu_usage": "1%" } }

with this sample config: - name: ProcessInfo type: object help: Process CPU usage path: $.ProcessInfo labels: environment: beta # static label values: cpu_usage: $.cpu_usage

I end up getting a reasonable error: level=error ts=2020-11-10T11:13:15.653Z caller=collector.go:81 msg="Failed to extract value" path=$.cpu_usage err="failed to parse value as float; value: \"0%\"; err: strconv.ParseFloat: parsing \"0%\": invalid syntax"

since "%" character can`t be parsed as float....

Unfortunately can`t find a way to transform the "$.cpu_usage". Is is possible to somehow split the string and to filter out unwanted characters? Is there a way to mutate the e.g. DATE and UPTIME values to ones accepted by this exporter and further prometheus scrapper job?

Thank you in advance.

krakazyabra commented 3 years ago

faced with the same situation, my device gives me such json

{
    "status": {
      "hardwareInfo": {
        "DIMM 1": {
          "DIMM Capacity": "16 GB",
          "DIMM Serial Number": "8270BBC3"
        },
        "DIMM 2": {
          "DIMM Capacity": "16 GB",
          "DIMM Serial Number": "8270BC71"
        },
        "HDD 1": {
          "Capacity": "960 GB",
          "Firmware": "EDA7502Q",
          "Model": "SAMSUNG MZ1LB960HAJQ-00007",
          "Serial Number": "S435NE0N103507",
          "Wear": "0%"
        },
      },
      "managementStatus": "Cartridge OK.",
      "power": "On",
      "status": "OK",
      "uid": "Off"
    }
}

And I need to convert $.status.hardwareInfo.["HDD 1"].Wear into simple number (and cut percentage symbol) to use this value in dynamic values.

tinfever commented 3 years ago

I've encountered something similar. My input has multiple comma separated values under one field (I wish it didn't) and I'd like to be able to use regex to parse it into one or more fields.

Example JSON:

{
    "status": "1",
    "message": "OK-Missing/Invalid API Key, rate limit of 1/5sec applied",
    "result": {
        "LastBlock": "13109518",
        "SafeGasPrice": "124",
        "ProposeGasPrice": "125",
        "FastGasPrice": "125",
        "suggestBaseFee": "123.917583941",
        "gasUsedRatio": "0.648082066666667,0.0912943,0.537084466666667,0.537810533333333,0.11204085876808"
    }
}

If I wanted all of the values, it'd be nice to be able to use a configuration like this: (Forgive me, regex isn't my first language)

metrics:
  - name: etherscan_gas
    type: object
    help: Etherscan Gas Statistics
    path: "{.result}"
    labels:
    values:
      LastBlock: '{.LastBlock}'
      SafeGasPrice: '{.SafeGasPrice}'
      ProposeGasPrice: '{.ProposeGasPrice}'
      FastGasPrice: '{.FastGasPrice}'
      SuggestBaseFee: '{.suggestBaseFee}'
      GasUsedRatio_value1:
        Input: '{.gasUsedRatio}'
        Regex: '([0-9,.]*),[0-9,.]*,[0-9,.]*,[0-9,.]*,[0-9,.]*'
      GasUsedRatio_value2:
        Input: '{.gasUsedRatio}'
        Regex: '[0-9,.]*,([0-9,.]*),[0-9,.]*,[0-9,.]*,[0-9,.]*'
      GasUsedRatio_value3:
        Input: '{.gasUsedRatio}'
        Regex: '[0-9,.]*,[0-9,.]*,([0-9,.]*),[0-9,.]*,[0-9,.]*'
      GasUsedRatio_value4:
        Input: '{.gasUsedRatio}'
        Regex: '[0-9,.]*,[0-9,.]*,[0-9,.]*,([0-9,.]*),[0-9,.]*'
      GasUsedRatio_value5:
        Input: '{.gasUsedRatio}'
        Regex: '[0-9,.]*,[0-9,.]*,[0-9,.]*,[0-9,.]*,([0-9,.]*)'

Maybe for the other people working with whole percentage numbers, there would be some way to add a "math" config for each value so they could just set it to "x/100" to convert their values into a 0-1 ratio. I'm sure someone else could find a use case for wanting to do "x^3+x^2-2x" or something fancy, although I suppose it could be argued that any math would be a better fit for Prometheus recording rules?

Hmm. I wonder if there is some way to have the json-exporter pull in these improperly formatted metrics as a dynamic label, and then use recording rules and relabeling to coax them into the right format, and then drop the original metric to avoid infinite label churn...

Edit: Unless there is some way to use relabel_config, metric_relabel_config, or recording rules to move data from a label to a metric, this isn't possible. Although that's the only issue I think. You could pull the data in via a dynamic label from json_exporter, and then use metric_relabel_config with regex to replace the same label with only the part you want. However, unless there was a way to then replace the metric value with that label's value (then you'd add another metric_relabel_config step to just drop the original label entirely), I can't see how to do it. You could have even used recording_rules to do any math too, although at that point you could just do it inside any query.

adriendrien commented 1 year ago

Hi, did you manage to do this ? I'm also trying to extract int from string (ie delete units, like %). I can't change the source json

BCordleRossVideo commented 1 year ago

Hi - Just want to +1 this issue. I am trying to parse data from Open Hardware Monitor, and the data.json it exposes results in values like "45%" and "60 *C". A way to convert those into floats would solve several issues for me.