diff --git a/scripts/rpc.py b/scripts/rpc.py index 165312310..f328e8a03 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -2,6 +2,7 @@ from rpc.client import print_dict, JSONRPCException +import logging import argparse import rpc import sys @@ -27,8 +28,10 @@ if __name__ == "__main__": parser.add_argument('-t', dest='timeout', help='Timeout as a floating point number expressed in seconds waiting for response. Default: 60.0', default=60.0, type=float) - parser.add_argument('-v', dest='verbose', - help='Verbose mode', action='store_true') + parser.add_argument('-v', dest='verbose', action='store_const', const="INFO", + help='Set verbose mode to INFO', default="ERROR") + parser.add_argument('--verbose', dest='verbose', choices=['DEBUG', 'INFO', 'ERROR'], + help="""Set verbose level. """) subparsers = parser.add_subparsers(help='RPC methods') def start_subsystem_init(args): @@ -1735,7 +1738,7 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse args = parser.parse_args() try: - args.client = rpc.client.JSONRPCClient(args.server_addr, args.port, args.verbose, args.timeout) + args.client = rpc.client.JSONRPCClient(args.server_addr, args.port, args.timeout, log_level=getattr(logging, args.verbose.upper())) args.func(args) except JSONRPCException as ex: print("Exception:") diff --git a/scripts/rpc/client.py b/scripts/rpc/client.py index cfdba7d6b..c90fc185a 100644 --- a/scripts/rpc/client.py +++ b/scripts/rpc/client.py @@ -2,6 +2,7 @@ import json import socket import time import os +import logging def print_dict(d): @@ -14,31 +15,53 @@ class JSONRPCException(Exception): class JSONRPCClient(object): - def __init__(self, addr, port=None, verbose=False, timeout=60.0): + def __init__(self, addr, port=None, timeout=60.0, **kwargs): self.sock = None - self.verbose = verbose + ch = logging.StreamHandler() + ch.setFormatter(logging.Formatter('%(levelname)s: %(message)s')) + ch.setLevel(logging.DEBUG) + self._logger = logging.getLogger("JSONRPCClient(%s)" % addr) + self._logger.addHandler(ch) + self.set_log_level(kwargs.get('log_level', logging.ERROR)) + self.timeout = timeout self._request_id = 0 self._recv_buf = "" self._reqs = [] try: if os.path.exists(addr): + self._logger.debug("Trying to connect to UNIX socket: %s", addr) self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self.sock.connect(addr) elif ':' in addr: + self._logger.debug("Trying to connect to IPv6 address addr:%s, port:%i", addr, port) for res in socket.getaddrinfo(addr, port, socket.AF_INET6, socket.SOCK_STREAM, socket.SOL_TCP): af, socktype, proto, canonname, sa = res self.sock = socket.socket(af, socktype, proto) self.sock.connect(sa) else: + self._logger.debug("Trying to connect to IPv4 address addr:%s, port:%i'", addr, port) self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((addr, port)) except socket.error as ex: raise JSONRPCException("Error while connecting to %s\n" "Error details: %s" % (addr, ex)) + def get_logger(self): + return self._logger + + """Set logging level + + Args: + lvl: Log level to set as accepted by logger.setLevel + """ + def set_log_level(self, lvl): + self._logger.info("Setting log level to %s", lvl) + self._logger.setLevel(lvl) + self._logger.info("Log level set to %s", lvl) + def __del__(self): - if self.sock: + if getattr(self, "sock", None): self.sock.close() def send(self, method, params=None): @@ -52,21 +75,20 @@ class JSONRPCClient(object): if params: req['params'] = params - reqstr = json.dumps(req) - if self.verbose: - print("request:") - print(json.dumps(req, indent=2)) - + reqstr = json.dumps(req, indent=2) + self._logger.info("request:\n%s\n", reqstr) self.sock.sendall(reqstr.encode("utf-8")) return req def decode_one_response(self): try: + self._logger.debug("Trying to decode response '%s'", self._recv_buf) buf = self._recv_buf.lstrip() obj, idx = json.JSONDecoder().raw_decode(buf) self._recv_buf = buf[idx:] return obj except ValueError: + self._logger.debug("Partial response") return None def recv(self): @@ -91,10 +113,7 @@ class JSONRPCClient(object): if not response: raise JSONRPCException("Timeout while waiting for response:\n%s\n" % self._recv_buf) - if self.verbose: - print("response:") - print(json.dumps(response, indent=2)) - + self._logger.info("response:\n%s\n", json.dumps(response, indent=2)) if 'error' in response: msg = "\n".join(["Got JSON-RPC error response", "response:", @@ -103,12 +122,14 @@ class JSONRPCClient(object): return response def call(self, method, params=None): + self._logger.debug("call('%s')" % method) self.send(method, params) try: return self.recv()['result'] except JSONRPCException as e: """ Don't expect response to kill """ if not self.sock and method == "kill_instance": + self._logger.info("Connection terminated but ignoring since method is '%s'" % method) return {} else: raise e diff --git a/scripts/spdkcli/ui_root.py b/scripts/spdkcli/ui_root.py index e2bf080ad..38ad48c9a 100644 --- a/scripts/spdkcli/ui_root.py +++ b/scripts/spdkcli/ui_root.py @@ -57,9 +57,9 @@ class UIRoot(UINode): # Do not use for "get_*" methods so that output is not # flooded. def w(self, **kwargs): - self.client.verbose = self.verbose + self.client.set_log_level("INFO" if self.verbose else "ERROR") r = f(self, **kwargs) - self.client.verbose = False + self.client.set_log_level("ERROR") return r return w diff --git a/test/json_config/clear_config.py b/test/json_config/clear_config.py index d0bbf2ce4..decf3eae3 100755 --- a/test/json_config/clear_config.py +++ b/test/json_config/clear_config.py @@ -3,6 +3,7 @@ import os import sys import argparse +import logging sys.path.append(os.path.join(os.path.dirname(__file__), "../../scripts")) import rpc # noqa from rpc.client import print_dict, JSONRPCException # noqa @@ -178,7 +179,10 @@ if __name__ == "__main__": parser.add_argument('-s', dest='server_addr', default='/var/tmp/spdk.sock') parser.add_argument('-p', dest='port', default=5260, type=int) parser.add_argument('-t', dest='timeout', default=60.0, type=float) - parser.add_argument('-v', dest='verbose', action='store_true') + parser.add_argument('-v', dest='verbose', action='store_const', const="INFO", + help='Set verbose mode to INFO', default="ERROR") + parser.add_argument('--verbose', dest='verbose', choices=['DEBUG', 'INFO', 'ERROR'], + help="""Set verbose level. """) subparsers = parser.add_subparsers(help='RPC methods') @call_test_cmd @@ -206,7 +210,7 @@ if __name__ == "__main__": args = parser.parse_args() try: - args.client = rpc.client.JSONRPCClient(args.server_addr, args.port, args.verbose, args.timeout) + args.client = rpc.client.JSONRPCClient(args.server_addr, args.port, args.timeout, log_level=getattr(logging, args.verbose.upper())) except JSONRPCException as ex: print((ex.message)) exit(1)