rrd로 트래픽수집을 하다보면 아래 그림처럼 갑자기 트래픽이 튀는 경우가 발생한다.



위와 같은 문제가 발생하면 rrd 디비를 dump -> 데이터수정 -> restore 를 해줘야 하는데 


상당히 귀찮은 작업이다.


그래서 스크립트 하나 만들어 봄...


1. rrd 파일을 xml 로 dump 를 받고

2. Param 으로 받은 시간대의 데이터를 0.0000000000e+00 으로 수정

3. 수정된 xml 로 restore 를 진행한다.


tip:

dump 이후에 수집된 데이터는 누락이 되는 문제가 있어 

dump 전/후 lastupdate 시간이 다를경우에 dump 후에 수집된 raw 데이터를 구하여 

update를 진행합니다. 


[root@new test]# /usr/local/python2.6/bin/python rrdmod.py -h

rrdmod.py [options]

Options:

-t, --time=<timestamp>   time format %Y%m%d%H or %Y%m%d

-f, --file=<filename>    rrd file name


코드는 아직 정리 전이라 보기에 좀 불편하겠지만 수정하여 다시 업데이트 할예정임...


import sys

import subprocess

import getopt

import datetime

import time

import re

import os


def get_rrd_lastinfo(rrd_file):

    last_time, last_input, last_output = None, None, None


    p = subprocess.Popen(

            ('rrdtool', 'lastupdate', rrd_file), stdout=subprocess.PIPE)

    out, err = p.communicate()

    for s in out.split("\n"):

        m = re.search(r"(\d+): (\d+) (\d+)", s)

        if m:

            last_time, last_input, last_output = m.groups()


    return last_time, last_input, last_output


def get_rrd_update_value(rrd_file, start_time, end_time, input, output):

    values = []

    p = subprocess.Popen(

        ('rrdtool', 'fetch', rrd_file, 'AVERAGE', '-s', start_time, '-e', end_time), stdout=subprocess.PIPE)

    out, err = p.communicate()

    for s in out.split("\n"):

        m = re.search(r"(\d+): ([\.e\+\-\d]+) ([\.e\+\-\d]+)", s)

        if m:

            last_time, last_input, last_output = m.groups()

            last_input = int(eval(last_input)*300)

            last_output = int(eval(last_output)*300)

            values.append((last_time,last_input, last_output))


    values.reverse()

    input = float(input)

    output = float(output)


    for n, v in enumerate(values):

        input -= v[1]

        output -= v[2]

        v = v + ("%d" % input,)

        v = v + ("%d" % output,)

        values[n] = v


    values.reverse()

    for v in values:

        print v

        subprocess.Popen(

            ('rrdtool', 'update', rrd_file, '%s:%s:%s' % (v[0], v[3], v[4])), stdout=subprocess.PIPE).communicate()


def modrrd(mod_time, rrd_file):

    """

    <!-- 2017-02-02 15:00:00 KST / 1486015200 --> <row><v>NaN</v><v>NaN</v></row>

    """

    pattern = re.compile(r" %s\s?[:\d]+ \w+ / (\d+) --> <row><v>(.*)</v><v>(.*)</v></row>" % mod_time)

    init_value = "0.0000000000e+00"


    last_update_time = get_rrd_lastinfo(rrd_file)[0]


    p1 = subprocess.Popen(

            ('rrdtool', 'dump', rrd_file), stdout=subprocess.PIPE)


    if os.path.exists('%s.new.rrd' % rrd_file):

        os.unlink('%s.new.rrd' % rrd_file)


    fp = open("%s.xml" % rrd_file, "a+")

    for num, line in enumerate(p1.stdout):

        matching = pattern.search(line)

        if matching:

            if len(matching.groups()) == 3:

                line = line.replace(matching.groups()[1], init_value).replace(matching.groups()[2], init_value)


        fp.write(line)

    fp.close()


    p2 = subprocess.Popen(

            ('rrdtool', 'restore', "%s.xml" % rrd_file, '%s.new.rrd' % rrd_file), stdout=subprocess.PIPE)


    out, err = p2.communicate()


    if os.path.exists("%s.xml" % rrd_file):

        os.unlink("%s.xml" % rrd_file)


    _last_update_time, _last_input, _last_output = get_rrd_lastinfo(rrd_file)


    if last_update_time != _last_update_time:

        get_rrd_update_value(rrd_file, last_update_time, _last_update_time, _last_input, _last_output)


def usage():

    print 'rrdmod.py [options]'

    print 'Options:'

    print '-t, --time=<timestamp>   time format %Y%m%d%H or %Y%m%d'

    print '-f, --file=<filename>    rrd file name'


def main():

    mod_time, rrd_file = None, None

    try:

        opts, args = getopt.getopt(sys.argv[1:],"ht:f:",["time=","file="])

    except getopt.GetoptError:

        usage()

        sys.exit(2)


    for opt, value in opts:

        if opt in ("-t", "--time"):

            mod_time = value

            if len(mod_time) == 10:

                mod_time = datetime.datetime.strptime(mod_time, '%Y%m%d%H')

                mod_time = mod_time.strftime("%Y-%m-%d %H")

            elif len(mod_time) == 8:

                mod_time = datetime.datetime.strptime(mod_time, '%Y%m%d')

                mod_time = mod_time.strftime("%Y-%m-%d")

            else:

                usage()

                sys.exit(2)


            # make timestamp

            #mod_time = time.mktime(mod_time.timetuple())


        elif opt in ("-f", "--file"):

             rrd_file = value

        elif opt == "-h":

            usage()

            sys.exit()


    if mod_time == None or rrd_file == None:

        usage()

        sys.exit()


    modrrd(mod_time, rrd_file)


if __name__ == "__main__":

    main()

'Python' 카테고리의 다른 글

sftpserver + pyotp  (0) 2017.03.08
Django + djangorestframework + django_rest_swagger 시작  (0) 2017.02.01
Pika Python AMQP Client Library  (0) 2017.01.31
s3 example  (0) 2016.12.28
daemonizing  (0) 2016.12.22

+ Recent posts