1
0
mirror of https://github.com/CumulusNetworks/ifupdown2.git synced 2024-05-06 15:54:50 +00:00

nlmanager: Provide option to prevent color output

Ticket: CM-7361
Reviewed By: CCR-
Testing Done: Tested with clag

Certain loggers, most notably the syslog, don't allow non-printable characters
in their output, and so they convert them to a string of printable characters.
For example, the newline character is converted to #012. This results in output
that looks like this:

2016-08-29T18:50:46.263178+00:00 act-5712-08 clagd[21539]: RXed RTM_NEWNEIGH,
length 68, seq 0, pid 0, flags 0x0#012#012  #033[91mNetlink Header#033[0m#012
1: #033[91m0x44000000#033[0m  D...  Length 0x00000044 (68)#012   2:
#033[91m0x1c000000#033[0m  ....  Type 0x001c (28 - RTM_NEWNEIGH), Flags 0x0000
()#012   3: #033[91m0x00000000#033[0m  ....  Sequence Number 0x00000000 (0)#012
4: #033[91m0x00000000#033[0m  ....  Process ID 0x00000000 (0)#012
#033[93mService Header#033[0m#012   5: #033[93m0x07000000#033[0m  ....  Family
0x07 (7)#012   6: #033[93m0x29010000#033[0m  )...  Interface Index 0x00000129
(297)#012   7: #033[93m0x02000000#033[0m  ....  State 0x0002 (2), Flags 0x00,
Type 0x0000 (0)#012  Attributes#012   8: #033[92m0x0a000200#033[0m  ....  Length
0x000a (10) padded to 12, Type 0x0002 (2) NDA_LLADDR#012   9:
#033[92m0x00020000#033[0m  ....  00:02:00:00:00:09#012  10:
#033[92m0x00090000#033[0m  ....  #012  11: #033[94m0x08000900#033[0m  ....
Length 0x0008 (8), Type 0x0009 (9) NDA_MASTER#012  12: #033[94m0x2b010000#033[0m
+...  299#012  13: #033[92m0x14000300#033[0m  ....  Length 0x0014 (20), Type
0x0003 (3) NDA_CACHEINFO#012  14: #033[92m0x00000000#033[0m  ....  0#012  15:
#033[92m0x00000000#033[0m  ....  0#012  16: #033[92m0x00000000#033[0m  ....
0#012  17: #033[92m0x00000000#033[0m  ....  0#012#012Attributes Summary#012{'(
2) NDA_LLADDR': '00:02:00:00:00:09',#012 '( 3) NDA_CACHEINFO': (0, 0, 0, 0),#012
'( 9) NDA_MASTER': 299}

which is rather hard to interpret. So this patch modifes the nlpacket debug
output so that the user can specify whether or not color output should be used
by including an extra, optional parameter when instantiating a NetlinkPacket
object. The default is for color output, just like before this patch. But if
color output is not desired, then no VT100 control sequences will be output. Nor
will there be any newline characters embedded in the output.

The NetlinkManagerWithListener and NetlinkManager classes were also modified to
add the same optional use_color attribute, which defaults to True. Thus when
class members which instantiate NetlinkPacket objects are created the
appropriate value for the use_color attribute will be applied.

I also noticed that the default pid_offset of the NetlinkListener class was 2,
when it should have been 1. So I fixed that too.
This commit is contained in:
Scott Emery
2016-08-29 11:28:52 -07:00
committed by Julien Fortin
parent 9f25ff0dbd
commit a61d1777cd
3 changed files with 100 additions and 63 deletions

View File

