rrdweb/graph.py
author Tero Marttila <terom@fixme.fi>
Tue, 25 Jan 2011 01:19:40 +0200
changeset 31 cd9ca8068b09
parent 28 89a4d9879171
child 32 47e977c23ba2
permissions -rw-r--r--
doc: clean up pmacct.conf
import rrd
import time

"""
    RRDTool graph output
"""

def timestamp () :
    return time.strftime("%Y/%m/%d %H:%M:%S %Z")

def common_opts () :
    """
        Common options for all views
    """

    return dict(
        # output
        imgformat           = "PNG",
        #        lazy                = True,

        color               = [
            # disable border
            # border            = 0,
            "SHADEA#ffffff00",
            "SHADEB#ffffff00",

            # keep background transparent
            "BACK#ffffff00",
            "SHADEB#ffffff00",
        ],
         
        # labels
        vertical_label      = "bits/s",
        units               = "si",

        # use logarithmic scaling
        logarithmic         = True,
        
        # smooth out lines
        slope_mode          = True,
    )

def overview_opts () :
    """
        Common options for the overview graph
    """

    return dict(
        width               = 600,
        height              = 50,
    ), [
        "CDEF:all=in,out,+",

        "VDEF:max=all,MAXIMUM",
        "VDEF:avg=all,AVERAGE",
        "VDEF:min=all,MINIMUM",

        "LINE1:in#0000FF:In",
        "LINE1:out#00CC00:Out",

        "GPRINT:max:%6.2lf %Sbps max",
        "GPRINT:avg:%6.2lf %Sbps avg",
        "GPRINT:min:%6.2lf %Sbps min\\l",
    ]

def detail_opts () :
    """
        Common options for the detail graph
    """

    return dict(
        # dimensions
        width               = 600,
        height              = 200,
    ), [
        # values
        'VDEF:in_max=in,MAXIMUM',
        'VDEF:in_avg=in,AVERAGE',
        'VDEF:in_min=in,MINIMUM',
        'VDEF:in_cur=in,LAST',
        'VDEF:out_max=out,MAXIMUM',
        'VDEF:out_avg=out,AVERAGE',
        'VDEF:out_min=out,MINIMUM',
        'VDEF:out_cur=out,LAST',

        # legend/graph
        "COMMENT:%4s" % "",
        "COMMENT:%11s" % "Maximum",
        "COMMENT:%11s" % "Average",
        "COMMENT:%11s" % "Minimum",
        "COMMENT:%11s\\l" % "Current",

        "LINE1:in#0000FF:%4s" % "In",
        'GPRINT:in_max:%6.2lf %Sbps',
        'GPRINT:in_avg:%6.2lf %Sbps',
        'GPRINT:in_min:%6.2lf %Sbps',
        'GPRINT:in_cur:%6.2lf %Sbps\\l',

        "LINE1:out#00CC00:%4s" % "Out",
        'GPRINT:out_max:%6.2lf %Sbps',
        'GPRINT:out_avg:%6.2lf %Sbps',
        'GPRINT:out_min:%6.2lf %Sbps',
        'GPRINT:out_cur:%6.2lf %Sbps\\l',
        
        # mark
        "COMMENT:Generated %s\\r" % timestamp().replace(':', '\\:'),
    ]

STYLE_DEFS = {
    'overview': overview_opts,
    'detail':   detail_opts,
}

def daily_opts (title) :
    """
        Common options for the 'daily' view
    """

    return dict(
        # labels
        x_grid              = "MINUTE:15:HOUR:1:HOUR:4:0:%H:%M",
    
        # general info
        title               = "Daily %s" % (title, ),
    
        # interval
        start               = "-24h",
    )

def weekly_opts (title) :
    return dict(
        # labels
        #        x_grid              = "MINUTE:15:HOUR:1:HOUR:4:0:%H:%M",
    
        # general info
        title               = "Weekly %s" % (title, ),
    
        # interval
        start               = "-7d",
    )

def yearly_opts (title) :
    return dict(
        # labels
        #        x_grid              = "MINUTE:15:HOUR:1:HOUR:4:0:%H:%M",
    
        # general info
        title               = "Yearly %s" % (title, ),
    
        # interval
        start               = "-1y",
    )


INTERVAL_DEFS = {
    'daily':    daily_opts,
    'weekly':   weekly_opts,
    'yearly':   yearly_opts,
}

def mrtg_data (rrd_path) :
    """
        Data sources for network in/out from an MRTG rrd
    """

    return [
        # data sources, bytes/s
        r'DEF:in0=%s:ds0:AVERAGE' % rrd_path,
        r'DEF:out0=%s:ds1:AVERAGE' % rrd_path,

        # data, bits/s
        'CDEF:in=in0,8,*',
        'CDEF:out=out0,8,*',

    ]        

def collectd_data (rrd_path) :
    """
        Data sources for if_octets from a collectd rrd
    """

    return [
        # data sources, bytes/s
        r'DEF:in0=%s:rx:AVERAGE' % rrd_path,
        r'DEF:out0=%s:tx:AVERAGE' % rrd_path,

        # data, bits/s
        'CDEF:in=in0,8,*',
        'CDEF:out=out0,8,*',

    ]        
    
def _graph (style, interval, title, data_func, rrd_path, out_path) :
    style_opts, style_vars = STYLE_DEFS[style]()
    interval_opts = INTERVAL_DEFS[interval](title)

    opts = rrd.merge_opts(common_opts(), style_opts, interval_opts)
    data = data_func(rrd_path) + style_vars

    return rrd.graph(out_path, *data, **opts)
   

def mrtg (style, interval, title, rrd_path, out_path) :
    return _graph(style, interval, title, mrtg_data, rrd_path, out_path)

def collectd_ifoctets (style, interval, title, rrd_path, out_path) :
    return _graph(style, interval, title, collectd_data, rrd_path, out_path)