Better Cacti memory usage graphs

Cacti is a wonderful tool, but many of the default graphs are ugly. Worse, the “ucd/net Memory Usage” graph is totally useless. It displays memory which is free, or dedicated to cache or buffers. But it doesn’t display the actual used memory or total. And it uses the wrong base, assuming there are 1000 bytes in a kilobyte of memory. I can’t imagine why this graph template is even included with Cacti by default. So, I set out to make a better one.

Here is the default graph:

default_memory_usage

(Click to embiggen)

The implementation for “used memory” in the SNMP OID is inconsistent across devices. But you can fetch “total memory”, and do the math:

Used memory = Total – (Free + Cache + Buffers)

Many people have used this method to make better memory usage templates. Eric A. Hall made a much prettier graph, but it relies on an external script to fetch the data and do the math. This is unnecessary, and (slightly) slower than using Cacti CDEF functions. Hans Fugal used CDEF functions, but his graphs use an eye-searing colour scheme. He also uses the wrong base; there are 1024 bytes in a kilobyte of RAM, not 1000 as in hard drives or network data rate.

Here are mine:

memory_usage

swap_usage

My implementation uses Eric Hall’s colour scheme and Hans Fugal’s CDEF method, but graphs real memory and swap as two separate graphs. It also uses the correct unit base of 1024. These graphs are also intended for Linux. Unix operating systems won’t report Buffers or Cache, but they’ll graph correctly as long as they report Free and Total.

Downloads:

cacti_graph_template__ucdnet_-_memory_usage_real.xml

cacti_graph_template__ucdnet_-_memory_usage_swap.xml

Only after making my own did I discover fmangeant‘s graphs. These use the CDEF method and correct base, although I’m not fond of the colours. The “Memory Usage Unix” graph would be useful if your device doesn’t report Buffers or Cache and you don’t want to see zero values on your graph.

