#!/usr/bin/env python # # Author: Vladislav Odintsov # # This script creates machine-readable output for OVS metrics # # Metrics values by columns: # 1: dpflows - dapath flows count in ovs-dpctl show output # 2: dphit - hits in cache (datapath) # 3: dpmiss - missed searches in cache (datapath) # 4: dploss - failed requests (datapath) # 5: ofports - datapath ports count # 6: mskhit - datapath mask hits # 7: mskmiss - datapath mask missed requests # 8: mskhitpkt - datapath mask hits/pkt # 9: usflows - userspace flows count import re import subprocess ovs_dpctl_show = ['ovs-dpctl', 'show'] ovs_ofctl_dump_aggregate = ['ovs-ofctl', 'dump-aggregate', 'c2nvp'] re_port = re.compile('\A(\w+) \d+: [\w-]+( \(.*\))?\Z') def get_data(cmd): p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) try: stdout, _ = p.communicate() except subprocess.CalledProcessError as e: raise Exception("Failed to run {0}".format(cmd)) try: return stdout.replace('\t', '').split('\n') except: raise Exception("Failed to parse stdout of {0}.".format(cmd)) def process_dp(data): res = {} # process datapath >>> dp = data[1].split(' ') res['dphit'] = dp[1].split(':')[1] res['dpmiss'] = dp[2].split(':')[1] res['dploss'] = dp[3].split(':')[1] # <<< process datapath # process flows >>> res['dpflows'] = data[2].split(': ')[1] # <<< process flows # process masks >>> masks = data[3].split(' ') res['mskhit'] = masks[1].split(':')[1] res['mskmiss'] = masks[2].split(':')[1] res['mskhtpkt'] = masks[3].split(':')[1] # <<< process masks # calculate openflow ports count >>> ofports = 0 for i in range(0, len(data)): m = re.match(re_port, data[i]) ofports = ofports + 1 if m and m.group(1) == 'port' else ofports res['ofports'] = ofports # <<< calculate openflow ports count return res def process_of(data): res = {} # process userspace flows >>> us = data[0].split(' ')[5] res['usflows'] = us.split('=')[1] # <<< process userspace flows return res def print_result(res): a = '' for k, v in res.iteritems(): a += "{k}: {v}\n".format(k=k, v=v) print(a) def main(): dp_data = get_data(ovs_dpctl_show) of_data = get_data(ovs_ofctl_dump_aggregate) result = process_dp(dp_data) result.update(process_of(of_data)) print_result(result) if __name__ == '__main__': main()