Ruby loop on arrayof hashes - how to add another entry to the hash

Hello,

I've burnt a few hours on this....

I want to ingest information via SNMP from a network switch. I have successfully configured logstash to grab these data, and now I want to do some filtering before firing it into ES. The input results in an array of hashes - example below. Because {balh}.ifAlias does not always contain a value, I want to update it with the value of {blah}.ifDescr when it does not. Could anybody help please?

I have the following Ruby so far:

ruby {
    code => "event.get('interfaces').each do |key,interface|
               if interface['iso.org.dod.internet.mgmt.mib-2.ifMIB.ifMIBObjects.ifXTable.ifXEntry.ifAlias'] == ''
                 ???
               end
             end"
  }

I'm not sure how I can update the value of {blah}.ifAlias if it is blank? Apologies I haven't put what I have tried so far, but this is one of those problems where I have tried about 50 different things and none have worked.

Any suggestions please? I've included an example input below:

 "interfaces" => [
        [ 0] {
                                                                                                "index" => "1",
                             "iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifOutDiscards" => 146096,
                                                                                        "ifAdminStatus" => "Up",
                "iso.org.dod.internet.mgmt.mib-2.ifMIB.ifMIBObjects.ifXTable.ifXEntry.ifHCOutUcastPkts" => 1297794267,
                             "iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifPhysAddress" => "fc:ec:da:04:de:21",
                 "iso.org.dod.internet.mgmt.mib-2.ifMIB.ifMIBObjects.ifXTable.ifXEntry.ifHCInUcastPkts" => 1726174182,
                                   "iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifIndex" => 1,
             "iso.org.dod.internet.mgmt.mib-2.ifMIB.ifMIBObjects.ifXTable.ifXEntry.ifHCInMulticastPkts" => 1628743,
                             "iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifAdminStatus" => 1,
                                     "iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifMtu" => 1518,
                   "iso.org.dod.internet.mgmt.mib-2.ifMIB.ifMIBObjects.ifXTable.ifXEntry.ifHCOutOctets" => 1046925983452,
                                                                                  "ifOperationalStatus" => "Up",
                              "iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifOperStatus" => 1,
                    "iso.org.dod.internet.mgmt.mib-2.ifMIB.ifMIBObjects.ifXTable.ifXEntry.ifHCInOctets" => 2205815878493,
                                   "iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifDescr" => "Slot: 0 Port: 1 Gigabit - Level",
                                "iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifInErrors" => 0,
            "iso.org.dod.internet.mgmt.mib-2.ifMIB.ifMIBObjects.ifXTable.ifXEntry.ifHCOutBroadcastPkts" => 10995020,
              "iso.org.dod.internet.mgmt.mib-2.ifMIB.ifMIBObjects.ifXTable.ifXEntry.ifConnectorPresent" => 1,
                              "iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifInDiscards" => 0,
                               "iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifOutErrors" => 0,
               "iso.org.dod.internet.mgmt.mib-2.ifMIB.ifMIBObjects.ifXTable.ifXEntry.ifPromiscuousMode" => 1,
                         "iso.org.dod.internet.mgmt.mib-2.ifMIB.ifMIBObjects.ifXTable.ifXEntry.ifAlias" => "",
             "iso.org.dod.internet.mgmt.mib-2.ifMIB.ifMIBObjects.ifXTable.ifXEntry.ifHCInBroadcastPkts" => 890065,
            "iso.org.dod.internet.mgmt.mib-2.ifMIB.ifMIBObjects.ifXTable.ifXEntry.ifHCOutMulticastPkts" => 2013721,
                                    "iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifType" => 6,
                                   "iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifSpeed" => 1000000000,
                              "iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifLastChange" => 564080300,
                     "iso.org.dod.internet.mgmt.mib-2.ifMIB.ifMIBObjects.ifXTable.ifXEntry.ifHighSpeed" => 1000
        },
        [...]
 ]

I have not tested it, but I would suggest...

code => "
    i = []
    event.get('interfaces').each do |key,interface|
        if interface['iso.org.dod.internet.mgmt.mib-2.ifMIB.ifMIBObjects.ifXTable.ifXEntry.ifAlias'] == ''
            interface['iso.org.dod.internet.mgmt.mib-2.ifMIB.ifMIBObjects.ifXTable.ifXEntry.ifAlias'] = interface['iso.org.dod.internet.mgmt.mib-2.ifMIB.ifMIBObjects.ifXTable.ifXEntry.ifDescr']
        end
        i << interface
    end
    event.set("interfaces", i)
"

Thanks Badger - that worked (with a tweak).

When I dropped that snippet into the conf file, is was getting the exception: Ruby exception occurred: undefined method []for nil:NilClass. I was getting this yesterday from time to time, but couldn't see the wood for the trees. I narrowed it down to be coming from the if statement, which I thought was weird. I removed the if and just tried outputting the variables key and interface, and found that the interface data was held in key. Removed key and its working now. So the filter is now:

ruby {
     41     code => " 
     42              i = []
     43              event.get('interfaces').each do |interface|
     45                if interface['iso.org.dod.internet.mgmt.mib-2.ifMIB.ifMIBObjects.ifXTable.ifXEntry.ifAlias'] == ''
     47                  interface['iso.org.dod.internet.mgmt.mib-2.ifMIB.ifMIBObjects.ifXTable.ifXEntry.ifAlias'] = interface['iso.org.dod.internet.mgmt.mib        -2.interfaces.ifTable.ifEntry.ifDescr']
     48                end
     49                i << interface
     50              end
     51              event.set('interfaces',i)"
     52   }

Thanks for the help!

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.