Skip to content

How to gather metrics with less complexity? #2

@hanynowsky

Description

@hanynowsky

Hello,
As you can see in the following example, it's very expensive to get metrics with less complexity.

def masac_poller(device_type, timeout, retries, sqlitedbtable, banned):
    """ Fetch SNMP metrics using fastsnmp module and send them to Carbon server  """
    # oids in group must be with same indexes
    oid_group_main = {"1.3.6.1.2.1.2.2.1.2": "ifDescr", "1.3.6.1.2.1.2.2.1.10": "ifInOctets","1.3.6.1.2.1.2.2.1.16": "ifOutOctets",}
    oid_group_in = {"1.3.6.1.2.1.2.2.1.10": "ifInOctets",}
    oid_group_out = {"1.3.6.1.2.1.2.2.1.16": "ifOutOctets",}
    oid_group = {"1.3.6.1.2.1.2.2.1.2": "ifDescr",}
    tags = ("Vlan","unrouted","thernet")
    if_desc_in = 'ifHCInOctets'
    if_desc_out = 'ifHCOutOctets'
    node = platform.node().replace('.', '-')
    DELAY = 1
    count = 0
    for h in get_db_device_list(sqlitedbtable, device_type, banned):
        timestamp = int(time.time()) # TODO Rather put timestamp inside the loop
        ###### Form a list of Interfaces and their indexes for a given DEVICE
        hostnames = []
        hostnames.append(h['ip'])
        interfaces = []
        e = {}
        snmp_data = snmp_poller.poller(hostnames, (oid_group.keys(),), h['snmp_community'], 2, 0)
        if len(list(snmp_data)) < 1 or h['snmp_community'] == '':
            update_device_in_db(sqlitedbtable, h['login'], device_type, 1)
            print("Banned " + h['ip'])
            continue
        snmp_data = snmp_poller.poller(hostnames, (oid_group.keys(),), h['snmp_community'], int(timeout), int(retries))
        for d in snmp_data:
                #print("host=%s oid=%s.%s value=%s" % (d[0], oid_group[d[1]], d[2], d[3]))
            e = {'hostname':h['login'], 'device':d[0],'index':d[2], 'interface':d[3]}
            interfaces.append(e)
        # Form a list of OUT metrics
        outoctets = []
        e = {}
        snmp_data = snmp_poller.poller(hostnames, (oid_group_out.keys(),), h['snmp_community'], int(timeout), int(retries))
        for d in snmp_data:
            e = {'device':d[0],'index':d[2], 'outoctets':d[3]}
            outoctets.append(e)
        ###### Form a list of IN metrics for Interfaces and their indexes for a given DEVICE
        inoctets = []
        e = {}
        snmp_data = snmp_poller.poller(hostnames, (oid_group_in.keys(),), h['snmp_community'], int(timeout), int(retries))
        for d in snmp_data:
            e = {'device':d[0],'index':d[2], 'inoctets':d[3]}
            inoctets.append(e)

        hostnames.pop() # Put that the last

        # now form a coupling list
        metrics = []
        e= {}
        for interface in interfaces:
            for inoctet in inoctets:
                for outoctet in outoctets:
                    if  interface['index'] == inoctet['index'] and interface['index'] == outoctet['index']:
                        e= {'hostname':interface['hostname'], 'device':interface['device'], 'index':interface['index'], 'interface':interface['interface'], 'inoctets':inoctet['inoctets'], 'outoctets':outoctet['outoctets']}
                        if tags[2] in e['interface'] and tags[0] not in e['interface'] and tags[1] not in e['interface']:
                            metrics.append(e)
        print("Processing: " + h['ip'])
        lines= []
        for ob in metrics:
            identifier = ob['hostname'].replace(".","_")
            if device_type == 'sdsl':
                identifier = str(ob['hostname'].replace(".","_").replace("@","_at_")) + "_" +h['ip'].replace(".","_")
            line_in = 'masac.test.%s.%s.%s %d %d' % (identifier, ob['interface'].replace("/","_").replace(" ","_"), if_desc_in, ob['inoctets'], timestamp)
            line_out = 'masac.test.%s.%s.%s %d %d' % (identifier, ob['interface'].replace("/","_").replace(" ","_"), if_desc_out, ob['outoctets'], timestamp)
            lines.append(line_in)                   
            lines.append(line_out)                  
        message = '\n'.join(lines) + '\n'
        sock = socket.socket()
        #sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect((CARBON_SERVER, CARBON_PORT))
        sock.sendall(message.encode('UTF-8'))
        sock.close()
        #print(message)     
        count = count + 1
    time.sleep(int(DELAY))
    return count
  • The CPU overhead is due to this snippet, I presume:
metrics = []
        e= {}
        for interface in interfaces:
            for inoctet in inoctets:
                for outoctet in outoctets:
                    if  interface['index'] == inoctet['index'] and interface['index'] == outoctet['index']:
                        e= {'hostname':interface['hostname'], 'device':interface['device'], 'index':interface['index'], 'interface':interface['interface'], 'inoctets':inoctet['inoctets'], 'outoctets':outoctet['outoctets']}
                        if tags[2] in e['interface'] and tags[0] not in e['interface'] and tags[1] not in e['interface']:
                            metrics.append(e)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions