1#! /usr/bin/env python 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright(c) 2018 Intel Corporation 4 5from __future__ import print_function 6from __future__ import unicode_literals 7 8import socket 9import os 10import sys 11import time 12 13BUFFER_SIZE = 200000 14 15METRICS_REQ = "{\"action\":0,\"command\":\"ports_all_stat_values\",\"data\":null}" 16API_REG = "{\"action\":1,\"command\":\"clients\",\"data\":{\"client_path\":\"" 17API_UNREG = "{\"action\":2,\"command\":\"clients\",\"data\":{\"client_path\":\"" 18GLOBAL_METRICS_REQ = "{\"action\":0,\"command\":\"global_stat_values\",\"data\":null}" 19DEFAULT_FP = "/var/run/dpdk/default_client" 20 21try: 22 raw_input # Python 2 23except NameError: 24 raw_input = input # Python 3 25 26if sys.version_info.major < 3: 27 print("WARNING: Python 2 is deprecated for use in DPDK, and will not work in future releases.", file=sys.stderr) 28 print("Please use Python 3 instead", file=sys.stderr) 29 30class Socket: 31 32 def __init__(self): 33 self.send_fd = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET) 34 self.recv_fd = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET) 35 self.client_fd = None 36 37 def __del__(self): 38 try: 39 self.send_fd.close() 40 self.recv_fd.close() 41 self.client_fd.close() 42 except: 43 print("Error - Sockets could not be closed") 44 45class Client: 46 47 def __init__(self): # Creates a client instance 48 self.socket = Socket() 49 self.file_path = None 50 self.choice = None 51 self.unregistered = 0 52 53 def __del__(self): 54 try: 55 if self.unregistered == 0: 56 self.unregister(); 57 except: 58 print("Error - Client could not be destroyed") 59 60 def getFilepath(self, file_path): # Gets arguments from Command-Line and assigns to instance of client 61 self.file_path = file_path 62 63 def register(self): # Connects a client to DPDK-instance 64 if os.path.exists(self.file_path): 65 os.unlink(self.file_path) 66 try: 67 self.socket.recv_fd.bind(self.file_path) 68 except socket.error as msg: 69 print ("Error - Socket binding error: " + str(msg) + "\n") 70 self.socket.recv_fd.settimeout(2) 71 self.socket.send_fd.connect("/var/run/dpdk/rte/telemetry") 72 JSON = (API_REG + self.file_path + "\"}}") 73 self.socket.send_fd.sendall(JSON.encode()) 74 75 self.socket.recv_fd.listen(1) 76 self.socket.client_fd = self.socket.recv_fd.accept()[0] 77 78 def unregister(self): # Unregister a given client 79 self.socket.client_fd.send((API_UNREG + self.file_path + "\"}}").encode()) 80 self.socket.client_fd.close() 81 82 def requestMetrics(self): # Requests metrics for given client 83 self.socket.client_fd.send(METRICS_REQ.encode()) 84 data = self.socket.client_fd.recv(BUFFER_SIZE).decode() 85 print("\nResponse: \n", data) 86 87 def repeatedlyRequestMetrics(self, sleep_time): # Recursively requests metrics for given client 88 print("\nPlease enter the number of times you'd like to continuously request Metrics:") 89 n_requests = int(raw_input("\n:")) 90 print("\033[F") #Removes the user input from screen, cleans it up 91 print("\033[K") 92 for i in range(n_requests): 93 self.requestMetrics() 94 time.sleep(sleep_time) 95 96 def requestGlobalMetrics(self): #Requests global metrics for given client 97 self.socket.client_fd.send(GLOBAL_METRICS_REQ.encode()) 98 data = self.socket.client_fd.recv(BUFFER_SIZE).decode() 99 print("\nResponse: \n", data) 100 101 def interactiveMenu(self, sleep_time): # Creates Interactive menu within the script 102 while self.choice != 4: 103 print("\nOptions Menu") 104 print("[1] Send for Metrics for all ports") 105 print("[2] Send for Metrics for all ports recursively") 106 print("[3] Send for global Metrics") 107 print("[4] Unregister client") 108 109 try: 110 self.choice = int(raw_input("\n:")) 111 print("\033[F") #Removes the user input for screen, cleans it up 112 print("\033[K") 113 if self.choice == 1: 114 self.requestMetrics() 115 elif self.choice == 2: 116 self.repeatedlyRequestMetrics(sleep_time) 117 elif self.choice == 3: 118 self.requestGlobalMetrics() 119 elif self.choice == 4: 120 self.unregister() 121 self.unregistered = 1 122 else: 123 print("Error - Invalid request choice") 124 except: 125 pass 126 127if __name__ == "__main__": 128 129 sleep_time = 1 130 file_path = "" 131 if (len(sys.argv) == 2): 132 file_path = sys.argv[1] 133 else: 134 print("Warning - No filepath passed, using default (" + DEFAULT_FP + ").") 135 file_path = DEFAULT_FP 136 client = Client() 137 client.getFilepath(file_path) 138 client.register() 139 client.interactiveMenu(sleep_time) 140