oetiker / rrdtool-1.x

RRDtool 1.x - Round Robin Database
http://www.rrdtool.org
GNU General Public License v2.0
992 stars 260 forks source link

CDEF works wrong on short distance #1096

Open BombermaG opened 3 years ago

BombermaG commented 3 years ago

RRDgraph show wrong data on graph when using CDEF and python callback. Code listing with bad result (from this example with little modification):

import rrdtool
import sys
import math

def my_callback(filename, cf, start, end, step):
    items = int((end - start) / step)
    return {
        'start': start,
        'step': 300,
        'data': {
            'a': [math.sin(x / 200) for x in range(0, items)],
            'b': [math.cos(x / 200) for x in range(10, items)],
            'c': [math.sin(x / 100) for x in range(100, items)],
        }
    }

def main():
    graphv_args = [
        'test.png',
        '--title', 'Callback Demo',
        '--start', '1424540800',
        '--end', 'start+1d',
        '--lower-limit=0',
        '--interlaced',
        '--imgformat', 'PNG',
        '--width=450',
        'DEF:a=cb//extrainfo:a:AVERAGE',
        'DEF:b=cb//:b:AVERAGE',
        'DEF:c=cb//:c:AVERAGE',
        'LINE:a#00b6e4:a',
        'LINE:b#10b634:b',
        'LINE:c#503d14:c',
        'CDEF:test=a,2,*',
        'LINE:test#ff391a:test',
        'VDEF:av=a,AVERAGE',
        'PRINT:av:%8.6lf'
    ]

    rrdtool.register_fetch_cb(my_callback)
    rrdtool.graphv(*graphv_args)

if __name__ == "__main__":
    main()

Result: bad Look at red line test. It is straight, but must be like a 2, because CDEF:test=a,2, After changing --end to start+2d all looks fine.

import rrdtool
import sys
import math

def my_callback(filename, cf, start, end, step):
    items = int((end - start) / step)
    return {
        'start': start,
        'step': 300,
        'data': {
            'a': [math.sin(x / 200) for x in range(0, items)],
            'b': [math.cos(x / 200) for x in range(10, items)],
            'c': [math.sin(x / 100) for x in range(100, items)],
        }
    }

def main():
    graphv_args = [
        'test.png',
        '--title', 'Callback Demo',
        '--start', '1424540800',
        '--end', 'start+2d',
        '--lower-limit=0',
        '--interlaced',
        '--imgformat', 'PNG',
        '--width=450',
        'DEF:a=cb//extrainfo:a:AVERAGE',
        'DEF:b=cb//:b:AVERAGE',
        'DEF:c=cb//:c:AVERAGE',
        'LINE:a#00b6e4:a',
        'LINE:b#10b634:b',
        'LINE:c#503d14:c',
        'CDEF:test=a,2,*',
        'LINE:test#ff391a:test',
        'VDEF:av=a,AVERAGE',
        'PRINT:av:%8.6lf'
    ]

    rrdtool.register_fetch_cb(my_callback)
    rrdtool.graphv(*graphv_args)

if __name__ == "__main__":
    main()

Result: good

Something wrong with CDEF on short period.

Debian 10.6, Python 3.7.3 rrdtool 1.7.1-2, python3-rrdtool 1.7.1-2 installed by apt.

yrebrac commented 3 years ago

You haven't shown the data for a. Have you checked the sin function isn't actually returning all zeros?

BombermaG commented 3 years ago

You haven't shown the data for a. Have you checked the sin function isn't actually returning all zeros?

As you can see, "a" is not the zero line on the chart.

yrebrac commented 3 years ago

2 x 0 = 0. So if series a is all zero, line test will be all zeros

BombermaG commented 3 years ago

2 x 0 = 0. So if series a is all zero, line test will be all zeros

Look at line "a" in the first chart.

yrebrac commented 3 years ago

Different start and end = equals potentially different dataset. rrdtool is resampling and recomputing entirely for each new time range. I'm not saying zero data is the problem, I'm saying you should rule it out :)