예제 #1
0
def graph(rrd, back=86400, title="", width=400, height=100):
    """ Make an RRD graph. The caller is responsible for
    deleting the returned path """

    tfile, tpath = tempfile.mkstemp(".gif", "oh")
    os.close(tfile)

    RRD.graph(
        tpath,
        "--start",
        "-" + str(back),
        "--title",
        title,
        "-w",
        str(width),
        "-h",
        str(height),
        "-c",
        "SHADEB#FFFFFF",
        "-c",
        "SHADEA#FFFFFF",
        "DEF:in=%s:in:AVERAGE" % rrd,
        "DEF:out=%s:out:AVERAGE" % rrd,
        "CDEF:inbits=in,8,*",
        "CDEF:outbits=out,8,*",
        'AREA:inbits#00FF00:"bps in"',
        'LINE1:outbits#0000FF:"bps out"',
    )

    return tpath
예제 #2
0
def graph(rrd, back=86400, title='', width=400, height=100):
    """ Make an RRD graph. The caller is responsible for
    deleting the returned path """

    tfile, tpath = tempfile.mkstemp('.gif', 'oh')
    os.close(tfile)

    RRD.graph(tpath, '--start', '-' + str(back), '--title', title, '-w',
              str(width), '-h', str(height), '-c', 'SHADEB#FFFFFF', '-c',
              'SHADEA#FFFFFF', 'DEF:in=%s:in:AVERAGE' % rrd,
              'DEF:out=%s:out:AVERAGE' % rrd, 'CDEF:inbits=in,8,*',
              'CDEF:outbits=out,8,*', 'AREA:inbits#00FF00:"bps in"',
              'LINE1:outbits#0000FF:"bps out"')

    return tpath
예제 #3
0
def uptime(req, s='-2592000'): # 30 days

    args = ['/dev/null', '--start', s,
            '--width=500'] # bizzare, but we need --width to match

    rrds = _list_server_rrds()

    # list of rrds, each like
    # 'DEF:s0=/var/db/openvps/iad01-06-04-01.openvps.net-uptime.rrd:admin_uptime:AVERAGE',

    for n in xrange(len(rrds)):
        args.append('DEF:s%d=%s:admin_uptime:AVERAGE' % (n, rrds[n]))

    # now the tricky part - construct sum in RPN
    #'CDEF:avg=s0,s1,+,s2,+,s3,+,s4,+,s5,+,s6,+,s7,+,8,/',

    rpn = ['s0']
    for n in xrange(1, len(rrds)):
        rpn.append('s%d' % n)
        rpn.append('+')
    rpn.append('%d' % len(rrds))
    rpn.append('/')

    args.append('CDEF:avg=' + (','.join(rpn)))
    
    # the average
    args.append('VDEF:tot_avg=avg,AVERAGE')

    # the output
    args.append('PRINT:tot_avg:"average uptime\\: %9.6lf"')

    uptime = RRD.graph(*args)[2][0][1:-1]

    #req.log_error(`args`)

    return uptime
예제 #4
0
def disk(req, name, params):

    if params.startswith('graph'):

        if not req.args:
            return error(req, 'Not sure what you mean')

        qargs = util.parse_qs(req.args)
        
        if not qargs.has_key('s'):
            return error(req, 'Where do I start?')

        start = '-'+qargs['s'][0]
        width = 484
        height = 70
        nolegend = ''
        if qargs.has_key('l'):
            nolegend = '-g'  # no legend

        # how many days back?
        secs = abs(int(start))
        if secs < 60*60*24:
            # we're talking hours
            title = 'last %d hours' % (secs/(60*60))
        else:
            title = 'last %d days' % (secs/(60*60*24))

        rrd = os.path.join(cfg.VAR_DB_OPENVPS, 'vsmon/%s.rrd' % name)
        tfile, tpath = tempfile.mkstemp('.gif', 'oh')
        os.close(tfile)

        args = [tpath, '--start', start,
                '--title', title,
                '-w', str(width),
                '-h', str(height),
                '-c', 'SHADEB#FFFFFF',
                '-c', 'SHADEA#FFFFFF',
                '-l', '0',
                'DEF:d=%s:vs_disk_b_used:AVERAGE' % rrd,
                'CDEF:db=d,1024,*',
                'AREA:db#4eee94:bytes used']

        if qargs.has_key('l'):
            args.append('-g')  # no legend
        
        RRD.graph(*args)
        
        req.content_type = 'image/gif'
        req.sendfile(tpath)
        os.unlink(tpath)
        
        return apache.OK

    else:

        location = 'stats:disk'

        body_tmpl = _tmpl_path('disk_body.html')

        rrd = os.path.join(cfg.VAR_DB_OPENVPS, 'vsmon/%s.rrd' % name)
        data = _load_rrd_data(rrd, ['vs_disk_b_used'])

        body_vars = {'data':data}

        vars = {'global_menu': _global_menu(req, name, location),
                'body':psp.PSP(req, body_tmpl, vars=body_vars),
                'name':name}

        p = psp.PSP(req, _tmpl_path('main_frame.html'),
                    vars=vars)

        p.run()

        return apache.OK
예제 #5
0
def graph(req, name, command):

    if not req.args:
        return error(req, 'Not sure what you mean')

    qargs = util.parse_qs(req.args)
        
    if not qargs.has_key('s'):
        return error(req, 'Where do I start?')
    start = '-'+qargs['s'][0]

    # exclude these vps's
    exclude = []
    if qargs.has_key('exclude'):
        exclude = qargs['exclude'][0].split()

    # limit to only these vps's
    limit = []
    if qargs.has_key('limit'):
        limit = qargs['limit'][0].split()

    width = 600
    if qargs.has_key('w'):
        width = int(qargs['w'][0])

    height = 400
    if qargs.has_key('h'):
        height = int(qargs['h'][0])

    # how many days back?
    secs = abs(int(start))
    if secs < 60*60*24:
        # we're talking hours
        title = 'last %d hours' % (secs/(60*60))
    else:
        title = 'last %d days' % (secs/(60*60*24))

    if command in ['bwidth', 'mem']:
        # here we need to draw a nice little graph....

        tfile, tpath = tempfile.mkstemp('.gif', 'oh')
        os.close(tfile)

        args = [tpath, '--start', start,
                '--title', title,
                '-w', str(width),
                '-h', str(height),
                '-c', 'SHADEB#FFFFFF',
                '-c', 'SHADEA#FFFFFF',
                '-l', '0']

        if qargs.has_key('l'):
            args.append('-g')  # no legend
        
        # list vservers
        vservers = vsutil.list_vservers()
        keys = vservers.keys()

        # assign colors
        colors = {}
        ci = 0
        for vs in keys:
            colors[vs.replace('-', '')] = COLORS[ci]
            ci += 1

        # process limit and exclude
        if limit:
            keys = [k for k in keys if k in limit]
        keys = [k for k in keys if k not in exclude]

        # we only have so many colors
        if len(keys) > len(COLORS):
            return error(req, 'Not enough colors for VPSs, exclude some:\n%s' % `keys`)

        keys.sort()

        for vs in keys:

            rrd = os.path.join(cfg.VAR_DB_OPENVPS, 'vsmon/%s.rrd' % vs)

            vs = vs.replace('-', '') # rrdtool does not like dashes

            if command == 'bwidth':

                args = args + [
                    'DEF:%s_in=%s:vs_in:AVERAGE' % (vs, rrd),
                    'DEF:%s_out=%s:vs_out:AVERAGE' % (vs, rrd),
                    'CDEF:%s_inb=%s_in,-8,*' % (vs, vs),
                    'CDEF:%s_outb=%s_out,8,*' % (vs, vs) ]
                
            elif command == 'mem':

                args = args + [
                    'DEF:%s_vm=%s:vs_vm:AVERAGE' % (vs, rrd),
                    'DEF:%s_rss=%s:vs_rss:AVERAGE' % (vs, rrd),
                    'CDEF:%s_vmb=%s_vm,1024,*' % (vs, vs),
                    'CDEF:%s_rssb=%s_rss,1024,*' % (vs, vs),
                    'CDEF:%s_rssbg=%s_rss,-1024,*' % (vs, vs),
                    ]

        if command == 'bwidth':

            # incoming
            vs = keys[0].replace('-', '')
            args = args + [
                'AREA:%s_outb#%s:%s bps out' % (vs, colors[vs], vs.ljust(10)),
                'GPRINT:%s_inb:MAX:Max IN\\: %%8.2lf%%s' % (vs, ),
                'GPRINT:%s_inb:AVERAGE:Avg IN\\: %%8.2lf%%s' % (vs, ),
                'GPRINT:%s_outb:MAX:Max OUT\\: %%8.2lf%%s' % (vs, ),
                'GPRINT:%s_outb:AVERAGE:Avg OUT\\: %%8.2lf%%s\\n' % (vs, )
                ]

            for vs in keys[1:]:
                vs = vs.replace('-', '')
                args = args + [
                    'STACK:%s_outb#%s:%s bps out' % (vs, colors[vs], vs.ljust(10)),
                    'GPRINT:%s_inb:MAX:Max IN\\: %%8.2lf%%s' % (vs, ),
                    'GPRINT:%s_inb:AVERAGE:Avg IN\\: %%8.2lf%%s' % (vs, ),
                    'GPRINT:%s_outb:MAX:Max OUT\\: %%8.2lf%%s' % (vs, ),
                    'GPRINT:%s_outb:AVERAGE:Avg OUT\\: %%8.2lf%%s\\n' % (vs, )
                    ]

            # outgoing
            keys.reverse()
            vs = keys[0].replace('-', '')
            args = args + [
                'AREA:%s_inb#%s::' % (vs, colors[vs]),
                ]

            for vs in keys[1:]:
                vs = vs.replace('-', '')
                args = args + [
                    'STACK:%s_inb#%s::' % (vs, colors[vs]),
                    ]

        elif command == 'mem':

            # rss (displayed at bottom)
            vs = keys[0].replace('-', '')
            args = args + [
                'AREA:%s_rssbg#%s:%s RSS bytes' % (vs, colors[vs], vs.ljust(10)),
                'GPRINT:%s_rssb:MAX:Max RSS\\: %%8.2lf%%s' % (vs, ),
                'GPRINT:%s_rssb:AVERAGE:Avg RSS\\: %%8.2lf%%s' % (vs, ),
                'GPRINT:%s_vmb:MAX:Max VM\\: %%8.2lf%%s' % (vs, ),
                'GPRINT:%s_vmb:AVERAGE:Avg VM\\: %%8.2lf%%s\\n' % (vs, )
                ]

            for vs in keys[1:]:
                vs = vs.replace('-', '')
                args = args + [
                    'STACK:%s_rssbg#%s:%s RSS bytes' % (vs, colors[vs], vs.ljust(10)),
                    'GPRINT:%s_rssb:MAX:Max RSS\\: %%8.2lf%%s' % (vs, ),
                    'GPRINT:%s_rssb:AVERAGE:Avg RSS\\: %%8.2lf%%s' % (vs, ),
                    'GPRINT:%s_vmb:MAX:Max VM\\: %%8.2lf%%s' % (vs, ),
                    'GPRINT:%s_vmb:AVERAGE:Avg VM\\: %%8.2lf%%s\\n' % (vs, )
                    ]
            # vm
            keys.reverse()
            vs = keys[0].replace('-', '')
            args = args + [
                'AREA:%s_vmb#%s::' % (vs, colors[vs]),
                ]

            for vs in keys[1:]:
                vs = vs.replace('-', '')
                args = args + [
                    'STACK:%s_vmb#%s::' % (vs, colors[vs]),
                    ]

        RRD.graph(*args)
        
        req.content_type = 'image/gif'
        req.sendfile(tpath)
        os.unlink(tpath)
        
        return apache.OK
    else:
        return error(req, 'request not understood')
