Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bulkCmd : The value captured by bulkCmd quickly becomes smaller and then rapidly grows larger #124

Open
zqabc opened this issue Jan 8, 2018 · 2 comments
Labels

Comments

@zqabc
Copy link

zqabc commented Jan 8, 2018

We are using v4.3.2 and python version is 2.6.6.
In the process of using bulkCmd to capture data, sometimes the count becomes smaller and rapidly becomes larger (which is not the zero of the counter itself), but the data fetched from other software is normal (such as opennms).
For example, one of the error data is as follows (this is simply processed here, but out_flow is actually the original grabbing value):
vlan_name, time, in_flow, out_flow
Bundle-Ether9.3074,1515388256,60998572969479,5313014778254
Bundle-Ether9.3074,1515388556,60999118275580,5313105547239
Bundle-Ether9.3074,1515388856,60999658574281,965716331125
Bundle-Ether9.3074,1515389156,61000192612995,4824519220661
Bundle-Ether9.3074,1515389456,61000738613868,5264938818724
Bundle-Ether9.3074,1515389756,61001243383351,5308399139081

Bundle-Ether9.3074,1515390056,61001765154377,5313028574933
Bundle-Ether9.3074,1515390356,61002271785340,5313571239526

The above data is captured once every 5 minutes, and in_flow, out_flow is the value captured at that time. For example, at 1515388556, out_flow is 5313105547239, and at the next moment(1515388856), it quickly becomes smaller (965716331125) and then slowly recovers. This will have a relatively large peak, which leads to inaccuracy in bandwidth calculation.

I know that the switch counter itself will return to zero, but it is not caused by this.

So I want to know that it's my code error or the problem of the version or the other reasons?
Thanks

The code is like what is shown below:


class Flow_Processor(object):
    def get_flow_out_64(self, ip, community):
        value_list=[]
        has_err = False
        for errorIndication, \
        errorStatus, errorIndex, \
        varBinds in bulkCmd(SnmpEngine(),
                        CommunityData(community),
                        UdpTransportTarget((ip, 161)),
                        ContextData(),
                        0, 25,
                        ObjectType(ObjectIdentity('.1.3.6.1.2.1.31.1.1.1.10')),
                        lexicographicMode=False):

            if errorIndication:
                print(errorIndication)
                log.warning(' get_flow_out_64 errorIndication: %s',errorIndication)
                has_err = True
                break
            elif errorStatus:
                err_msg = '%s at %s' % (
                    errorStatus.prettyPrint(),
                    errorIndex and varBinds[int(errorIndex)-1][0] or '?'
                    )
                print(err_msg)
                log.warning(' get_flow_out_64 errorStatus: %s', err_msg)
                has_err = True
                break
            else:
                for varBind in varBinds:
                    line = (' = '.join([ x.prettyPrint() for x in varBind ]))
                    #line like this: SNMPv2-SMI::mib-2.31.1.1.1.11.145 = 659296
                    value = line.split('.')[-1]
                    value_list.append(value)

        return value_list, has_err
        
    def get_flow_in_64(self, ip, community):
        #print "I was at the get_flow_64! %s" %(ctime())
        value_list=[]
        has_err = False
        for errorIndication, \
        errorStatus, errorIndex, \
        varBinds in bulkCmd(SnmpEngine(),
                        CommunityData(community),
                        UdpTransportTarget((ip, 161)),
                        ContextData(),
                        0, 25,
                        ObjectType(ObjectIdentity('.1.3.6.1.2.1.31.1.1.1.6')),
                        #ObjectType(ObjectIdentity('.1.3.6.1.2.1.31.1.1.1.11')),
                        lexicographicMode=False):

            if errorIndication:
                print(errorIndication)
                log.warning(' get_flow_in_64 errorIndication: %s',errorIndication)
                has_err = True
                break
            elif errorStatus:
                err_msg = '%s at %s' % (
                    errorStatus.prettyPrint(),
                    errorIndex and varBinds[int(errorIndex) - 1][0] or '?'
                )
                print(err_msg)
                log.warning(' get_flow_in_64 errorStatus: %s', err_msg)
                has_err = True
                break
            else:
                for varBind in varBinds:
                    line = (' = '.join([ x.prettyPrint() for x in varBind ]))
                    #line like this: SNMPv2-SMI::mib-2.31.1.1.1.11.145 = 659296
                    value = line.split('.')[-1]
                    value_list.append(value)

        return value_list, has_err

    def get_ifDescr(self, ip, community):
        print "I was at the get_ifDescr! %s" %(ctime())        
        descr_dict = {}
        line =''
        i =0
        has_err = False
        for errorIndication, \
        errorStatus, errorIndex, \
        varBinds in bulkCmd(SnmpEngine(),
                        CommunityData(community),
                        UdpTransportTarget((ip, 161)),
                        ContextData(),
                        0, 25,
                        ObjectType(ObjectIdentity('.1.3.6.1.2.1.2.2.1.2')),
                       # ObjectType(ObjectIdentity('.1.3.6.1.2.1.2.2.1.3')),
                        lexicographicMode=False):

            if errorIndication:
                print(errorIndication)
                log.warning(' get_ifDescr errorIndication: %s', errorIndication)
                has_err = True
                break
            elif errorStatus:
                err_msg = '%s at %s' % (
                    errorStatus.prettyPrint(),
                    errorIndex and varBinds[int(errorIndex) - 1][0] or '?'
                )
                print(err_msg)
                log.warning(' get_ifDescr errorStatus: %s', err_msg)
                has_err = True
                break
            else:
                for varBind in varBinds:
                    #get ifDescr
                    line = (' = '.join([ x.prettyPrint() for x in varBind ]))
                    # line : SNMPv2-SMI::mib-2.2.2.1.2.151 = GigabitEthernet0/0/1/1.1094
                    # descr: 151 = GigabitEthernet0/0/1/1.1094
                    if_descr = line.split('= ')[-1]
                    #if len(if_descr.split('.')) ==2:
                        #vlan = if_descr.split('.')[-1]
                    flag = line.split('=')[0].split('.')[-1] 
                    descr_dict[flag] = if_descr
                    

        return descr_dict, has_err
@etingof
Copy link
Owner

etingof commented Jan 28, 2018

Your code looks good except a minor performance nitpick -- you should have a single persistent SnmpEngine object and pass it to all the SNMP calls.

The counters problem may have something to do with integer64 serialization (either your SNMP agent or underlying pyasn1 screws that up). To diagnose that it would be useful to either:

  • tcpdump/wireshark SNMP packets which contain that spikes
  • enable pysnmp debugging and pinpoint hex dump containing that spiking SNMP packets

To enable SNMP debugging you need to add this to your script:

from pysnmp import debug

debug.setLogger(debug.Debug('io', 'msgproc'))

@zqabc
Copy link
Author

zqabc commented Jan 29, 2018

Thank you very much.

I've added it.

Look forward to the problem again

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants