Skip to content

Commit c8b9af7

Browse files
committed
1.“python控制台”区分了命令行与输出的颜色,以方便用户更容易区分
2.増加“日志查看”中的“实时日志”现在可以使用了 3.“性能分析”中増加了“TickProfile”类型的分析支持
1 parent a8373e3 commit c8b9af7

24 files changed

+59633
-265
lines changed

kbe/tools/server/pycommon/LoggerWatcher.py

Lines changed: 118 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,32 @@
1818

1919
CONSOLE_LOG_MSGID = 65501 # log 消息
2020

21-
KBELOG_SCRIPT_INFO = 0x00000040
22-
KBELOG_SCRIPT_ERROR = 0x00000080
23-
KBELOG_SCRIPT_DEBUG = 0x00000100
24-
KBELOG_SCRIPT_WARNING = 0x00000200
25-
KBELOG_SCRIPT_NORMAL = 0x00000400
21+
22+
KBELOG_UNKNOWN = 0x00000000
23+
KBELOG_PRINT = 0x00000001
24+
KBELOG_ERROR = 0x00000002
25+
KBELOG_WARNING = 0x00000004
26+
KBELOG_DEBUG = 0x00000008
27+
KBELOG_INFO = 0x00000010
28+
KBELOG_CRITICAL = 0x00000020
29+
KBELOG_SCRIPT_INFO = 0x00000040
30+
KBELOG_SCRIPT_ERROR = 0x00000080
31+
KBELOG_SCRIPT_DEBUG = 0x00000100
32+
KBELOG_SCRIPT_WARNING = 0x00000200
33+
KBELOG_SCRIPT_NORMAL = 0x00000400
2634

2735
logName2type = {
28-
"NORMAL" : KBELOG_SCRIPT_NORMAL,
29-
"INFO" : KBELOG_SCRIPT_INFO,
30-
"ERROR" : KBELOG_SCRIPT_ERROR,
31-
"DEBUG" : KBELOG_SCRIPT_DEBUG,
32-
"WARNING" : KBELOG_SCRIPT_WARNING,
36+
"PRINT" : KBELOG_PRINT,
37+
"ERROR" : KBELOG_ERROR,
38+
"WARNING" : KBELOG_WARNING,
39+
"DEBUG" : KBELOG_DEBUG,
40+
"INFO" : KBELOG_INFO,
41+
"CRITICAL" : KBELOG_CRITICAL,
42+
"S_NORM" : KBELOG_SCRIPT_NORMAL,
43+
"S_INFO" : KBELOG_SCRIPT_INFO,
44+
"S_ERR" : KBELOG_SCRIPT_ERROR,
45+
"S_DBG" : KBELOG_SCRIPT_DEBUG,
46+
"S_WARN" : KBELOG_SCRIPT_WARNING,
3347
}
3448

3549
class LoggerWatcher:
@@ -40,7 +54,6 @@ def __init__( self ):
4054
"""
4155
"""
4256
self.socket = None
43-
4457
self.msgBuffer = "".encode()
4558

4659
def connect( self, ip, port ):
@@ -61,18 +74,39 @@ def close( self ):
6174
self.socket.close()
6275
self.socket = None
6376

64-
def registerToLogger( self, uid ):
77+
def registerToLogger( self, uid):
6578
"""
6679
向logger注册
6780
"""
81+
6882
msg = Define.BytesIO()
6983
msg.write( struct.pack("=H", Logger_registerLogWatcher ) ) # command
70-
msg.write( struct.pack("=H", struct.calcsize("=iIiiccB" + "i" * Define.COMPONENT_END_TYPE + "BB") ) ) # package len
84+
msg.write( struct.pack("=H", struct.calcsize("=iIiiccB" + "i" * Define.COMPONENT_END_TYPE + "BB") ) ) # package len
7185
msg.write( struct.pack("=i", uid ) )
72-
msg.write( struct.pack("=I", 0xffffffff) ) # logtypes filter
73-
msg.write( struct.pack("=iicc", 0, 0, "\0".encode(), "\0".encode() ) ) # globalOrder, groupOrder, date, keyStr
74-
msg.write( struct.pack("=B", Define.COMPONENT_END_TYPE ) ) # component type filter count
75-
msg.write( struct.pack("=" + "i" * Define.COMPONENT_END_TYPE, *list( range( Define.COMPONENT_END_TYPE ) ))) # component type filter
86+
msg.write( struct.pack("=I",0xffffffff) ) # logtypes filter
87+
# msg.write( struct.pack("=I",KBELOG_WARNING ) ) # logtypes filter
88+
msg.write( struct.pack("=iicc", 0, 0, '\0'.encode(), '\0'.encode())) # globalOrder, groupOrder, date, keyStr
89+
msg.write( struct.pack("=B" ,Define.COMPONENT_END_TYPE) ) # component type filter count
90+
msg.write( struct.pack("="+"i" * Define.COMPONENT_END_TYPE, *list(range(Define.COMPONENT_END_TYPE)))) # component type filter
91+
msg.write( struct.pack("=BB", 0, 1 ) ) # isfind, first
92+
self.socket.sendall( msg.getvalue() )
93+
94+
def registerToLoggerForWeb( self, uid, components_check, logtype, globalOrder, groupOrder, searchDate, keystr ):
95+
"""
96+
向logger注册
97+
"""
98+
99+
msg = Define.BytesIO()
100+
d1 = str(len(searchDate.encode()))
101+
d2 = str(len(keystr.encode()))
102+
msg.write( struct.pack("=H", Logger_registerLogWatcher ) ) # command
103+
msg.write( struct.pack("=H", struct.calcsize("=iIiiccB" + "i" * Define.COMPONENT_END_TYPE + "BB") + len(searchDate.encode()) + len(keystr.encode())) ) # package len
104+
msg.write( struct.pack("=i", uid ) )
105+
msg.write( struct.pack("=I",logtype) ) # logtypes filter
106+
# msg.write( struct.pack("=I",KBELOG_WARNING ) ) # logtypes filter
107+
msg.write( struct.pack("=ii" + d1 + "sc" + d2 + "sc", globalOrder, groupOrder, searchDate.encode() ,'\0'.encode() , keystr.encode(), '\0'.encode() )) # globalOrder, groupOrder, date, keyStr
108+
msg.write( struct.pack("=B" ,Define.COMPONENT_END_TYPE) ) # component type filter count
109+
msg.write( struct.pack("="+"i" * Define.COMPONENT_END_TYPE, *list(list(components_check)))) # component type filter
76110
msg.write( struct.pack("=BB", 0, 1 ) ) # isfind, first
77111
self.socket.sendall( msg.getvalue() )
78112

@@ -139,7 +173,7 @@ def parseLog( self, stream ):
139173
pos += 4
140174
if buffLen < pos + dataLen:
141175
self.msgBuffer = self.msgBuffer[pos - 4:]
142-
return result
176+
return result
143177

144178
if cmdID != CONSOLE_LOG_MSGID:
145179
print( "Unknown command.(id = %s)" % cmdID )
@@ -163,11 +197,10 @@ def receiveLog( self, callbackFunc, loop = False ):
163197
if len( msg ) == 0:
164198
print( "Receive 0 bytes, over! fileno '%s'" % self.socket.fileno() )
165199
return
166-
200+
167201
ms = self.parseLog( msg )
168202
if ms:
169203
callbackFunc( ms )
170-
171204
continue
172205

173206
if not loop:
@@ -177,3 +210,68 @@ def receiveLog( self, callbackFunc, loop = False ):
177210
self.sendActiveTick()
178211

179212

213+
class LogWatch(object):
214+
"""
215+
日志输出
216+
"""
217+
def __init__(self,wsInst, extaddr, extport, uid, components_check, logtype, globalOrder, groupOrder, searchDate, keystr):
218+
self.wsInst = wsInst
219+
self.extaddr = extaddr
220+
self.extport = extport
221+
self.uid = uid
222+
self.components_check = components_check
223+
self.logtype = logtype
224+
self.globalOrder = globalOrder
225+
self.groupOrder = groupOrder
226+
self.searchDate = searchDate
227+
self.keystr = keystr
228+
self.logger = LoggerWatcher()
229+
230+
self.pops = ""
231+
self.pops_end = ""
232+
self.again = 0
233+
self.first = 0
234+
self.sendinfo = False
235+
236+
def do(self):
237+
"""
238+
"""
239+
240+
self.logger.close()
241+
self.logger.connect( self.extaddr, self.extport)
242+
self.logger.registerToLoggerForWeb( self.uid,self.components_check, self.logtype, self.globalOrder, self.groupOrder,self.searchDate, self.keystr )
243+
def onReceivedLog(logs):
244+
if self.first < 2 :
245+
for e in logs:
246+
self.wsInst.send(e)
247+
self.first = self.first + 1
248+
self.pops = list.pop(logs)
249+
if self.again > 0:
250+
if self.pops != self.pops_end:
251+
self.again = self.again - 1
252+
if self.again < 0:
253+
self.again = 0
254+
if self.again < 6:
255+
if self.pops == self.pops_end:
256+
self.again = self.again + 1
257+
self.wsInst.send(self.pops)
258+
self.pops_end = self.pops
259+
self.logger.deregisterFromLogger()
260+
self.logger.receiveLog(onReceivedLog, True)
261+
262+
if self.wsInst:
263+
self.wsInst.close()
264+
self.logger.close()
265+
266+
def close(self):
267+
"""
268+
"""
269+
self.logger.close()
270+
self.logger.deregisterFromLogger()
271+
272+
if self.wsInst:
273+
self.wsInst.close()
274+
self.wsInst = None
275+
276+
self.extaddr = ""
277+
self.extport = 0
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# -*- coding: utf-8 -*-
2+
import telnetlib, sys, select
3+
from django.http import HttpResponse
4+
5+
from .auth import login_check
6+
7+
def _pre_process_cmd(cmd):
8+
if cmd.endswith( b"\r\n" ):
9+
return cmd
10+
elif cmd[-1] == b"\r":
11+
cmd += b"\n"
12+
elif cmd[-1] == b"\n":
13+
cmd = cmd[:-1] + b"\r\n"
14+
else:
15+
cmd += b"\r\n"
16+
return cmd
17+
18+
class TelnetConsole(object):
19+
def __init__( self, wsInst, host, port ):
20+
"""
21+
"""
22+
self.wsInst = wsInst
23+
self.host = host
24+
self.port = port
25+
self.consoleInst = None
26+
27+
def close( self ):
28+
"""
29+
"""
30+
if self.consoleInst:
31+
self.consoleInst.close()
32+
self.consoleInst = None
33+
34+
if self.wsInst:
35+
self.wsInst.close()
36+
self.wsInst = None
37+
38+
self.host = ""
39+
self.port = 0
40+
41+
def run( self ):
42+
"""
43+
"""
44+
try:
45+
self.consoleInst = telnetlib.Telnet( self.host, self.port )
46+
except Exception:
47+
self.wsInst.send("服务器连接失败!\n")
48+
self.close()
49+
return
50+
51+
self.onConnectedToConsole()
52+
53+
try:
54+
tlfd = self.consoleInst.fileno()
55+
wsfd = self.wsInst.protocol.sock.fileno()
56+
rlist = [ tlfd, wsfd ]
57+
58+
while True:
59+
rl, wl, xl = select.select(rlist, [], [], 0.1)
60+
if tlfd in rl:
61+
data = self.consoleInst.read_some()
62+
if not data:
63+
break # socket closed
64+
if not self.onReceivedConsoleData( data ):
65+
break
66+
67+
if wsfd in rl:
68+
data = self.wsInst.read()
69+
if data is None:
70+
break # socket closed
71+
if len(data) == 0:
72+
continue
73+
if not self.onReceivedClientData( data ):
74+
break
75+
except:
76+
sys.excepthook( *sys.exc_info() )
77+
78+
self.close()
79+
#return HttpResponse("")
80+
return
81+
82+
# test code
83+
"""
84+
try:
85+
for message in self.wsInst:
86+
self.wsInst.send(message)
87+
except:
88+
sys.excepthook( *sys.exc_info() )
89+
return
90+
"""
91+
92+
def onConnectedToConsole( self ):
93+
"""
94+
template method.
95+
当成功连接上telnet控制台时回调
96+
"""
97+
pass
98+
99+
def onReceivedConsoleData( self, data ):
100+
"""
101+
template method.
102+
当从telenet控制台收到了新数据以后回调
103+
"""
104+
print( data )
105+
self.wsInst.send( data )
106+
return True
107+
108+
def onReceivedClientData( self, data ):
109+
"""
110+
template method.
111+
当从客户端收到了新数据以后回调
112+
"""
113+
if data == ":quit":
114+
self.wsInst.close()
115+
return False
116+
self.consoleInst.write( _pre_process_cmd( data ) )
117+
return True
118+
119+
120+
121+
122+
class ProfileConsole(TelnetConsole):
123+
"""
124+
用于性能分析的控制台类
125+
"""
126+
def onConnectedToConsole( self ):
127+
"""
128+
template method.
129+
当成功连接上telnet控制台时回调
130+
"""
131+
self.consoleInst.write( b"kbe\r\n" )
132+
self.consoleInst.write( b":pytickprofile 10\r\n" )
133+
134+
def onReceivedConsoleData( self, data ):
135+
"""
136+
template method.
137+
当从telenet控制台收到了新数据以后回调
138+
"""
139+
self.wsInst.send( data )
140+
return True
141+
142+
def onReceivedClientData( self, data ):
143+
"""
144+
template method.
145+
当从客户端收到了新数据以后回调
146+
"""
147+
if data == ":":
148+
self.wsInst.close()
149+
return False
150+
self.consoleInst.write( _pre_process_cmd( data ) )
151+
return True
152+

kbe/tools/server/webconsole/WebConsole/urls.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
1. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
1414
"""
1515
from django.conf.urls import include, url
16-
from . import views, auth
16+
from . import views, auth, views_console, views_profile, views_log
1717

1818
urlpatterns = [
1919
url(r'^login$', auth.login, name = "login"),
@@ -30,6 +30,8 @@
3030
url(r'^components/manage$', views.components_manage, name = "components_manage"),
3131
url(r'^components/run$', views.components_run, name = "components_run"),
3232
url(r'^components/shutdown$', views.components_shutdown, name = "components_shutdown"),
33+
url(r'^components/(?P<ct>[0-9]+)/shutdown$', views.components_group_shutdown, name = "components_group_shutdown"),
34+
url(r'^components/(?P<ct>[0-9]+)/query$', views.components_group_query, name = "components_group_query" ),
3335
url(r'^components/query$', views.components_query, name = "components_query" ),
3436
url(r'^components/query_machines$', views.components_query_machines, name = "components_query_machines" ),
3537
url(r'^components/save_layout$', views.components_save_layout, name = "components_save_layout" ),
@@ -39,8 +41,15 @@
3941

4042
url(r'^machines/show_all$', views.machines_show_all, name = "machines_show_all" ),
4143

42-
url(r'^console/show_components$', views.console_show_components, name = "console_show_components" ),
43-
url(r'^console/connect$', views.console_connect, name = "console_connect" ),
44-
url(r'^console/process_cmd$', views.console_process_cmd, name = "console_process_cmd" ),
44+
url(r'^console/show_components$', views_console.show_components, name = "console_show_components" ),
45+
url(r'^console/connect$', views_console.connect, name = "console_connect" ),
46+
url(r'^console/process_cmd$', views_console.process_cmd, name = "console_process_cmd" ),
4547

48+
url(r'^profile/show_components$', views_profile.show_components, name = "console_show_components" ),
49+
url(r'^profile/connect$', views_profile.connect, name = "console_connect" ),
50+
url(r'^profile/process_cmd$', views_profile.process_cmd, name = "console_process_cmd" ),
51+
52+
url(r'^log/connect',views_log.connect, name = "real_time_log" ),
53+
url(r'^log/process_cmd$', views_log.process_cmd, name = "log_process_cmd" ),
54+
url(r'^log/connect/pull',views_log.pull_log,name = "pull_log"),
4655
]

0 commit comments

Comments
 (0)