@@ -164,7 +164,10 @@ def data_to_color_text(line_number, color, data, extra=''):
else:
in_ascii.append('.')
return ' %2d: \033[%dm0x%02x%02x%02x%02x\033[0m %s %s' % (line_number, color, c1, c2, c3, c4, ''.join(in_ascii), extra)
if color:
return ' %2d: \033[%dm0x%02x%02x%02x%02x\033[0m %s %s' % (line_number, color, c1, c2, c3, c4, ''.join(in_ascii), extra)
return ' %2d: 0x%02x%02x%02x%02x %s %s' % (line_number, c1, c2, c3, c4, ''.join(in_ascii), extra)
def padded_length(length):
@@ -1235,13 +1238,14 @@ class NetlinkPacket(object):
RTM_GETQDISC : 'RTM_GETQDISC'
}
def __init__(self, msgtype, debug, owner_logger=None):
def __init__(self, msgtype, debug, owner_logger=None, use_color=True):
self.msgtype = msgtype
self.attributes = {}
self.dump_buffer = ['']
self.line_number = 1
self.debug = debug
self.message = None
self.use_color = use_color
if owner_logger:
self.log = owner_logger
@@ -1346,9 +1350,11 @@ class NetlinkPacket(object):
header_data = self.header_data
# Print the netlink header in red
color = red
netlink_header_length = 16
self.dump_buffer.append(" \033[%dmNetlink Header\033[0m" % color)
color = red if self.use_color else None
color_start = "\033[%dm" % color if color else ""
color_end = "\033[0m" if color else ""
self.dump_buffer.append(" %sNetlink Header%s" % (color_start, color_end))
for x in range(0, netlink_header_length/4):
start = x * 4
@@ -1384,7 +1390,7 @@ class NetlinkPacket(object):
if self.debug:
self.dump_buffer.append(" Attributes")
color = green
color = green if self.use_color else None
data = self.msg_data[self.LEN:]
@@ -1413,10 +1419,11 @@ class NetlinkPacket(object):
self.line_number = attr.dump_lines(self.dump_buffer, self.line_number, color)
# Alternate back and forth between green and blue
if color == green:
color = blue
else:
color = green
if self.use_color:
if color == green:
color = blue
else:
color = green
data = data[attr_end:]
@@ -1484,6 +1491,14 @@ class NetlinkPacket(object):
(self, self.length, self.seq, self.pid, self.flags,
self.get_netlink_header_flags_string(self.msgtype, self.flags)))
def pretty_display_dict(self, dic, level):
for k,v in dic.iteritems():
if isinstance(v, dict):
self.log.debug(' '*level + str(k) + ':')
self.pretty_display_dict(v, level+1)
else:
self.log.debug(' '*level + str(k) + ': ' + str(v))
# Print the netlink message in hex. This is only used for debugging.
def dump(self, desc=None):
attr_string = {}
@@ -1495,8 +1510,18 @@ class NetlinkPacket(object):
key_string = "(%2d) %s" % (attr_type, self.get_attr_string(attr_type))
attr_string[key_string] = attr_obj.get_pretty_value()
self.log.debug("%s\n%s\n\nAttributes Summary\n%s\n" %
(desc, '\n'.join(self.dump_buffer), pformat(attr_string)))
if self.use_color:
self.log.debug("%s\n%s\n\nAttributes Summary\n%s\n" %
(desc, '\n'.join(self.dump_buffer), pformat(attr_string)))
else:
# Assume if we are not allowing color output we also don't want embedded
# newline characters in the output. Output each line individually.
self.log.debug(desc)
for line in self.dump_buffer:
self.log.debug(line)
self.log.debug("")
self.log.debug("Attributes Summary")
self.pretty_display_dict(attr_string, 1)
class Address(NetlinkPacket):
@@ -1557,8 +1582,8 @@ class Address(NetlinkPacket):
IFA_F_PERMANENT : 'IFA_F_PERMANENT'
}
def __init__(self, msgtype, debug=False, logger=None):
NetlinkPacket.__init__(self, msgtype, debug, logger)
def __init__(self, msgtype, debug=False, logger=None, use_color=True):
NetlinkPacket.__init__(self, msgtype, debug, logger, use_color)
self.PACK = '4Bi'
self.LEN = calcsize(self.PACK)
@@ -1573,8 +1598,10 @@ class Address(NetlinkPacket):
unpack(self.PACK, self.msg_data[:self.LEN])
if self.debug:
color = yellow
self.dump_buffer.append(" \033[%dmService Header\033[0m" % color)
color = yellow if self.use_color else None
color_start = "\033[%dm" % color if color else ""
color_end = "\033[0m" if color else ""
self.dump_buffer.append(" %sService Header%s" % (color_start, color_end))
for x in range(0, self.LEN/4):
if self.line_number == 5:
@@ -1670,8 +1697,8 @@ class Error(NetlinkPacket):
NLE_DUMP_INTR : 'NLE_DUMP_INTR'
}
def __init__(self, msgtype, debug=False, logger=None):
NetlinkPacket.__init__(self, msgtype, debug, logger)
def __init__(self, msgtype, debug=False, logger=None, use_color=True):
NetlinkPacket.__init__(self, msgtype, debug, logger, use_color)
self.PACK = '=iLHHLL'
self.LEN = calcsize(self.PACK)
@@ -1686,8 +1713,10 @@ class Error(NetlinkPacket):
unpack(self.PACK, self.msg_data[:self.LEN])
if self.debug:
color = yellow
self.dump_buffer.append(" \033[%dmService Header\033[0m" % color)
color = yellow if self.use_color else None
color_start = "\033[%dm" % color if color else ""
color_end = "\033[0m" if color else ""
self.dump_buffer.append(" %sService Header%s" % (color_start, color_end))
for x in range(0, self.LEN/4):
@@ -2328,8 +2357,8 @@ class Link(NetlinkPacket):
RTEXT_FILTER_SKIP_STATS : 'RTEXT_FILTER_SKIP_STATS'
}
def __init__(self, msgtype, debug=False, logger=None):
NetlinkPacket.__init__(self, msgtype, debug, logger)
def __init__(self, msgtype, debug=False, logger=None, use_color=True):
NetlinkPacket.__init__(self, msgtype, debug, logger, use_color)
self.PACK = 'BxHiII'
self.LEN = calcsize(self.PACK)
@@ -2379,8 +2408,11 @@ class Link(NetlinkPacket):
unpack(self.PACK, self.msg_data[:self.LEN])
if self.debug:
color = yellow
self.dump_buffer.append(" \033[%dmService Header\033[0m" % color)
color = yellow if self.use_color else None
color_start = "\033[%dm" % color if color else ""
color_end = "\033[0m" if color else ""
self.dump_buffer.append(" %sService Header%s" % (color_start, color_end))
for x in range(0, self.LEN/4):
if self.line_number == 5:
extra = "Family %s (%d), Device Type %s (%d - %s)" % \
@@ -2489,8 +2521,8 @@ class Neighbor(NetlinkPacket):
NUD_PERMANENT : 'NUD_PERMANENT'
}
def __init__(self, msgtype, debug=False, logger=None):
NetlinkPacket.__init__(self, msgtype, debug, logger)
def __init__(self, msgtype, debug=False, logger=None, use_color=True):
NetlinkPacket.__init__(self, msgtype, debug, logger, use_color)
self.PACK = 'BxxxiHBB'
self.LEN = calcsize(self.PACK)
@@ -2509,8 +2541,10 @@ class Neighbor(NetlinkPacket):
unpack(self.PACK, self.msg_data[:self.LEN])
if self.debug:
color = yellow
self.dump_buffer.append(" \033[%dmService Header\033[0m" % color)
color = yellow if self.use_color else None
color_start = "\033[%dm" % color if color else ""
color_end = "\033[0m" if color else ""
self.dump_buffer.append(" %sService Header%s" % (color_start, color_end))
for x in range(0, self.LEN/4):
if self.line_number == 5:
@@ -2714,8 +2748,8 @@ class Route(NetlinkPacket):
RTM_F_PREFIX : 'RTM_F_PREFIX'
}
def __init__(self, msgtype, debug=False, logger=None):
NetlinkPacket.__init__(self, msgtype, debug, logger)
def __init__(self, msgtype, debug=False, logger=None, use_color=True):
NetlinkPacket.__init__(self, msgtype, debug, logger, use_color)
self.PACK = '=8BI' # or is it 8Bi ?
self.LEN = calcsize(self.PACK)
self.family = None
@@ -2799,8 +2833,10 @@ class Route(NetlinkPacket):
unpack(self.PACK, self.msg_data[:self.LEN])
if self.debug:
color = yellow
self.dump_buffer.append(" \033[%dmService Header\033[0m" % color)
color = yellow if self.use_color else None
color_start = "\033[%dm" % color if color else ""
color_end = "\033[0m" if color else ""
self.dump_buffer.append(" %sService Header%s" % (color_start, color_end))
for x in range(0, self.LEN/4):
if self.line_number == 5: