Commit 264f6f57 authored by Julien Muchembled's avatar Julien Muchembled

Various neoctl/neolog formatting improvements/fixes

- format IPv6 inside [] when followed by :<port>
- unify rendering of node lists
- neoctl: do not crash on empty DB (no PT id)
parent 933953e2
...@@ -235,7 +235,8 @@ class BaseConnection(object): ...@@ -235,7 +235,8 @@ class BaseConnection(object):
def _getReprInfo(self): def _getReprInfo(self):
r = [ r = [
('uuid', uuid_str(self.getUUID())), ('uuid', uuid_str(self.getUUID())),
('address', '%s:%u' % self.addr if self.addr else '?'), ('address', ('[%s]:%s' if ':' in self.addr[0] else '%s:%s')
% self.addr if self.addr else '?'),
('handler', self.getHandler()), ('handler', self.getHandler()),
] ]
connector = self.connector connector = self.connector
......
...@@ -219,8 +219,8 @@ class NEOLogger(Logger): ...@@ -219,8 +219,8 @@ class NEOLogger(Logger):
def _emit(self, r): def _emit(self, r):
if type(r) is PacketRecord: if type(r) is PacketRecord:
ip, port = r.addr ip, port = r.addr
peer = '%s %s (%s:%u)' % ('>' if r.outgoing else '<', peer = ('%s %s ([%s]:%s)' if ':' in ip else '%s %s (%s:%s)') % (
uuid_str(r.uuid), ip, port) '>' if r.outgoing else '<', uuid_str(r.uuid), ip, port)
msg = r.msg msg = r.msg
if msg is not None: if msg is not None:
msg = buffer(msg) msg = buffer(msg)
......
...@@ -19,7 +19,8 @@ from os.path import exists, getsize ...@@ -19,7 +19,8 @@ from os.path import exists, getsize
import json import json
from . import attributeTracker, logging from . import attributeTracker, logging
from .protocol import uuid_str, NodeTypes, NodeStates, ProtocolError from .protocol import formatNodeList, uuid_str, \
NodeTypes, NodeStates, ProtocolError
class Node(object): class Node(object):
...@@ -161,10 +162,12 @@ class Node(object): ...@@ -161,10 +162,12 @@ class Node(object):
return self._identified return self._identified
def __repr__(self): def __repr__(self):
return '<%s(uuid=%s, address=%s, state=%s, connection=%r%s) at %x>' % ( addr = self._address
return '<%s(uuid=%s%s, state=%s, connection=%r%s) at %x>' % (
self.__class__.__name__, self.__class__.__name__,
uuid_str(self._uuid), uuid_str(self._uuid),
self._address, ', address=' + ('[%s]:%s' if ':' in addr[0] else '%s:%s') % addr
if addr else '',
self._state, self._state,
self._connection, self._connection,
'' if self._identified else ', not identified', '' if self._identified else ', not identified',
...@@ -448,16 +451,8 @@ class NodeManager(object): ...@@ -448,16 +451,8 @@ class NodeManager(object):
def log(self): def log(self):
logging.info('Node manager : %u nodes', len(self._node_set)) logging.info('Node manager : %u nodes', len(self._node_set))
if self._node_set: if self._node_set:
node_list = [(node, uuid_str(node.getUUID())) logging.info('\n'.join(formatNodeList(
for node in sorted(self._node_set)] map(Node.asTuple, self._node_set), ' * ')))
max_len = max(len(x[1]) for x in node_list)
for node, uuid in node_list:
address = node.getAddress() or ''
if address:
address = '%s:%d' % address
logging.info(' * %*s | %8s | %22s | %s',
max_len, uuid, node.getType(), address, node.getState())
@apply @apply
def NODE_TYPE_MAPPING(): def NODE_TYPE_MAPPING():
......
...@@ -1742,3 +1742,22 @@ def Errors(): ...@@ -1742,3 +1742,22 @@ def Errors():
registry_dict)(handler_method_name_dict) registry_dict)(handler_method_name_dict)
Errors = Errors() Errors = Errors()
# Common helpers between the 'neo' module and 'neolog'.
from datetime import datetime
from operator import itemgetter
def formatNodeList(node_list, prefix='', _sort_key=itemgetter(2)):
if node_list:
node_list.sort(key=_sort_key)
node_list = [(
uuid_str(uuid), str(node_type),
('[%s]:%s' if ':' in addr[0] else '%s:%s')
% addr if addr else '', str(state),
str(id_timestamp and datetime.utcfromtimestamp(id_timestamp)))
for node_type, addr, uuid, state, id_timestamp in node_list]
t = ''.join('%%-%us | ' % max(len(x[i]) for x in node_list)
for i in xrange(len(node_list[0]) - 1))
return map((prefix + t + '%s').__mod__, node_list)
return ()
...@@ -14,11 +14,10 @@ ...@@ -14,11 +14,10 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from operator import itemgetter
from .neoctl import NeoCTL, NotReadyException from .neoctl import NeoCTL, NotReadyException
from neo.lib.util import p64, u64, tidFromTime, timeStringFromTID from neo.lib.util import p64, u64, tidFromTime, timeStringFromTID
from neo.lib.protocol import uuid_str, ClusterStates, NodeTypes, \ from neo.lib.protocol import uuid_str, formatNodeList, \
UUID_NAMESPACES, ZERO_TID ClusterStates, NodeTypes, UUID_NAMESPACES, ZERO_TID
action_dict = { action_dict = {
'print': { 'print': {
...@@ -71,15 +70,6 @@ class TerminalNeoCTL(object): ...@@ -71,15 +70,6 @@ class TerminalNeoCTL(object):
for (uuid, state) in cell_list)) for (uuid, state) in cell_list))
for (offset, cell_list) in row_list) for (offset, cell_list) in row_list)
def formatNodeList(self, node_list, _sort_key=itemgetter(2, 0, 1)):
if not node_list:
return 'Empty list!'
node_list.sort(key=_sort_key)
return '\n'.join(
'%s - %s - %s - %s' % (node_type, uuid_str(uuid),
address and '%s:%s' % address, state)
for node_type, address, uuid, state in node_list)
# Actual actions # Actual actions
def getLastIds(self, params): def getLastIds(self, params):
""" """
...@@ -94,7 +84,7 @@ class TerminalNeoCTL(object): ...@@ -94,7 +84,7 @@ class TerminalNeoCTL(object):
else: else:
loid, ltid = self.neoctl.getLastIds() loid, ltid = self.neoctl.getLastIds()
r = "last_oid = 0x%x" % (u64(loid)) r = "last_oid = 0x%x" % (u64(loid))
return r + "\nlast_tid = 0x%x (%s)\nlast_ptid = %u" % \ return r + "\nlast_tid = 0x%x (%s)\nlast_ptid = %s" % \
(u64(ltid), timeStringFromTID(ltid), ptid) (u64(ltid), timeStringFromTID(ltid), ptid)
def getPartitionRowList(self, params): def getPartitionRowList(self, params):
...@@ -129,7 +119,7 @@ class TerminalNeoCTL(object): ...@@ -129,7 +119,7 @@ class TerminalNeoCTL(object):
else: else:
node_type = None node_type = None
node_list = self.neoctl.getNodeList(node_type=node_type) node_list = self.neoctl.getNodeList(node_type=node_type)
return self.formatNodeList(node_list) return '\n'.join(formatNodeList(node_list)) or 'Empty list!'
def getClusterState(self, params): def getClusterState(self, params):
""" """
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
import bz2, gzip, errno, optparse, os, signal, sqlite3, sys, time import bz2, gzip, errno, optparse, os, signal, sqlite3, sys, time
from bisect import insort from bisect import insort
from logging import getLevelName from logging import getLevelName
from functools import partial
comp_dict = dict(bz2=bz2.BZ2File, gz=gzip.GzipFile) comp_dict = dict(bz2=bz2.BZ2File, gz=gzip.GzipFile)
...@@ -93,6 +94,11 @@ class Log(object): ...@@ -93,6 +94,11 @@ class Log(object):
exec bz2.decompress(text) in g exec bz2.decompress(text) in g
for x in 'uuid_str', 'Packets', 'PacketMalformedError': for x in 'uuid_str', 'Packets', 'PacketMalformedError':
setattr(self, x, g[x]) setattr(self, x, g[x])
try:
self.notifyNodeInformation = partial(g['formatNodeList'],
prefix=' ! ')
except KeyError:
self.notifyNodeInformation = None
try: try:
self._next_protocol, = q("SELECT date FROM protocol WHERE date>?", self._next_protocol, = q("SELECT date FROM protocol WHERE date>?",
(date,)).next() (date,)).next()
...@@ -144,18 +150,6 @@ class Log(object): ...@@ -144,18 +150,6 @@ class Log(object):
def error(self, code, message): def error(self, code, message):
return "%s (%s)" % (code, message), return "%s (%s)" % (code, message),
def notifyNodeInformation(self, node_list):
node_list.sort(key=lambda x: x[2])
node_list = [(self.uuid_str(x[2]), str(x[0]),
'%s:%u' % x[1] if x[1] else '?', str(x[3]))
+ ((repr(x[4]),) if len(x) > 4 else ()) # BBB
for x in node_list]
if node_list:
t = ''.join(' %%%us |' % max(len(x[i]) for x in node_list)
for i in xrange(len(node_list[0]) - 1))
return map((' !' + t + ' %s').__mod__, node_list)
return ()
def emit_many(log_list): def emit_many(log_list):
log_list = [(log, iter(log).next) for log in log_list] log_list = [(log, iter(log).next) for log in log_list]
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment