Ad Widget

Collapse

Count an specific word

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • cyberphantom
    Member
    • Dec 2021
    • 67

    #1

    Count an specific word

    Hello!
    I have an item that is collecting the result from an API. The result is a JSON, like this:
    {"service1" : { "healthy" : true, "yyy" : "xxx" }, "service2" : { "healthy" : true}, "service3" : { "healthy" : true} (...) }
    To monitor it, I need to count how many "true" it's returning, so in the final, if I have 5 "true's" I know that everything is ok. I'm with some troubles to do it... I tried calculated items and used this expression: > count(general.value,"true"), and "general.value" is the key of my main item, the one that is collecting the response from API, but unsuccessfully. I've read the manual, but I didn't understand it very well, so I know that I'm doing something wrong.

    This is the best way to do this type of count? and what I'm doing wrong?
  • ISiroshtan
    Senior Member
    • Nov 2019
    • 324

    #2
    Count function will not count how many times X is present in value. If will count how many values contained X in the past Y values. So if you check a single item it will just give 1 if it found word "true" and 0 if it did not.

    It should be possible to achieve what you want somehow, but would it not make more sense to actually split each service into separate item and have separate trigger for each of the services reported?

    Comment

    • cyberphantom
      Member
      • Dec 2021
      • 67

      #3
      I see...
      Well, I'm already doing your suggestion, I just wanted to do something more "compact" too

      Comment

      • ISiroshtan
        Senior Member
        • Nov 2019
        • 324

        #4
        Well if you want "compact" solution as you described initially: change item data type to numeric and drop preprocessing of JS type with code:

        Code:
        var count = (value.match(/true/g) || []).length;
        return count
        Also still think creating template with discvoery is a better long-term approach.

        P.S. Don't remember your Zabbix version, but pre-processing test on 4.4 showed good result (can not test on 5.0, as killed my Zabbix 5 lab machine when doing some tests with Ubuntu )
        P.P.S. One thing this forum teaches me - using JS... bit-by-bit

        Comment

        • splitek
          Senior Member
          • Dec 2018
          • 101

          #5
          You can use preprocessing: https://www.zabbix.com/documentation..._functionality
          Maybe something like one of this:
          $.object.history.length() Return the number of object.history array elements.
          $[?(@.price > 10)].length() Return the number of objects with price being greater than 10.
          $..tags.first().length() definite 5 $..tags is indefinite path, so it returns an array of matched elements - [["a", "b", "c", "d", "e" ]], first() returns the first element - ["a", "b", "c", "d", "e" ] and finally length() calculates its length - 5.
          Generally you need to know JsonPath, how to calculate number of array elements equal "true"

          Comment

          • ISiroshtan
            Senior Member
            • Nov 2019
            • 324

            #6
            Hah, actually you are correct splitek. I was thinking it will not work as it's not an array that is returned, but after few tests I can say that it does work:

            So yeah, cyberphantom instead of JS pre-processing you can go JsonPath preprocessing with expression like
            Code:
            $.[?(@.healthy == "true")].length()
            P.S. Still think template with LLD is better :P

            Comment

            • cyberphantom
              Member
              • Dec 2021
              • 67

              #7
              Thanks ISiroshtan and splitek !!
              I've tested here and it's working perfectly.

              Comment

              Working...