예제 #6
0
def uptime_graph(req, s='-2592000'): # 30 days

    # generate a temporary path
    tfile, tpath = tempfile.mkstemp('.png', 'ova')
    os.close(tfile)

    args = [tpath, '--start', s, '--imgformat=PNG', '--width=600',
            '--base=1000', '--height=120', '--interlaced',
            '--lower-limi', '80',
            '--upper-limit', '101', '--rigid']

    rrds = _list_server_rrds()

    # list of rrds, each like
    # 'DEF:s0=/var/db/openvps/iad01-06-04-01.openvps.net-uptime.rrd:admin_uptime:AVERAGE',

    for n in xrange(len(rrds)):
        args.append('DEF:s%d=%s:admin_uptime:AVERAGE' % (n, rrds[n]))

    # now the tricky part - construct sum in RPN
    #'CDEF:avg=s0,s1,+,s2,+,s3,+,s4,+,s5,+,s6,+,s7,+,8,/',

    rpn = ['s0']
    for n in xrange(1, len(rrds)):
        rpn.append('s%d' % n)
        rpn.append('+')
    rpn.append('%d' % len(rrds))
    rpn.append('/')

    args.append('CDEF:avg=' + (','.join(rpn)))
    
    # the average
    args.append('VDEF:tot_avg=avg,AVERAGE')

    trend = 60*60*24*7 # 7 days

    # trended average
    args.append('CDEF:tavg=avg,%d,TREND' % trend)

    degr = '99.99'
    
    # degraded - anything less than 99.99%
    args.append('CDEF:degr=avg,%s,GE,0,INF,IF' % degr)
    
    # degraded shade
    args.append('AREA:degr#ffff99:degraded\\n')

    # tranded average
    args.append('LINE2:tavg#0000FF:%d day moving average\\n' % (trend / (60*60*24)))
                
    # real uptime
    args.append('LINE:avg#00FF00:simple average\\n')
                
    # the output
    args.append('COMMENT:\\n')
    args.append('GPRINT:tot_avg:Last %d Day Average\\: %%9.6lf\\n' % (abs(int(s)) / (60*60*24)))

    # run it
    RRD.graph(*args)

    req.content_type = 'image/png'
    req.sendfile(tpath)
    os.unlink(tpath)
                            
    return 
예제 #7
0
def disk(req, name, params):

    if params.startswith('graph'):

        if not req.args:
            return error(req, 'Not sure what you mean')

        qargs = util.parse_qs(req.args)

        if not qargs.has_key('s'):
            return error(req, 'Where do I start?')

        start = '-' + qargs['s'][0]
        width = 484
        height = 70
        nolegend = ''
        if qargs.has_key('l'):
            nolegend = '-g'  # no legend

        # how many days back?
        secs = abs(int(start))
        if secs < 60 * 60 * 24:
            # we're talking hours
            title = 'last %d hours' % (secs / (60 * 60))
        else:
            title = 'last %d days' % (secs / (60 * 60 * 24))

        rrd = os.path.join(cfg.VAR_DB_OPENVPS, 'vsmon/%s.rrd' % name)
        tfile, tpath = tempfile.mkstemp('.gif', 'oh')
        os.close(tfile)

        args = [
            tpath, '--start', start, '--title', title, '-w',
            str(width), '-h',
            str(height), '-c', 'SHADEB#FFFFFF', '-c', 'SHADEA#FFFFFF', '-l',
            '0',
            'DEF:d=%s:vs_disk_b_used:AVERAGE' % rrd, 'CDEF:db=d,1024,*',
            'AREA:db#4eee94:bytes used'
        ]

        if qargs.has_key('l'):
            args.append('-g')  # no legend

        RRD.graph(*args)

        req.content_type = 'image/gif'
        req.sendfile(tpath)
        os.unlink(tpath)

        return apache.OK

    else:

        location = 'stats:disk'

        body_tmpl = _tmpl_path('disk_body.html')

        rrd = os.path.join(cfg.VAR_DB_OPENVPS, 'vsmon/%s.rrd' % name)
        data = _load_rrd_data(rrd, ['vs_disk_b_used'])

        body_vars = {'data': data}

        vars = {
            'global_menu': _global_menu(req, name, location),
            'body': psp.PSP(req, body_tmpl, vars=body_vars),
            'name': name
        }

        p = psp.PSP(req, _tmpl_path('main_frame.html'), vars=vars)

        p.run()

        return apache.OK
