rpc: extend logging in JSONRPCClient class
Add extra long argument '--verbose <VERBOSE LEVEL>' to add more log levels Default is error. Legacy'-v' parameter is translated into INFO log level. Some parts of code are logged using DEBUG level. Change-Id: I2aaa6e2fbaf9b2101c6eeaec0cef6141636f135b Signed-off-by: Pawel Wodkowski <pawelx.wodkowski@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/436528 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
d5ac3eb190
commit
27cc63ec68
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
from rpc.client import print_dict, JSONRPCException
|
from rpc.client import print_dict, JSONRPCException
|
||||||
|
|
||||||
|
import logging
|
||||||
import argparse
|
import argparse
|
||||||
import rpc
|
import rpc
|
||||||
import sys
|
import sys
|
||||||
@ -27,8 +28,10 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument('-t', dest='timeout',
|
parser.add_argument('-t', dest='timeout',
|
||||||
help='Timeout as a floating point number expressed in seconds waiting for response. Default: 60.0',
|
help='Timeout as a floating point number expressed in seconds waiting for response. Default: 60.0',
|
||||||
default=60.0, type=float)
|
default=60.0, type=float)
|
||||||
parser.add_argument('-v', dest='verbose',
|
parser.add_argument('-v', dest='verbose', action='store_const', const="INFO",
|
||||||
help='Verbose mode', action='store_true')
|
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')
|
subparsers = parser.add_subparsers(help='RPC methods')
|
||||||
|
|
||||||
def start_subsystem_init(args):
|
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()
|
args = parser.parse_args()
|
||||||
|
|
||||||
try:
|
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)
|
args.func(args)
|
||||||
except JSONRPCException as ex:
|
except JSONRPCException as ex:
|
||||||
print("Exception:")
|
print("Exception:")
|
||||||
|
@ -2,6 +2,7 @@ import json
|
|||||||
import socket
|
import socket
|
||||||
import time
|
import time
|
||||||
import os
|
import os
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
def print_dict(d):
|
def print_dict(d):
|
||||||
@ -14,31 +15,53 @@ class JSONRPCException(Exception):
|
|||||||
|
|
||||||
|
|
||||||
class JSONRPCClient(object):
|
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.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.timeout = timeout
|
||||||
self._request_id = 0
|
self._request_id = 0
|
||||||
self._recv_buf = ""
|
self._recv_buf = ""
|
||||||
self._reqs = []
|
self._reqs = []
|
||||||
try:
|
try:
|
||||||
if os.path.exists(addr):
|
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 = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
self.sock.connect(addr)
|
self.sock.connect(addr)
|
||||||
elif ':' in 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):
|
for res in socket.getaddrinfo(addr, port, socket.AF_INET6, socket.SOCK_STREAM, socket.SOL_TCP):
|
||||||
af, socktype, proto, canonname, sa = res
|
af, socktype, proto, canonname, sa = res
|
||||||
self.sock = socket.socket(af, socktype, proto)
|
self.sock = socket.socket(af, socktype, proto)
|
||||||
self.sock.connect(sa)
|
self.sock.connect(sa)
|
||||||
else:
|
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 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
self.sock.connect((addr, port))
|
self.sock.connect((addr, port))
|
||||||
except socket.error as ex:
|
except socket.error as ex:
|
||||||
raise JSONRPCException("Error while connecting to %s\n"
|
raise JSONRPCException("Error while connecting to %s\n"
|
||||||
"Error details: %s" % (addr, ex))
|
"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):
|
def __del__(self):
|
||||||
if self.sock:
|
if getattr(self, "sock", None):
|
||||||
self.sock.close()
|
self.sock.close()
|
||||||
|
|
||||||
def send(self, method, params=None):
|
def send(self, method, params=None):
|
||||||
@ -52,21 +75,20 @@ class JSONRPCClient(object):
|
|||||||
if params:
|
if params:
|
||||||
req['params'] = params
|
req['params'] = params
|
||||||
|
|
||||||
reqstr = json.dumps(req)
|
reqstr = json.dumps(req, indent=2)
|
||||||
if self.verbose:
|
self._logger.info("request:\n%s\n", reqstr)
|
||||||
print("request:")
|
|
||||||
print(json.dumps(req, indent=2))
|
|
||||||
|
|
||||||
self.sock.sendall(reqstr.encode("utf-8"))
|
self.sock.sendall(reqstr.encode("utf-8"))
|
||||||
return req
|
return req
|
||||||
|
|
||||||
def decode_one_response(self):
|
def decode_one_response(self):
|
||||||
try:
|
try:
|
||||||
|
self._logger.debug("Trying to decode response '%s'", self._recv_buf)
|
||||||
buf = self._recv_buf.lstrip()
|
buf = self._recv_buf.lstrip()
|
||||||
obj, idx = json.JSONDecoder().raw_decode(buf)
|
obj, idx = json.JSONDecoder().raw_decode(buf)
|
||||||
self._recv_buf = buf[idx:]
|
self._recv_buf = buf[idx:]
|
||||||
return obj
|
return obj
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
self._logger.debug("Partial response")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def recv(self):
|
def recv(self):
|
||||||
@ -91,10 +113,7 @@ class JSONRPCClient(object):
|
|||||||
if not response:
|
if not response:
|
||||||
raise JSONRPCException("Timeout while waiting for response:\n%s\n" % self._recv_buf)
|
raise JSONRPCException("Timeout while waiting for response:\n%s\n" % self._recv_buf)
|
||||||
|
|
||||||
if self.verbose:
|
self._logger.info("response:\n%s\n", json.dumps(response, indent=2))
|
||||||
print("response:")
|
|
||||||
print(json.dumps(response, indent=2))
|
|
||||||
|
|
||||||
if 'error' in response:
|
if 'error' in response:
|
||||||
msg = "\n".join(["Got JSON-RPC error response",
|
msg = "\n".join(["Got JSON-RPC error response",
|
||||||
"response:",
|
"response:",
|
||||||
@ -103,12 +122,14 @@ class JSONRPCClient(object):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
def call(self, method, params=None):
|
def call(self, method, params=None):
|
||||||
|
self._logger.debug("call('%s')" % method)
|
||||||
self.send(method, params)
|
self.send(method, params)
|
||||||
try:
|
try:
|
||||||
return self.recv()['result']
|
return self.recv()['result']
|
||||||
except JSONRPCException as e:
|
except JSONRPCException as e:
|
||||||
""" Don't expect response to kill """
|
""" Don't expect response to kill """
|
||||||
if not self.sock and method == "kill_instance":
|
if not self.sock and method == "kill_instance":
|
||||||
|
self._logger.info("Connection terminated but ignoring since method is '%s'" % method)
|
||||||
return {}
|
return {}
|
||||||
else:
|
else:
|
||||||
raise e
|
raise e
|
||||||
|
@ -57,9 +57,9 @@ class UIRoot(UINode):
|
|||||||
# Do not use for "get_*" methods so that output is not
|
# Do not use for "get_*" methods so that output is not
|
||||||
# flooded.
|
# flooded.
|
||||||
def w(self, **kwargs):
|
def w(self, **kwargs):
|
||||||
self.client.verbose = self.verbose
|
self.client.set_log_level("INFO" if self.verbose else "ERROR")
|
||||||
r = f(self, **kwargs)
|
r = f(self, **kwargs)
|
||||||
self.client.verbose = False
|
self.client.set_log_level("ERROR")
|
||||||
return r
|
return r
|
||||||
return w
|
return w
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import argparse
|
import argparse
|
||||||
|
import logging
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), "../../scripts"))
|
sys.path.append(os.path.join(os.path.dirname(__file__), "../../scripts"))
|
||||||
import rpc # noqa
|
import rpc # noqa
|
||||||
from rpc.client import print_dict, JSONRPCException # 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('-s', dest='server_addr', default='/var/tmp/spdk.sock')
|
||||||
parser.add_argument('-p', dest='port', default=5260, type=int)
|
parser.add_argument('-p', dest='port', default=5260, type=int)
|
||||||
parser.add_argument('-t', dest='timeout', default=60.0, type=float)
|
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')
|
subparsers = parser.add_subparsers(help='RPC methods')
|
||||||
|
|
||||||
@call_test_cmd
|
@call_test_cmd
|
||||||
@ -206,7 +210,7 @@ if __name__ == "__main__":
|
|||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
try:
|
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:
|
except JSONRPCException as ex:
|
||||||
print((ex.message))
|
print((ex.message))
|
||||||
exit(1)
|
exit(1)
|
||||||
|
Loading…
Reference in New Issue
Block a user