mirror of
https://github.com/tinode/chat.git
synced 2025-03-14 10:05:07 +00:00
add verbose logging option
This commit is contained in:
@ -27,6 +27,10 @@ from google.protobuf.json_format import MessageToDict
|
|||||||
from tinode_grpc import pb
|
from tinode_grpc import pb
|
||||||
from tinode_grpc import pbx
|
from tinode_grpc import pbx
|
||||||
|
|
||||||
|
# For compatibility with python2
|
||||||
|
if sys.version_info[0] >= 3:
|
||||||
|
unicode = str
|
||||||
|
|
||||||
APP_NAME = "Tino-chatbot"
|
APP_NAME = "Tino-chatbot"
|
||||||
APP_VERSION = "1.2.0"
|
APP_VERSION = "1.2.0"
|
||||||
LIB_VERSION = pkg_resources.get_distribution("tinode_grpc").version
|
LIB_VERSION = pkg_resources.get_distribution("tinode_grpc").version
|
||||||
@ -51,11 +55,20 @@ def add_future(tid, bundle):
|
|||||||
onCompletion[tid] = bundle
|
onCompletion[tid] = bundle
|
||||||
|
|
||||||
# Shorten long strings for logging.
|
# Shorten long strings for logging.
|
||||||
class JsonHelper(json.JSONEncoder):
|
def clip_long_string(obj):
|
||||||
def default(self, obj):
|
if isinstance(obj, unicode) or isinstance(obj, str):
|
||||||
if type(obj) == str and len(obj) > MAX_LOG_LEN:
|
if len(obj) > MAX_LOG_LEN:
|
||||||
return '<' + len(obj) + ', bytes: ' + obj[:12] + '...' + obj[-12:] + '>'
|
return '<' + str(len(obj)) + ' bytes: ' + obj[:12] + '...' + obj[-12:] + '>'
|
||||||
return super(JsonHelper, self).default(obj)
|
return obj
|
||||||
|
elif isinstance(obj, (list, tuple)):
|
||||||
|
return [clip_long_string(item) for item in obj]
|
||||||
|
elif isinstance(obj, dict):
|
||||||
|
return dict((key, clip_long_string(val)) for key, val in obj.items())
|
||||||
|
else:
|
||||||
|
return obj
|
||||||
|
|
||||||
|
def to_json(msg):
|
||||||
|
return json.dumps(clip_long_string(MessageToDict(msg)))
|
||||||
|
|
||||||
# Resolve or reject the future
|
# Resolve or reject the future
|
||||||
def exec_future(tid, code, text, params):
|
def exec_future(tid, code, text, params):
|
||||||
@ -144,7 +157,7 @@ def client_generate():
|
|||||||
msg = queue_out.get()
|
msg = queue_out.get()
|
||||||
if msg == None:
|
if msg == None:
|
||||||
return
|
return
|
||||||
log("out:", json.dumps(MessageToDict(msg), cls=JsonHelper))
|
log("out:", to_json(msg)
|
||||||
yield msg
|
yield msg
|
||||||
|
|
||||||
def client_post(msg):
|
def client_post(msg):
|
||||||
@ -237,8 +250,7 @@ def client_message_loop(stream):
|
|||||||
try:
|
try:
|
||||||
# Read server responses
|
# Read server responses
|
||||||
for msg in stream:
|
for msg in stream:
|
||||||
log(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3],
|
log(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3], "in:", to_json(msg))
|
||||||
"in:", json.dumps(MessageToDict(msg), cls=JsonHelper))
|
|
||||||
|
|
||||||
if msg.HasField("ctrl"):
|
if msg.HasField("ctrl"):
|
||||||
# Run code on command completion
|
# Run code on command completion
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
# coding=utf-8
|
||||||
|
|
||||||
"""Python implementation of Tinode command line client using gRPC."""
|
"""Python implementation of Tinode command line client using gRPC."""
|
||||||
|
|
||||||
@ -27,8 +28,6 @@ import sys
|
|||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from google.protobuf import json_format
|
|
||||||
|
|
||||||
# Import generated grpc modules
|
# Import generated grpc modules
|
||||||
from tinode_grpc import pb
|
from tinode_grpc import pb
|
||||||
from tinode_grpc import pbx
|
from tinode_grpc import pbx
|
||||||
@ -37,6 +36,7 @@ import tn_globals
|
|||||||
from tn_globals import printerr
|
from tn_globals import printerr
|
||||||
from tn_globals import printout
|
from tn_globals import printout
|
||||||
from tn_globals import stdoutln
|
from tn_globals import stdoutln
|
||||||
|
from tn_globals import to_json
|
||||||
|
|
||||||
APP_NAME = "tn-cli"
|
APP_NAME = "tn-cli"
|
||||||
APP_VERSION = "1.4.0"
|
APP_VERSION = "1.4.0"
|
||||||
@ -821,7 +821,10 @@ def gen_message(scheme, secret, args):
|
|||||||
tn_globals.InputThread.daemon = True
|
tn_globals.InputThread.daemon = True
|
||||||
tn_globals.InputThread.start()
|
tn_globals.InputThread.start()
|
||||||
|
|
||||||
yield hiMsg(id)
|
msg = hiMsg(id)
|
||||||
|
if tn_globals.Verbose:
|
||||||
|
stdoutln("\r=> " + to_json(msg))
|
||||||
|
yield msg
|
||||||
|
|
||||||
if scheme != None:
|
if scheme != None:
|
||||||
id += 1
|
id += 1
|
||||||
@ -829,7 +832,10 @@ def gen_message(scheme, secret, args):
|
|||||||
setattr(login, 'scheme', scheme)
|
setattr(login, 'scheme', scheme)
|
||||||
setattr(login, 'secret', secret)
|
setattr(login, 'secret', secret)
|
||||||
setattr(login, 'cred', None)
|
setattr(login, 'cred', None)
|
||||||
yield loginMsg(id, login, args)
|
msg = loginMsg(id, login, args)
|
||||||
|
if tn_globals.Verbose:
|
||||||
|
stdoutln("\r=> " + to_json(msg))
|
||||||
|
yield msg
|
||||||
|
|
||||||
print_prompt = True
|
print_prompt = True
|
||||||
|
|
||||||
@ -859,6 +865,8 @@ def gen_message(scheme, secret, args):
|
|||||||
tn_globals.WaitingFor = cmd
|
tn_globals.WaitingFor = cmd
|
||||||
|
|
||||||
if not hasattr(cmd, 'no_yield'):
|
if not hasattr(cmd, 'no_yield'):
|
||||||
|
if tn_globals.Verbose:
|
||||||
|
stdoutln("\r=> " + to_json(pbMsg))
|
||||||
yield pbMsg
|
yield pbMsg
|
||||||
|
|
||||||
elif not tn_globals.OutputQueue.empty():
|
elif not tn_globals.OutputQueue.empty():
|
||||||
@ -920,6 +928,9 @@ def run(args, schema, secret):
|
|||||||
|
|
||||||
# Read server responses
|
# Read server responses
|
||||||
for msg in stream:
|
for msg in stream:
|
||||||
|
if tn_globals.Verbose:
|
||||||
|
stdoutln("\r<= " + to_json(msg))
|
||||||
|
|
||||||
if msg.HasField("ctrl"):
|
if msg.HasField("ctrl"):
|
||||||
handle_ctrl(msg.ctrl)
|
handle_ctrl(msg.ctrl)
|
||||||
|
|
||||||
@ -1044,12 +1055,17 @@ if __name__ == '__main__':
|
|||||||
parser.add_argument('--api-key', default='AQEAAAABAAD_rAp4DJh05a1HAwFT3A6K', help='API key for file uploads')
|
parser.add_argument('--api-key', default='AQEAAAABAAD_rAp4DJh05a1HAwFT3A6K', help='API key for file uploads')
|
||||||
parser.add_argument('--load-macros', default='./macros.py', help='path to macro module to load')
|
parser.add_argument('--load-macros', default='./macros.py', help='path to macro module to load')
|
||||||
parser.add_argument('--version', action='store_true', help='print version')
|
parser.add_argument('--version', action='store_true', help='print version')
|
||||||
|
parser.add_argument('--verbose', action='store_true', help='verbose output: print full JSON representation of messages')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if args.version:
|
if args.version:
|
||||||
printout(version)
|
printout(version)
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
|
if args.verbose:
|
||||||
|
tn_globals.Verbose = True
|
||||||
|
|
||||||
printout(purpose)
|
printout(purpose)
|
||||||
printout("Secure server" if args.ssl else "Server", "at '"+args.host+"'",
|
printout("Secure server" if args.ssl else "Server", "at '"+args.host+"'",
|
||||||
"SNI="+args.ssl_host if args.ssl_host else "")
|
"SNI="+args.ssl_host if args.ssl_host else "")
|
||||||
|
@ -2,13 +2,19 @@
|
|||||||
# To make print() compatible between p2 and p3
|
# To make print() compatible between p2 and p3
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import json
|
||||||
import sys
|
import sys
|
||||||
from collections import deque
|
from collections import deque
|
||||||
|
from google.protobuf.json_format import MessageToDict
|
||||||
try:
|
try:
|
||||||
import Queue as queue
|
import Queue as queue
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import queue
|
import queue
|
||||||
|
|
||||||
|
if sys.version_info[0] >= 3:
|
||||||
|
# for compatibility with python2
|
||||||
|
unicode = str
|
||||||
|
|
||||||
# Dictionary wich contains lambdas to be executed when server {ctrl} response is received.
|
# Dictionary wich contains lambdas to be executed when server {ctrl} response is received.
|
||||||
OnCompletion = {}
|
OnCompletion = {}
|
||||||
|
|
||||||
@ -35,6 +41,9 @@ DefaultTopic = None
|
|||||||
# Variables: results of command execution
|
# Variables: results of command execution
|
||||||
Variables = {}
|
Variables = {}
|
||||||
|
|
||||||
|
# Flag to enable extended logging. Useful for debugging.
|
||||||
|
Verbose = False
|
||||||
|
|
||||||
# Print prompts in interactive mode only.
|
# Print prompts in interactive mode only.
|
||||||
def printout(*args):
|
def printout(*args):
|
||||||
if IsInteractive:
|
if IsInteractive:
|
||||||
@ -65,3 +74,27 @@ def stdout(*args):
|
|||||||
def stdoutln(*args):
|
def stdoutln(*args):
|
||||||
args = args + ("\n",)
|
args = args + ("\n",)
|
||||||
stdout(*args)
|
stdout(*args)
|
||||||
|
|
||||||
|
# Shorten long strings for logging.
|
||||||
|
def clip_long_string(obj):
|
||||||
|
if isinstance(obj, str) or isinstance(obj, unicode):
|
||||||
|
if len(obj) > 64:
|
||||||
|
return '<' + str(len(obj)) + ' bytes: ' + obj[:12] + '...' + obj[-12:] + '>'
|
||||||
|
return obj
|
||||||
|
elif isinstance(obj, (list, tuple)):
|
||||||
|
return [clip_long_string(item) for item in obj]
|
||||||
|
elif isinstance(obj, dict):
|
||||||
|
return dict((key, clip_long_string(val)) for key, val in obj.items())
|
||||||
|
else:
|
||||||
|
return obj
|
||||||
|
|
||||||
|
# Convert protobuff message to json. Shorten very long strings.
|
||||||
|
def to_json(msg):
|
||||||
|
if not msg:
|
||||||
|
return 'null'
|
||||||
|
try:
|
||||||
|
return json.dumps(clip_long_string(MessageToDict(msg)))
|
||||||
|
except Exception as err:
|
||||||
|
stdoutln("Exception: {}".format(err))
|
||||||
|
|
||||||
|
return 'exception'
|
||||||
|
Reference in New Issue
Block a user