Tags:

  1. Kelvin’s avatar

    I implemented Memory Usage Real. All except Used memory are fine. For Used Memory the values are nan. How can I solve this problem?

    Reply

    1. Tyler Wagner’s avatar

      Hi Kelvin,

      Used Memory is calculated from the other values. Are any of them showing NaN?

      Did you get the CDEF “Memory Usage – Calculate Memory Used” in the import?

      Are you polling at 1 minute or 5? Since this uses multiple data sources, if your poller runs every minute but you only poll for this graph every five, you’ll have a problem. The easiest solution is to make sure this

      I’ve replaced the XML files on this post with my latest versions. Changes:
      – Removed the maximum values on RAM, which default to 10 GB. That’s too low on modern equipment.
      – Changed to polling every minute. Should work on 5-minute polling. To change back, edit all Memory Usage data templates and change Step from 60 to 300 and Heartbeat from 120 to 600.

      Reply

    2. Kelvin’s avatar

      The others are showing values except for Used Memory.

      Yes. The CDEF “Memory Usage – Calculate Memory Used” is also imported. I’ve also implemented in all 5 graph items under “Used” Data Source.

      You are referring to the Poller Interval under Settings? If that’s so it’s already at 5 minutes.

      Reply

      1. Tyler Wagner’s avatar

        A default Cacti install has Poller Internal set to 5 minutes, but higher end users often set this to 1 minute (and update cron). After that, they edit any data source templates and add the “Hourly (1 Minute Average)” RRA, and lower Step to 60 and Heartbeat to 120. If you’re using the default config, consider editing my Data Source Templates and change Step to 300 and Heartbeat to 600 in all places.

        Please try the new XMLs on this post.

        If that fails, turn on graph debugging and post what it prints here. Mine looks like this:

        /usr/bin/rrdtool graph - \
        --imgformat=PNG \
        --start=1366710758 \
        --end=1366797158 \
        --title='ap-belafonte - Memory Usage, Real' \
        --base=1024 \
        --height=120 \
        --width=750 \
        --alt-autoscale-max \
        --lower-limit='0' \
        COMMENT:"From 2013-04-23 10\:52\:38 To 2013-04-24 10\:52\:38\c" \
        COMMENT:"  \n" \
        --vertical-label='bytes' \
        --slope-mode \
        --font TITLE:10: \
        --font AXIS:8: \
        --font LEGEND:8: \
        --font UNIT:8: \
        DEF:a="/var/www/cacti/rra/ap-belafonte_mem_buffers_831.rrd":'mem_buffers':AVERAGE \
        DEF:b="/var/www/cacti/rra/ap-belafonte_mem_cache_832.rrd":'mem_cache':AVERAGE \
        DEF:c="/var/www/cacti/rra/ap-belafonte_mem_free_833.rrd":'mem_free':AVERAGE \
        DEF:d="/var/www/cacti/rra/ap-belafonte_mem_total_834.rrd":'mem_total':AVERAGE \
        CDEF:cdefa='d,a,-,b,-,c,-,1024,*' \
        CDEF:cdeff='a,1024,*' \
        CDEF:cdefba='b,1024,*' \
        CDEF:cdefbf='c,1024,*' \
        CDEF:cdefca='d,1024,*' \
        AREA:cdefa#862F2FFF:"Used"  \
        GPRINT:cdefa:LAST:"      Current\:%8.2lf %s"  \
        GPRINT:cdefa:AVERAGE:"Average\:%8.2lf %s"  \
        GPRINT:cdefa:AVERAGE:"Minimum\:%8.2lf %s"  \
        GPRINT:cdefa:MAX:"Maximum\:%8.2lf %s\n"  \
        AREA:cdeff#EA8F00FF:"Buffers":STACK \
        GPRINT:cdeff:LAST:"   Current\:%8.2lf %s"  \
        GPRINT:cdeff:AVERAGE:"Average\:%8.2lf %s"  \
        GPRINT:cdeff:AVERAGE:"Minimum\:%8.2lf %s"  \
        GPRINT:cdeff:MAX:"Maximum\:%8.2lf %s\n"  \
        AREA:cdefba#FFC73BFF:"Cache":STACK \
        GPRINT:cdefba:LAST:"     Current\:%8.2lf %s"  \
        GPRINT:cdefba:AVERAGE:"Average\:%8.2lf %s"  \
        GPRINT:cdefba:AVERAGE:"Minimum\:%8.2lf %s"  \
        GPRINT:cdefba:MAX:"Maximum\:%8.2lf %s\n"  \
        AREA:cdefbf#74C366FF:"Free":STACK \
        GPRINT:cdefbf:LAST:"      Current\:%8.2lf %s"  \
        GPRINT:cdefbf:AVERAGE:"Average\:%8.2lf %s"  \
        GPRINT:cdefbf:AVERAGE:"Minimum\:%8.2lf %s"  \
        GPRINT:cdefbf:MAX:"Maximum\:%8.2lf %s\n"  \
        LINE1:cdefca#000000FF:"Total Real"  \
        GPRINT:cdefca:LAST:"Current\:%8.2lf %s\n" 

        Sometimes updating or importing graph templates causes errors where CDEFs aren’t correctly applied. If you see any lines lacking the “cdef” prefixes where they do exist in my example, that’s your issue. The workaround is to edit the Graph Template, edit each item, and save.

        Reply

      2. Kelvin’s avatar
        /usr/bin/rrdtool graph - \
        --imgformat=PNG \
        --start=-86400 \
        --end=-300 \
        --title='my-adsl - Memory Usage, Real' \
        --base=1024 \
        --height=120 \
        --width=750 \
        --alt-autoscale-max \
        --lower-limit='0' \
        --vertical-label='bytes' \
        --slope-mode \
        --font TITLE:10: \
        --font AXIS:7: \
        --font LEGEND:8: \
        --font UNIT:7: \
        DEF:a="/var/www/cacti/rra/my-adsl_usedreal_293.rrd":'usedReal':AVERAGE \
        DEF:b="/var/www/cacti/rra/my-adsl_mem_buffers_312.rrd":'mem_buffers':AVERAGE \
        DEF:c="/var/www/cacti/rra/my-adsl_mem_cache_313.rrd":'mem_cache':AVERAGE \
        DEF:d="/var/www/cacti/rra/my-adsl_mem_free_314.rrd":'mem_free':AVERAGE \
        DEF:e="/var/www/cacti/rra/my-adsl_mem_total_315.rrd":'mem_total':AVERAGE \
        CDEF:cdefa='a,1024,*' \
        CDEF:cdeff='b,1024,*' \
        CDEF:cdefba='c,1024,*' \
        CDEF:cdefbf='d,1024,*' \
        CDEF:cdefca='e,1024,*' \
        AREA:cdefa#862F2FFF:"Used"  \
        GPRINT:cdefa:LAST:"      Current\:%8.2lf %s"  \
        GPRINT:cdefa:AVERAGE:"Average\:%8.2lf %s"  \
        GPRINT:cdefa:MIN:"Minimum\:%8.2lf %s"  \
        GPRINT:cdefa:MAX:"Maximum\:%8.2lf %s\n"  \
        AREA:cdeff#EA8F00FF:"Buffers":STACK \
        GPRINT:cdeff:LAST:"   Current\:%8.2lf %s"  \
        GPRINT:cdeff:AVERAGE:"Average\:%8.2lf %s"  \
        GPRINT:cdeff:AVERAGE:"Minimum\:%8.2lf %s"  \
        GPRINT:cdeff:MAX:"Maximum\:%8.2lf %s\n"  \
        AREA:cdefba#FFC73BFF:"Cache":STACK \
        GPRINT:cdefba:LAST:"     Current\:%8.2lf %s"  \
        GPRINT:cdefba:AVERAGE:"Average\:%8.2lf %s"  \
        GPRINT:cdefba:AVERAGE:"Minimum\:%8.2lf %s"  \
        GPRINT:cdefba:MAX:"Maximum\:%8.2lf %s\n"  \
        AREA:cdefbf#74C366FF:"Free":STACK \
        GPRINT:cdefbf:LAST:"      Current\:%8.2lf %s"  \
        GPRINT:cdefbf:AVERAGE:"Average\:%8.2lf %s"  \
        GPRINT:cdefbf:AVERAGE:"Minimum\:%8.2lf %s"  \
        GPRINT:cdefbf:MAX:"Maximum\:%8.2lf %s\n"  \
        LINE1:cdefca#000000FF:"Total Real"  \
        GPRINT:cdefca:LAST:"Current\:%8.2lf %s\n"

        Reply

        1. Tyler Wagner’s avatar

          Where does this data source “usedReal” come from? That’s not in my template, and you cannot fetch usedReal in the ucd/net MIB. That’s why it must be calculated.

          Compare our output, and you can see that my first set of GPRINTS are using the “Calculate Memory Used” CDEF. Yours is pulling from some data source I haven’t heard of.

          Reply

        2. Tyler Wagner’s avatar

          Your graph template has been edited somehow. Here is mine:

          graph_template_1

          And here are the details of item #2. Notice how there is no data source, and shouldn’t be. The CDEF provides the data.

          graph_template_2

          Reply

        3. Kelvin’s avatar

          Thanks for the screenshots. I changed the settings according to your screenshots and I don’t know why a new error shows. Here’s my debugging output:

          /usr/bin/rrdtool graph - \
          --imgformat=PNG \
          --start=-86400 \
          --end=-300 \
          --title='my-adsl - Memory Usage, Real' \
          --base=1024 \
          --height=120 \
          --width=750 \
          --alt-autoscale-max \
          --lower-limit='0' \
          --vertical-label='bytes' \
          --slope-mode \
          --font TITLE:10: \
          --font AXIS:7: \
          --font LEGEND:8: \
          --font UNIT:7: \
          DEF:a="/var/www/cacti/rra/my-adsl_mem_buffers_306.rrd":'mem_buffers':AVERAGE \
          DEF:b="/var/www/cacti/rra/my-adsl_mem_cache_307.rrd":'mem_cache':AVERAGE \
          DEF:c="/var/www/cacti/rra/my-adsl_mem_free_308.rrd":'mem_free':AVERAGE \
          DEF:d="/var/www/cacti/rra/my-adsl_mem_total_315.rrd":'mem_total':AVERAGE \
          CDEF:cdefa='d,a,-,b,-,c,-,1024,*' \
          CDEF:cdefb='a,1024,*' \
          CDEF:cdefd='a,1024,*' \
          CDEF:cdefi='b,1024,*' \
          CDEF:cdefbd='c,1024,*' \
          CDEF:cdefbi='d,1024,*' \
          GPRINT:cdefa:LAST:"Current\:%8.2lf %s"  \
          GPRINT:cdefb:AVERAGE:"Average\:%8.2lf %s"  \
          GPRINT:cdefa:AVERAGE:"Minimum\:%8.2lf %s"  \
          :cdefd#EA8F00FF:"Buffers":STACK \
          GPRINT:cdefd:LAST:"   Current\:%8.2lf %s"  \
          GPRINT:cdefd:AVERAGE:"Average\:%8.2lf %s"  \
          GPRINT:cdefd:AVERAGE:"Minimum\:%8.2lf %s"  \
          GPRINT:cdefd:MAX:"Maximum\:%8.2lf %s\n"  \
          :cdefi#FFC73BFF:"Cache":STACK \
          GPRINT:cdefi:LAST:"     Current\:%8.2lf %s"  \
          GPRINT:cdefi:AVERAGE:"Average\:%8.2lf %s"  \
          GPRINT:cdefi:AVERAGE:"Minimum\:%8.2lf %s"  \
          GPRINT:cdefi:MAX:"Maximum\:%8.2lf %s\n"  \
          :cdefbd#74C366FF:"Free":STACK \
          GPRINT:cdefbd:LAST:"      Current\:%8.2lf %s"  \
          GPRINT:cdefbd:AVERAGE:"Average\:%8.2lf %s"  \
          GPRINT:cdefbd:AVERAGE:"Minimum\:%8.2lf %s"  \
          GPRINT:cdefbd:MAX:"Maximum\:%8.2lf %s\n"  \
          LINE1:cdefbi#000000FF:"Total Real"  \
          GPRINT:cdefbi:LAST:"Current\:%8.2lf %s\n" 

          RRDTool Says:

          ERROR: Could not make sense out of ‘:cdefd#EA8F00FF:Buffers:STACK’

          Reply

          1. Tyler Wagner’s avatar

            I wrapped your output in “pre” tags to make it display better here.

            The lines that say “:cdefbd#74C366FF:”Free”:STACK” are in error. They should begin with “AREA”. Try editing each of those lines and change them to AREA for the first item and STACK for the others. You may need to change them to LINE1 and then back again for this to fix itself.

            Reply

          2. Kelvin’s avatar

            Got it. Thanks a lot. My graph is working well now.

            Reply

          3. AK’s avatar

            Thanks for these, they just worked and are great!

            Reply

          4. Steve Stevenson’s avatar

            I just tried to import your templates you had in this document. I see all the items in the cacti sections.

            [code]
            /usr/bin/rrdtool create \
            /var/lib/cacti/rra/localhost_mem_total_64.rrd \
            –step 60 \
            DS:mem_total:GAUGE:120:0:U \
            RRA:AVERAGE:0.5:1:500 \
            RRA:AVERAGE:0.5:1:600 \
            RRA:AVERAGE:0.5:6:700 \
            RRA:AVERAGE:0.5:24:775 \
            RRA:AVERAGE:0.5:288:797 \
            RRA:MIN:0.5:1:500 \
            RRA:MIN:0.5:1:600 \
            RRA:MIN:0.5:6:700 \
            RRA:MIN:0.5:24:775 \
            RRA:MIN:0.5:288:797 \
            RRA:MAX:0.5:1:500 \
            RRA:MAX:0.5:1:600 \
            RRA:MAX:0.5:6:700 \
            RRA:MAX:0.5:24:775 \
            RRA:MAX:0.5:288:797 \
            RRA:LAST:0.5:1:500 \
            RRA:LAST:0.5:1:600 \
            RRA:LAST:0.5:6:700 \
            RRA:LAST:0.5:24:775 \
            RRA:LAST:0.5:288:797 \
            [/code]

            This is being output by cacti in the data source debugger. But the file is not being created on the file system. If I run the same from the CLI using the same user as the cacti process it creates it fine. But for whatever reason cacti is not generating this file on its own. If I create data sources from the default cacti templates/sources it is creating the rrd files with no issues. Any idea why your templates would not be allowing cacti to create them on its own?

            Reply

            1. Tyler Wagner’s avatar

              No idea, sorry. I have not experienced that after importing these templates on other installs. Suggested test: export another similar template and compare the exports (Meld, colordiff, diff) side by side to see if there is anything relevant.

              Reply

            2. https://computerrepairmanchesternews.wordpress.com’s avatar

              Wohh just what I was looking for, thanks for putting up.

              Reply

Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.