Ad Widget

Collapse

Calculating a ratio between two items

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • eran
    Member
    • Apr 2007
    • 36

    #1

    Calculating a ratio between two items

    Is it possible to create a calculated item that would be the ratio of two other items?
    It seems that all the pieces are there, it is possible to calculate a ratio in triggers, so Zabbix knows how to do that, and it also has the concept of aggregated items, which are calculated based on other items. However, when I tried creating a new aggregated item which is the ratio between two other aggregated items it didn't work. Any way to do that?

    Thanks,
    Eran
    Last edited by eran; 22-01-2010, 22:27.
  • nelsonab
    Senior Member
    Zabbix Certified SpecialistZabbix Certified Professional
    • Sep 2006
    • 1233

    #2
    If you're wanting to do any calculation for items within the same host you'll need to write an external check on the server which does a query of the last value for each item and then stores that value. It's not pretty but it's the best way to do it right now.
    RHCE, author of zbxapi
    Ansible, the missing piece (Zabconf 2017): https://www.youtube.com/watch?v=R5T9NidjjDE
    Zabbix and SNMP on Linux (Zabconf 2015): https://www.youtube.com/watch?v=98PEHpLFVHM

    Comment

    • eran
      Member
      • Apr 2007
      • 36

      #3
      Thanks!
      I see Zabbix 1.8 now has an API so hopefully that would not require direct DB queries, however the API reference in the documentation is practically useless without some minimal background on how to use it. Any idea where can that information be found.
      Also I saw your zabocon cli tool, seems very cool, I'll try that as well.

      Comment

      • nelsonab
        Senior Member
        Zabbix Certified SpecialistZabbix Certified Professional
        • Sep 2006
        • 1233

        #4
        You'll still need to direct DB queries, but you can have that data injected via a user parameter. Eventually the API will support the ability to query data points, but right now it's only capable of manipulating what's monitored.
        RHCE, author of zbxapi
        Ansible, the missing piece (Zabconf 2017): https://www.youtube.com/watch?v=R5T9NidjjDE
        Zabbix and SNMP on Linux (Zabconf 2015): https://www.youtube.com/watch?v=98PEHpLFVHM

        Comment

        • Alexei
          Founder, CEO
          Zabbix Certified Trainer
          Zabbix Certified SpecialistZabbix Certified Professional
          • Sep 2004
          • 5654

          #5
          We are releasing support of calculated items in Zabbix 1.8.1.
          Alexei Vladishev
          Creator of Zabbix, Product manager
          New York | Tokyo | Riga
          My Twitter

          Comment

          • Ranjit
            Junior Member
            • Mar 2010
            • 5

            #6
            Can you please let me know the syntax for doing this ?

            For example, would this work ?

            vm.memory.size[total] - vm.memory.size[free]

            Thanks.

            Comment

            • nelsonab
              Senior Member
              Zabbix Certified SpecialistZabbix Certified Professional
              • Sep 2006
              • 1233

              #7
              It's probably follows a syntax similar to triggers.
              RHCE, author of zbxapi
              Ansible, the missing piece (Zabconf 2017): https://www.youtube.com/watch?v=R5T9NidjjDE
              Zabbix and SNMP on Linux (Zabconf 2015): https://www.youtube.com/watch?v=98PEHpLFVHM

              Comment

              • alixen
                Senior Member
                • Apr 2006
                • 474

                #8
                Originally posted by nelsonab
                It's probably follows a syntax similar to triggers.
                Well, not really .
                It would be something like:
                last("vm.memory.size[total]") - last("vm.memory.size[free]")

                Check the manual for details : http://www.zabbix.com/documentation/...lculated_items

                Regards
                Alixen
                http://www.alixen.fr/zabbix.html

                Comment

                • jhgrc
                  Member
                  • Jun 2009
                  • 52

                  #9
                  Originally posted by alixen
                  Well, not really .
                  last("vm.memory.size[total]") - last("vm.memory.size[free]")
                  Is there information available how "last" is working.

                  time1: total=tot1 free=fr1
                  time2: total=tot2 free=[nodata yet]

                  Now I use calculated function at time2:

                  last("total") + last("free")

                  I'll get: tot2+fr1

                  Basically I did not expect that is I want to have diskspace information at the same time. But I want to ensure that I get tot2+fr2 despite that fr2 is empty.

                  What I am thinking, can I use somekind of expiry period with last. Like do not calculate last data if it is older than x seconds.

                  last("total",60) + last("free",60)

                  It would calculate data together with maximum age of 60 seconds.

                  Or should I use average function. If my item polls every 60 seconds, I use avg("total",60) to get average of 1 measure?

                  Comment

                  • alixen
                    Senior Member
                    • Apr 2006
                    • 474

                    #10
                    Originally posted by jhgrc
                    Is there information available how "last" is working.
                    Yes.
                    Functions are described in trigger section http://www.zabbix.com/documentation/...gger_functions
                    last without argument returns most recent value.


                    Originally posted by jhgrc
                    time1: total=tot1 free=fr1
                    time2: total=tot2 free=[nodata yet]

                    Now I use calculated function at time2:

                    last("total") + last("free")

                    I'll get: tot2+fr1

                    Basically I did not expect that is I want to have diskspace information at the same time. But I want to ensure that I get tot2+fr2 despite that fr2 is empty.
                    I don't think that Zabbix can guess a value in the future

                    Originally posted by jhgrc
                    What I am thinking, can I use somekind of expiry period with last. Like do not calculate last data if it is older than x seconds.

                    last("total",60) + last("free",60)
                    last always returns a value.
                    According to manual, 60 will be ignored in "last(60)" form.
                    Originally posted by jhgrc
                    It would calculate data together with maximum age of 60 seconds.

                    Or should I use average function. If my item polls every 60 seconds, I use avg("total",60) to get average of 1 measure?
                    I don't see your point. How an average of one mesure is better than last known value ?

                    Alixen
                    http://www.alixen.fr/zabbix.html

                    Comment

                    • jhgrc
                      Member
                      • Jun 2009
                      • 52

                      #11
                      It seems that you didn't get my question. Which was that "last" always returns last value, I cannot control it how old the data can be? Nobody asked to predict to future. I wanted: if no new data is available when evaluating value of calculated item, don't use the expired data.

                      --

                      Perhaps the diskspace calculation was too easy or misleading because diskspace was for single host, lets think about routers.

                      I've items:
                      - r1_bps_in, updated every 30s (on router1 ip 1.1.1.1)
                      - r2_bps_in, updated every 30s (on router2 ip 2.2.2.2)

                      I want to calculate together total bandwidth in
                      - bw_bps_in

                      I use formula:
                      last("r1_bps_in") + last("r2_bps_in)

                      Fine, it works fine normally and is accurate enough.

                      What if r2 goes down, no updates to r2_bps_in -item. But still above calculation calculates last("r1_bps_in")+last("r2_bps_in") in which "r2_bps_in" might be even week old value.

                      I want to limit this. If no update on certain period, don't use it. Expect it as undef or 0.

                      --

                      Then I was thinking of I use avg-function to limit data validity. Remember, I have 30s update interval. What if I use

                      avg("r1_bps_in",30) + avg("r2_bps_in",30)

                      - with-in 30s is only 1 measure (my interval is 30s), so it returns the value as value itself divided by 1 is....
                      - If r2_bps_in goes offline, and no new data with-in 30s -> avg returns 0 (at least it should), remember last returns data from week ago (don't take this literal, week ago, year ago, anytime ago outside wanted window).
                      - okay, I acknowledge that avg(..,30) could also return average of 2 values if data is fetched exactly 30s intervals, and item query is on the same second.

                      --

                      Looking at triggers

                      The function also supports an optional time_shift parameter. For example,
                      last(0,86400) will return the most recent value one day ago.
                      Is this active for "calculated"? And syntax is? last("r1_bps_in",0,45)? (and this is starting from 1.8.2)

                      --

                      Or is the solution with last?
                      nodata("r1_bps_in",45)*last("r1_bps_in) + nodata("r2_bps_in",45)*last("r2_bps_in)

                      Which option is the cheapest?
                      Last edited by jhgrc; 10-03-2010, 13:11.

                      Comment

                      • alixen
                        Senior Member
                        • Apr 2006
                        • 474

                        #12
                        Originally posted by jhgrc
                        It seems that you didn't get my question. Which was that "last" always returns last value, I cannot control it how old the data can be? Nobody asked to predict to future.
                        Sorry, it was just a joke.

                        Originally posted by jhgrc
                        I wanted: if no new data is available when evaluating value of calculated item, don't use the expired data.

                        --

                        Perhaps the diskspace calculation was too easy or misleading because diskspace was for single host, lets think about routers.

                        I've items:
                        - r1_bps_in, updated every 30s (on router1 ip 1.1.1.1)
                        - r2_bps_in, updated every 30s (on router2 ip 2.2.2.2)

                        I want to calculate together total bandwidth in
                        - bw_bps_in

                        I use formula:
                        last("r1_bps_in") + last("r2_bps_in)

                        Fine, it works fine normally and is accurate enough.

                        What if r2 goes down, no updates to r2_bps_in -item. But still above calculation calculates last("r1_bps_in")+last("r2_bps_in") in which "r2_bps_in" might be even week old value.

                        I want to limit this. If no update on certain period, don't use it. Expect it as undef or 0.

                        --

                        Then I was thinking of I use avg-function to limit data validity. Remember, I have 30s update interval. What if I use

                        avg("r1_bps_in",30) + avg("r2_bps_in",30)

                        - with-in 30s is only 1 measure (my interval is 30s), so it returns the value as value itself divided by 1 is....
                        - If r2_bps_in goes offline, and no new data with-in 30s -> avg returns 0 (at least it should), remember last returns data from week ago (don't take this literal, week ago, year ago, anytime ago outside wanted window).
                        - okay, I acknowledge that avg(..,30) could also return average of 2 values if data is fetched exactly 30s intervals, and item query is on the same second.

                        --

                        Looking at triggers



                        Is this active for "calculated"? And syntax is? last("r1_bps_in",0,45)? (and this is starting from 1.8.2)

                        --

                        Or is the solution with last?
                        nodata("r1_bps_in",45)*last("r1_bps_in) + nodata("r2_bps_in",45)*last("r2_bps_in)

                        Which option is the cheapest?
                        Well, calculated items are rather new, so I've done some testing :
                        I have 2 SNMP items collected every 300 s: ifInOctets1 and ifOutOctets1.
                        I have defined 4 calculated items evaluated every 30 seconds:
                        1) ifInOutOctets1 = last(ifInOctets1)+last(ifOutOctets1)
                        2) ifInOutOctets1_avg60 = avg(ifInOctets1,60)+avg(ifOutOctets1,60)
                        3) ifInOutOctets1_avg600 = avg(ifInOctets1,600)+avg(ifOutOctets1,600)
                        4) ifInOutOctets1_nodata = (1-nodata(ifInOctets1,60))*last(ifInOctets1)+(1-nodata(ifOutOctets1,60))*last(ifOutOctets1)

                        First and third items work but may use old values.
                        Second one becomes "unsupported" as soon as there is no data available in last 60 seconds.

                        ifInOutOctets1_nodata is the only one that works as expected:
                        Code:
                        ifInOutOctets1_nodata
                        
                        2010-03-10 16:25:38	1268234738	0
                        2010-03-10 16:25:08	1268234708	0
                        2010-03-10 16:24:38	1268234678	0
                        2010-03-10 16:24:08	1268234648	0
                        2010-03-10 16:23:38	1268234618	0
                        2010-03-10 16:23:08	1268234588	2122063.9467
                        2010-03-10 16:22:38	1268234558	2122063.9467
                        2010-03-10 16:22:08	1268234528	125750.5333
                        2010-03-10 16:21:38	1268234498	125750.5333
                        2010-03-10 16:21:08	1268234468	0
                        2010-03-10 16:20:38	1268234438	0
                        2010-03-10 16:20:08	1268234408	0
                        2010-03-10 16:19:38	1268234378	0
                        2010-03-10 16:19:08	1268234348	0
                        2010-03-10 16:18:38	1268234318	0
                        2010-03-10 16:18:08	1268234288	603761.1733
                        2010-03-10 16:17:38	1268234258	603761.1733
                        2010-03-10 16:17:08	1268234228	80506.56
                        2010-03-10 16:16:38	1268234198	80506.56
                        Hope this helps
                        Alixen
                        http://www.alixen.fr/zabbix.html

                        Comment

                        • jhgrc
                          Member
                          • Jun 2009
                          • 52

                          #13
                          Thanks - however you use rather short avg value for 2nd option as item data is available every 5 minutes but you take 1 minute average. So you have a calculation result 1/5 of the time and 4/5 of the time system should return 0?

                          But still because of way data is collected (not realtime OS) I think the option 4 is only viable solution. But again, use something like 310s for nodata.

                          Comment

                          • alixen
                            Senior Member
                            • Apr 2006
                            • 474

                            #14
                            Originally posted by jhgrc
                            Thanks - however you use rather short avg value for 2nd option as item data is available every 5 minutes but you take 1 minute average. So you have a calculation result 1/5 of the time and 4/5 of the time system should return 0?

                            But still because of way data is collected (not realtime OS) I think the option 4 is only viable solution. But again, use something like 310s for nodata.
                            My point was to check what happens when data is too old.
                            As I didn't want to wait several hours with a real life scenario, I have set up a very short delay (60s) in order to check last() and nodata() behavior.

                            In order to have meaningful values, I agree with you; I should use a delay a little bit superior to data acquisition period.
                            So the best formula would be something like:
                            (1-nodata(ifInOctets1,310))*last(ifInOctets1)+(1-nodata(ifOutOctets1,310))*last(ifOutOctets1)

                            Regards,
                            Alixen
                            http://www.alixen.fr/zabbix.html

                            Comment

                            • fjrial
                              Senior Member
                              • Feb 2010
                              • 140

                              #15
                              Is this active for "calculated"? And syntax is? last("r1_bps_in",0,45)? (and this is starting from 1.8.2)

                              --

                              Or is the solution with last?
                              nodata("r1_bps_in",45)*last("r1_bps_in) + nodata("r2_bps_in",45)*last("r2_bps_in)

                              Which option is the cheapest?
                              My experience: I'm using also calculated items, and zabbix 1.8.2.. and yes, I can use the time_shift parameter in last, but it does NOT work as I want:

                              last("host:item",30) will return the last value in the last 30 seconds of host:item, but, if the item has no value during those 30 seconds, it will return a zero anyway.. for me this is not okay, I need a blank value if I ask for a value that is not present.

                              I opened another thread in the forums to discuss this issue with the time shift parameter:
                              Join the friendly and open Zabbix community on our forums and social media platforms.


                              By the way, wonderful solution with the nodata expresion, it really helps me a lot!!

                              Comment

                              Working...