예제 #8
0
def graph(req, name, command):

    if not req.args:
        return error(req, 'Not sure what you mean')

    qargs = util.parse_qs(req.args)

    if not qargs.has_key('s'):
        return error(req, 'Where do I start?')
    start = '-' + qargs['s'][0]

    # exclude these vps's
    exclude = []
    if qargs.has_key('exclude'):
        exclude = qargs['exclude'][0].split()

    # limit to only these vps's
    limit = []
    if qargs.has_key('limit'):
        limit = qargs['limit'][0].split()

    width = 600
    if qargs.has_key('w'):
        width = int(qargs['w'][0])

    height = 400
    if qargs.has_key('h'):
        height = int(qargs['h'][0])

    # how many days back?
    secs = abs(int(start))
    if secs < 60 * 60 * 24:
        # we're talking hours
        title = 'last %d hours' % (secs / (60 * 60))
    else:
        title = 'last %d days' % (secs / (60 * 60 * 24))

    if command in ['bwidth', 'mem']:
        # here we need to draw a nice little graph....

        tfile, tpath = tempfile.mkstemp('.gif', 'oh')
        os.close(tfile)

        args = [
            tpath, '--start', start, '--title', title, '-w',
            str(width), '-h',
            str(height), '-c', 'SHADEB#FFFFFF', '-c', 'SHADEA#FFFFFF', '-l',
            '0'
        ]

        if qargs.has_key('l'):
            args.append('-g')  # no legend

        # list vservers
        vservers = vsutil.list_vservers()
        keys = vservers.keys()

        # assign colors
        colors = {}
        ci = 0
        for vs in keys:
            colors[vs.replace('-', '')] = COLORS[ci]
            ci += 1

        # process limit and exclude
        if limit:
            keys = [k for k in keys if k in limit]
        keys = [k for k in keys if k not in exclude]

        # we only have so many colors
        if len(keys) > len(COLORS):
            return error(
                req,
                'Not enough colors for VPSs, exclude some:\n%s' % ` keys `)

        keys.sort()

        for vs in keys:

            rrd = os.path.join(cfg.VAR_DB_OPENVPS, 'vsmon/%s.rrd' % vs)

            vs = vs.replace('-', '')  # rrdtool does not like dashes

            if command == 'bwidth':

                args = args + [
                    'DEF:%s_in=%s:vs_in:AVERAGE' % (vs, rrd),
                    'DEF:%s_out=%s:vs_out:AVERAGE' % (vs, rrd),
                    'CDEF:%s_inb=%s_in,-8,*' % (vs, vs),
                    'CDEF:%s_outb=%s_out,8,*' % (vs, vs)
                ]

            elif command == 'mem':

                args = args + [
                    'DEF:%s_vm=%s:vs_vm:AVERAGE' % (vs, rrd),
                    'DEF:%s_rss=%s:vs_rss:AVERAGE' % (vs, rrd),
                    'CDEF:%s_vmb=%s_vm,1024,*' % (vs, vs),
                    'CDEF:%s_rssb=%s_rss,1024,*' % (vs, vs),
                    'CDEF:%s_rssbg=%s_rss,-1024,*' % (vs, vs),
                ]

        if command == 'bwidth':

            # incoming
            vs = keys[0].replace('-', '')
            args = args + [
                'AREA:%s_outb#%s:%s bps out' % (vs, colors[vs], vs.ljust(10)),
                'GPRINT:%s_inb:MAX:Max IN\\: %%8.2lf%%s' % (vs, ),
                'GPRINT:%s_inb:AVERAGE:Avg IN\\: %%8.2lf%%s' % (vs, ),
                'GPRINT:%s_outb:MAX:Max OUT\\: %%8.2lf%%s' % (vs, ),
                'GPRINT:%s_outb:AVERAGE:Avg OUT\\: %%8.2lf%%s\\n' % (vs, )
            ]

            for vs in keys[1:]:
                vs = vs.replace('-', '')
                args = args + [
                    'STACK:%s_outb#%s:%s bps out' %
                    (vs, colors[vs], vs.ljust(10)),
                    'GPRINT:%s_inb:MAX:Max IN\\: %%8.2lf%%s' % (vs, ),
                    'GPRINT:%s_inb:AVERAGE:Avg IN\\: %%8.2lf%%s' % (vs, ),
                    'GPRINT:%s_outb:MAX:Max OUT\\: %%8.2lf%%s' % (vs, ),
                    'GPRINT:%s_outb:AVERAGE:Avg OUT\\: %%8.2lf%%s\\n' % (vs, )
                ]

            # outgoing
            keys.reverse()
            vs = keys[0].replace('-', '')
            args = args + [
                'AREA:%s_inb#%s::' % (vs, colors[vs]),
            ]

            for vs in keys[1:]:
                vs = vs.replace('-', '')
                args = args + [
                    'STACK:%s_inb#%s::' % (vs, colors[vs]),
                ]

        elif command == 'mem':

            # rss (displayed at bottom)
            vs = keys[0].replace('-', '')
            args = args + [
                'AREA:%s_rssbg#%s:%s RSS bytes' %
                (vs, colors[vs], vs.ljust(10)),
                'GPRINT:%s_rssb:MAX:Max RSS\\: %%8.2lf%%s' % (vs, ),
                'GPRINT:%s_rssb:AVERAGE:Avg RSS\\: %%8.2lf%%s' % (vs, ),
                'GPRINT:%s_vmb:MAX:Max VM\\: %%8.2lf%%s' % (vs, ),
                'GPRINT:%s_vmb:AVERAGE:Avg VM\\: %%8.2lf%%s\\n' % (vs, )
            ]

            for vs in keys[1:]:
                vs = vs.replace('-', '')
                args = args + [
                    'STACK:%s_rssbg#%s:%s RSS bytes' %
                    (vs, colors[vs], vs.ljust(10)),
                    'GPRINT:%s_rssb:MAX:Max RSS\\: %%8.2lf%%s' % (vs, ),
                    'GPRINT:%s_rssb:AVERAGE:Avg RSS\\: %%8.2lf%%s' % (vs, ),
                    'GPRINT:%s_vmb:MAX:Max VM\\: %%8.2lf%%s' % (vs, ),
                    'GPRINT:%s_vmb:AVERAGE:Avg VM\\: %%8.2lf%%s\\n' % (vs, )
                ]
            # vm
            keys.reverse()
            vs = keys[0].replace('-', '')
            args = args + [
                'AREA:%s_vmb#%s::' % (vs, colors[vs]),
            ]

            for vs in keys[1:]:
                vs = vs.replace('-', '')
                args = args + [
                    'STACK:%s_vmb#%s::' % (vs, colors[vs]),
                ]

        RRD.graph(*args)

        req.content_type = 'image/gif'
        req.sendfile(tpath)
        os.unlink(tpath)

        return apache.OK
    else:
        return error(req, 'request not understood')