[or-cvs] r20078: {arm} Miscellaneous fix and feature batch. added: relay's flags to (arm/trunk/interface)
atagar at seul.org
atagar at seul.org
Sat Jul 18 07:16:16 UTC 2009
Author: atagar
Date: 2009-07-18 03:16:16 -0400 (Sat, 18 Jul 2009)
New Revision: 20078
Modified:
arm/trunk/interface/confPanel.py
arm/trunk/interface/connPanel.py
arm/trunk/interface/controller.py
arm/trunk/interface/headerPanel.py
arm/trunk/interface/logPanel.py
Log:
Miscellaneous fix and feature batch.
added: relay's flags to the header
added: listing by relay nickname
added: additional event aliases and option for NEWCONSENSUS
fix: updates cached consensus mappings with NEWDESC and NEWCONSENSUS events
change: use constant "Listing" label for sorting rather than current view
change: removed 'reload torrc' option (deceptive and useless)
Modified: arm/trunk/interface/confPanel.py
===================================================================
--- arm/trunk/interface/confPanel.py 2009-07-18 06:07:13 UTC (rev 20077)
+++ arm/trunk/interface/confPanel.py 2009-07-18 07:16:16 UTC (rev 20078)
@@ -40,7 +40,6 @@
elif key == curses.KEY_PPAGE: self.scroll = max(self.scroll - pageHeight, 0)
elif key == curses.KEY_NPAGE: self.scroll = max(0, min(self.scroll + pageHeight, len(self.confContents) - pageHeight))
elif key == ord('n') or key == ord('N'): self.showLineNum = not self.showLineNum
- elif key == ord('r') or key == ord('R'): self.reset()
elif key == ord('s') or key == ord('S'):
self.stripComments = not self.stripComments
self.scroll = 0
Modified: arm/trunk/interface/connPanel.py
===================================================================
--- arm/trunk/interface/connPanel.py 2009-07-18 06:07:13 UTC (rev 20077)
+++ arm/trunk/interface/connPanel.py 2009-07-18 07:16:16 UTC (rev 20078)
@@ -10,17 +10,17 @@
import hostnameResolver
# enums for listing types
-LIST_IP, LIST_HOSTNAME, LIST_FINGERPRINT = range(3)
-LIST_LABEL = {LIST_IP: "IP", LIST_HOSTNAME: "Hostname", LIST_FINGERPRINT: "Fingerprint"}
+LIST_IP, LIST_HOSTNAME, LIST_FINGERPRINT, LIST_NICKNAME = range(4)
+LIST_LABEL = {LIST_IP: "IP Address", LIST_HOSTNAME: "Hostname", LIST_FINGERPRINT: "Fingerprint", LIST_NICKNAME: "Nickname"}
# enums for sorting types (note: ordering corresponds to SORT_TYPES for easy lookup)
# TODO: add ORD_BANDWIDTH -> (ORD_BANDWIDTH, "Bandwidth", lambda x, y: ???)
ORD_TYPE, ORD_FOREIGN_LISTING, ORD_SRC_LISTING, ORD_DST_LISTING, ORD_COUNTRY, ORD_FOREIGN_PORT, ORD_SRC_PORT, ORD_DST_PORT = range(8)
SORT_TYPES = [(ORD_TYPE, "Connection Type",
lambda x, y: TYPE_WEIGHTS[x[CONN_TYPE]] - TYPE_WEIGHTS[y[CONN_TYPE]]),
- (ORD_FOREIGN_LISTING, "* (Foreign)", None),
- (ORD_SRC_LISTING, "* (Source)", None),
- (ORD_DST_LISTING, "* (Dest.)", None),
+ (ORD_FOREIGN_LISTING, "Listing (Foreign)", None),
+ (ORD_SRC_LISTING, "Listing (Source)", None),
+ (ORD_DST_LISTING, "Listing (Dest.)", None),
(ORD_COUNTRY, "Country Code",
lambda x, y: cmp(x[CONN_COUNTRY], y[CONN_COUNTRY])),
(ORD_FOREIGN_PORT, "Port (Foreign)",
@@ -36,7 +36,34 @@
# enums for indexes of ConnPanel 'connections' fields
CONN_TYPE, CONN_L_IP, CONN_L_PORT, CONN_F_IP, CONN_F_PORT, CONN_COUNTRY = range(6)
-# provides bi-directional mapping of sorts with their associated labels (with getSortLabel)
+# provides bi-directional mapping of sorts with their associated labels
+def getSortLabel(sortType, withColor = False):
+ """
+ Provides label associated with a type of sorting. Throws ValueEror if no such
+ sort exists. If adding color formatting this wraps with the following mappings:
+ Connection Type red
+ Listing * blue
+ Port * green
+ Bandwidth cyan
+ Country Code yellow
+ """
+
+ for (type, label, func) in SORT_TYPES:
+ if sortType == type:
+ color = None
+
+ if withColor:
+ if label == "Connection Type": color = "red"
+ elif label.startswith("Listing"): color = "blue"
+ elif label.startswith("Port"): color = "green"
+ elif label == "Bandwidth": color = "cyan"
+ elif label == "Country Code": color = "yellow"
+
+ if color: return "<%s>%s</%s>" % (color, label, color)
+ else: return label
+
+ raise ValueError(sortType)
+
def getSortType(sortLabel):
"""
Provides sort type associated with a given label. Throws ValueEror if label
@@ -45,8 +72,6 @@
for (type, label, func) in SORT_TYPES:
if sortLabel == label: return type
- elif label.startswith("*"):
- if sortLabel in [label.replace("*", listingType) for listingType in LIST_LABEL.values()]: return type
raise ValueError(sortLabel)
class ConnPanel(TorCtl.PostEventListener, util.Panel):
@@ -66,7 +91,9 @@
self.isPaused = False
self.resolver = hostnameResolver.HostnameResolver()
self.fingerprintLookupCache = {} # chache of (ip, port) -> fingerprint
+ self.nicknameLookupCache = {} # chache of (ip, port) -> nickname
self.fingerprintMappings = _getFingerprintMappings(self.conn) # mappings of ip -> [(port, OR identity), ...]
+ self.nickname = self.conn.get_option("Nickname")[0][1]
# gets process id to make sure we get the correct netstat data
psCall = os.popen('ps -C tor -o pid')
@@ -92,13 +119,44 @@
self.reset()
# when consensus changes update fingerprint mappings
- def new_consensus_event(self, n):
- self.fingerprintLookupCache = {}
- self.fingerprintMappings = _getFingerprintMappings(self.conn)
+ def new_consensus_event(self, event):
+ self.fingerprintLookupCache.clear()
+ self.nicknameLookupCache.clear()
+ self.fingerprintMappings = _getFingerprintMappings(self.conn, event.nslist)
- def new_desc_event(self, d):
- self.fingerprintLookupCache = {}
- self.fingerprintMappings = _getFingerprintMappings(self.conn)
+ def new_desc_event(self, event):
+ for fingerprint in event.idlist:
+ # clears entries with this fingerprint from the cache
+ if fingerprint in self.fingerprintLookupCache.values():
+ invalidEntries = set(k for k, v in self.fingerprintLookupCache.iteritems() if v == fingerprint)
+ for k in invalidEntries:
+ # nicknameLookupCache keys are a subset of fingerprintLookupCache
+ del self.fingerprintLookupCache[k]
+ if k in self.nicknameLookupCache.keys(): del self.nicknameLookupCache[k]
+
+ # gets consensus data for the new description
+ nsData = self.conn.get_network_status("id/%s" % fingerprint)
+ if len(nsData) > 1:
+ # multiple records for fingerprint (shouldn't happen)
+ self.logger.monitor_event("WARN", "Multiple consensus entries for fingerprint: %s" % fingerprint)
+ return
+ nsEntry = nsData[0]
+
+ # updates fingerprintMappings with new data
+ if nsEntry.ip in self.fingerprintMappings.keys():
+ # if entry already exists with the same orport, remove it
+ orportMatch = None
+ for entryPort, entryFingerprint in self.fingerprintMappings[nsEntry.ip]:
+ if entryPort == nsEntry.orport:
+ orportMatch = (entryPort, entryFingerprint)
+ break
+
+ if orportMatch: self.fingerprintMappings[nsEntry.ip].remove(orportMatch)
+
+ # add new entry
+ self.fingerprintMappings[nsEntry.ip].append((nsEntry.orport, nsEntry.idhash))
+ else:
+ self.fingerprintMappings[nsEntry.ip] = [(nsEntry.orport, nsEntry.idhash)]
def reset(self):
"""
@@ -192,11 +250,16 @@
dst = "%s:%s" % (hostname if hostname else entry[CONN_F_IP], entry[CONN_F_PORT])
dst = "%-37s" % dst
- else:
+ elif self.listingType == LIST_FINGERPRINT:
src = "localhost "
if entry[CONN_TYPE] == "control": dst = "localhost"
else: dst = self.getFingerprint(entry[CONN_F_IP], entry[CONN_F_PORT])
dst = "%-41s" % dst
+ else:
+ src = "%-11s" % self.nickname
+ if entry[CONN_TYPE] == "control": dst = self.nickname
+ else: dst = self.getNickname(entry[CONN_F_IP], entry[CONN_F_PORT])
+ dst = "%-41s" % dst
if type == "inbound": src, dst = dst, src
self.addfstr(lineNum, 0, "<%s>%s --> %s (<b>%s</b>)</%s>" % (color, src, dst, type.upper(), color))
@@ -229,40 +292,26 @@
self.fingerprintLookupCache[(ipAddr, port)] = match
return match
- def setPaused(self, isPause):
+ def getNickname(self, ipAddr, port):
"""
- If true, prevents connection listing from being updated.
+ Attempts to provide the nickname for an ip/port combination, "UNKNOWN"
+ if this can't be determined.
"""
- self.isPaused = isPause
+ if (ipAddr, port) in self.nicknameLookupCache:
+ return self.nicknameLookupCache[(ipAddr, port)]
+ else:
+ match = self.getFingerprint(ipAddr, port)
+ if match != "UNKNOWN": match = self.conn.get_network_status("id/%s" % match)[0].nickname
+ self.nicknameLookupCache[(ipAddr, port)] = match
+ return match
- def getSortLabel(self, sortType, withColor = False):
+ def setPaused(self, isPause):
"""
- Provides label associated with a type of sorting. Throws ValueEror if no such
- sort exists. If adding color formatting this wraps with the following mappings:
- Connection Type red
- [Listing] * blue
- Port * green
- Bandwidth cyan
- Country Code yellow
+ If true, prevents connection listing from being updated.
"""
- for (type, label, func) in SORT_TYPES:
- if sortType == type:
- color = None
-
- if withColor:
- if label == "Connection Type": color = "red"
- elif label.startswith("*"): color = "blue"
- elif label.startswith("Port"): color = "green"
- elif label == "Bandwidth": color = "cyan"
- elif label == "Country Code": color = "yellow"
-
- if label.startswith("*"): label = label.replace("*", LIST_LABEL[self.listingType])
- if color: return "<%s>%s</%s>" % (color, label, color)
- else: return label
-
- raise ValueError(sortType)
+ self.isPaused = isPause
def sortConnections(self):
"""
@@ -281,10 +330,13 @@
listingWrapper = lambda ip, port: _ipToInt(ip)
elif self.listingType == LIST_HOSTNAME:
# alphanumeric hostnames followed by unresolved IP addresses
- listingWrapper = lambda ip, port: self.resolver.resolve(ip).upper() if self.resolver.resolve(ip) else "ZZZZZ%099i" % _ipToInt(ip)
+ listingWrapper = lambda ip, port: self.resolver.resolve(ip).upper() if self.resolver.resolve(ip) else "zzzzz%099i" % _ipToInt(ip)
elif self.listingType == LIST_FINGERPRINT:
# alphanumeric fingerprints followed by UNKNOWN entries
- listingWrapper = lambda ip, port: self.getFingerprint(ip, port) if self.getFingerprint(ip, port) != "UNKNOWN" else "ZZZZZ%099i" % _ipToInt(ip)
+ listingWrapper = lambda ip, port: self.getFingerprint(ip, port) if self.getFingerprint(ip, port) != "UNKNOWN" else "zzzzz%099i" % _ipToInt(ip)
+ elif self.listingType == LIST_NICKNAME:
+ # alphanumeric nicknames followed by Unnamed then UNKNOWN entries
+ listingWrapper = lambda ip, port: self.getNickname(ip, port) if self.getNickname(ip, port) not in ("UNKNOWN", "Unnamed") else "zzzzz%i%099i" % (0 if self.getNickname(ip, port) == "Unnamed" else 1, _ipToInt(ip))
for entry in self.sortOrdering:
if entry == ORD_FOREIGN_LISTING:
@@ -312,18 +364,16 @@
return total
# uses consensus data to map IP addresses to port / fingerprint combinations
-def _getFingerprintMappings(conn):
+def _getFingerprintMappings(conn, nsList = None):
ipToFingerprint = {}
- try:
- lastIp, lastPort = None, None
- for line in conn.get_info("desc/all-recent")["desc/all-recent"].split("\n"):
- if line.startswith("router "): lastIp, lastPort = line.split()[2], line.split()[3]
- elif line.startswith("opt fingerprint "):
- fingerprint = "".join(line.split()[2:])
- if lastIp in ipToFingerprint.keys(): ipToFingerprint[lastIp].append((lastPort, fingerprint))
- else: ipToFingerprint[lastIp] = [(lastPort, fingerprint)]
- except TorCtl.TorCtlClosed: pass
+ if not nsList:
+ try: nsList = conn.get_network_status()
+ except TorCtl.TorCtlClosed: nsList = []
+ for entry in nsList:
+ if entry.ip in ipToFingerprint.keys(): ipToFingerprint[entry.ip].append((entry.orport, entry.idhex))
+ else: ipToFingerprint[entry.ip] = [(entry.orport, entry.idhex)]
+
return ipToFingerprint
Modified: arm/trunk/interface/controller.py
===================================================================
--- arm/trunk/interface/controller.py 2009-07-18 06:07:13 UTC (rev 20077)
+++ arm/trunk/interface/controller.py 2009-07-18 07:16:16 UTC (rev 20078)
@@ -35,6 +35,9 @@
PAGE_COUNT = 3 # all page numbering is internally represented as 0-indexed
# TODO: page for configuration information
+# events needed for panels other than the event log
+REQ_EVENTS = ["BW", "NEWDESC", "NEWCONSENSUS"]
+
class ControlPanel(util.Panel):
""" Draws single line label for interface controls. """
@@ -98,7 +101,7 @@
try:
# adds BW events if not already included (so bandwidth monitor will work)
# removes UNKNOWN since not an actual event type
- connEvents = loggedEvents.union(set(["BW"]))
+ connEvents = loggedEvents.union(set(REQ_EVENTS))
connEvents.discard("UNKNOWN")
conn.set_events(connEvents)
eventsSet = True
@@ -255,11 +258,7 @@
popup.addstr(2, 2, "page up: scroll up a page")
popup.addstr(2, 41, "page down: scroll down a page")
- listingEnum = panels["conn"].listingType
- if listingEnum == connPanel.LIST_IP: listingType = "ip address"
- elif listingEnum == connPanel.LIST_HOSTNAME: listingType = "hostname"
- else: listingType = "fingerprint"
-
+ listingType = connPanel.LIST_LABEL[panels["conn"].listingType].lower()
popup.addfstr(3, 2, "l: listed identity (<b>%s</b>)" % listingType)
allowDnsLabel = "allow" if panels["conn"].allowDNS else "disallow"
@@ -277,8 +276,6 @@
lineNumLabel = "on" if panels["torrc"].showLineNum else "off"
popup.addfstr(3, 41, "n: line numbering (<b>%s</b>)" % lineNumLabel)
-
- popup.addfstr(4, 2, "r: reload torrc")
popup.addstr(7, 2, "Press any key...")
@@ -316,7 +313,7 @@
popup.addstr(0, 0, "Event Types:", util.LABEL_ATTR)
lineNum = 1
for line in logPanel.EVENT_LISTING.split("\n"):
- line = " " + line.strip()
+ line = line[6:]
popup.addstr(lineNum, 0, line)
lineNum += 1
popup.refresh()
@@ -348,7 +345,7 @@
cursesLock.release()
elif (page == 1 and (key == ord('l') or key == ord('L'))) or (key == 27 and panels["conn"].listingType == connPanel.LIST_HOSTNAME and panels["control"].resolvingCounter != -1):
# either pressed 'l' on connection listing or canceling hostname resolution (esc on any page)
- panels["conn"].listingType = (panels["conn"].listingType + 1) % 3
+ panels["conn"].listingType = (panels["conn"].listingType + 1) % len(connPanel.LIST_LABEL)
if panels["conn"].listingType == connPanel.LIST_HOSTNAME:
curses.halfdelay(10) # refreshes display every second until done resolving
@@ -376,18 +373,12 @@
# listing of inital ordering
prevOrdering = "<b>Current Order: "
- for sort in panels["conn"].sortOrdering: prevOrdering += panels["conn"].getSortLabel(sort, True) + ", "
+ for sort in panels["conn"].sortOrdering: prevOrdering += connPanel.getSortLabel(sort, True) + ", "
prevOrdering = prevOrdering[:-2] + "</b>"
# Makes listing of all options
options = []
- for (type, label, func) in connPanel.SORT_TYPES:
- label = panels["conn"].getSortLabel(type)
-
- # replaces 'Fingerprint' listings with shorter description
- if label.startswith("Fingerprint"): label = label.replace("Fingerprint", "Tor ID")
-
- options.append(label)
+ for (type, label, func) in connPanel.SORT_TYPES: options.append(connPanel.getSortLabel(type))
options.append("Cancel")
while len(selections) < 3:
@@ -399,7 +390,7 @@
# provides new ordering
newOrdering = "<b>New Order: "
if selections:
- for sort in selections: newOrdering += panels["conn"].getSortLabel(sort, True) + ", "
+ for sort in selections: newOrdering += connPanel.getSortLabel(sort, True) + ", "
newOrdering = newOrdering[:-2] + "</b>"
else: newOrdering += "</b>"
popup.addfstr(2, 2, newOrdering)
Modified: arm/trunk/interface/headerPanel.py
===================================================================
--- arm/trunk/interface/headerPanel.py 2009-07-18 06:07:13 UTC (rev 20077)
+++ arm/trunk/interface/headerPanel.py 2009-07-18 07:16:16 UTC (rev 20078)
@@ -9,6 +9,11 @@
import util
+FLAG_COLORS = {"Authority": "white", "BadExit": "red", "BadDirectory": "red", "Exit": "cyan",
+ "Fast": "yellow", "Guard": "green", "HSDir": "magenta", "Named": "blue",
+ "Stable": "blue", "Running": "yellow", "Unnamed": "magenta", "Valid": "green",
+ "V2Dir": "cyan", "V3Dir": "white"}
+
class HeaderPanel(util.Panel):
"""
Draws top area containing static information.
@@ -26,7 +31,7 @@
"""
def __init__(self, lock, conn):
- util.Panel.__init__(self, lock, 5)
+ util.Panel.__init__(self, lock, 6)
self.vals = [] # mapping of information to be presented
self.conn = conn # Tor control port connection
self.isPaused = False
@@ -69,17 +74,15 @@
# Line 4 (fingerprint)
self.addstr(3, 0, "fingerprint: %s" % self.vals["fingerprint"])
+ # Line 5 (flags)
+ flagLine = "flags: "
+ for flag in self.vals["flags"]:
+ flagColor = FLAG_COLORS[flag] if flag in FLAG_COLORS.keys() else "white"
+ flagLine += "<b><%s>%s</%s></b>, " % (flagColor, flag, flagColor)
- # Lines 3-5
- #self.addstr(3, 0, "Config: %s" % self.vals["config-file"])
- #exitPolicy = self.vals["ExitPolicy"]
+ if len(self.vals["flags"]) > 0: flagLine = flagLine[:-2]
+ self.addfstr(4, 0, flagLine)
- # adds note when default exit policy is appended
- #if exitPolicy == None: exitPolicy = "<default>"
- #elif not exitPolicy.endswith("accept *:*") and not exitPolicy.endswith("reject *:*"):
- # exitPolicy += ", <default>"
- #self.addstr(4, 0, "Exit Policy: %s" % exitPolicy)
-
self.refresh()
def setPaused(self, isPause):
@@ -93,10 +96,10 @@
"""
Updates mapping of static Tor settings and system information to their
corresponding string values. Keys include:
- info - version, config-file, *address, *fingerprint
+ info - version, *address, *fingerprint, *flags
sys - sys-name, sys-os, sys-version
ps - *%cpu, *rss, *%mem, *pid, *etime
- config - Nickname, ORPort, DirPort, ControlPort, ExitPolicy
+ config - Nickname, ORPort, DirPort, ControlPort
config booleans - IsPasswordAuthSet, IsCookieAuthSet, IsAccountingEnabled
* volatile parameter that'll be reset (otherwise won't be checked if
@@ -114,7 +117,7 @@
self.vals["sys-version"] = unameVals[2]
# parameters from the user's torrc
- configFields = ["Nickname", "ORPort", "DirPort", "ControlPort", "ExitPolicy"]
+ configFields = ["Nickname", "ORPort", "DirPort", "ControlPort"]
self.vals.update(dict([(key, self.conn.get_option(key)[0][1]) for key in configFields]))
# simply keeps booleans for if authentication info is set
@@ -134,6 +137,13 @@
# Can be caused if tor crashed
if not self.vals[param]: self.vals[param] = "Unknown"
+ # flags held by relay
+ self.vals["flags"] = []
+ if self.vals["fingerprint"] != "Unknown":
+ try: self.vals["flags"] = self.conn.get_network_status("id/%s" % self.vals["fingerprint"])[0].flags
+ except TorCtl.TorCtlClosed: pass
+ except socket.error: pass
+
# ps call provides header followed by params for tor
psParams = ["%cpu", "rss", "%mem", "pid", "etime"]
psCall = os.popen('ps -C %s -o %s' % ("tor", ",".join(psParams)))
Modified: arm/trunk/interface/logPanel.py
===================================================================
--- arm/trunk/interface/logPanel.py 2009-07-18 06:07:13 UTC (rev 20077)
+++ arm/trunk/interface/logPanel.py 2009-07-18 07:16:16 UTC (rev 20078)
@@ -13,18 +13,21 @@
RUNLEVEL_EVENT_COLOR = {"DEBUG": "magenta", "INFO": "blue", "NOTICE": "green", "WARN": "yellow", "ERR": "red"}
EVENT_TYPES = {
- "d": "DEBUG", "a": "ADDRMAP", "l": "NEWDESC", "u": "AUTHDIR_NEWDESCS",
- "i": "INFO", "b": "BW", "m": "NS", "v": "CLIENTS_SEEN",
- "n": "NOTICE", "c": "CIRC", "o": "ORCONN", "x": "STATUS_GENERAL",
- "w": "WARN", "f": "DESCCHANGED", "s": "STREAM", "y": "STATUS_CLIENT",
- "e": "ERR", "g": "GUARD", "t": "STREAM_BW", "z": "STATUS_SERVER"}
+ "d": "DEBUG", "a": "ADDRMAP", "l": "NEWDESC", "v": "AUTHDIR_NEWDESCS",
+ "i": "INFO", "b": "BW", "m": "NS", "x": "STATUS_GENERAL",
+ "n": "NOTICE", "c": "CIRC", "o": "ORCONN", "y": "STATUS_CLIENT",
+ "w": "WARN", "f": "DESCCHANGED", "s": "STREAM", "z": "STATUS_SERVER",
+ "e": "ERR", "g": "GUARD", "t": "STREAM_BW",
+ "k": "NEWCONSENSUS", "u": "CLIENTS_SEEN"}
-EVENT_LISTING = """ d DEBUG a ADDRMAP l NEWDESC u AUTHDIR_NEWDESCS
- i INFO b BW m NS v CLIENTS_SEEN
- n NOTICE c CIRC o ORCONN x STATUS_GENERAL
- w WARN f DESCCHANGED s STREAM y STATUS_CLIENT
- e ERR g GUARD t STREAM_BW z STATUS_SERVER
- Aliases: A All Events U Unknown Events R Runlevels (dinwe)"""
+EVENT_LISTING = """ d DEBUG a ADDRMAP l NEWDESC v AUTHDIR_NEWDESCS
+ i INFO b BW m NS x STATUS_GENERAL
+ n NOTICE c CIRC o ORCONN y STATUS_CLIENT
+ w WARN f DESCCHANGED s STREAM z STATUS_SERVER
+ e ERR g GUARD t STREAM_BW
+ k NEWCONSENSUS u CLIENTS_SEEN
+ Aliases: A All Events X No Events U Unknown Events
+ DINWE Runlevel and higher severity"""
def expandEvents(eventAbbr):
"""
@@ -46,10 +49,15 @@
expandedEvents = set(EVENT_TYPES.values())
expandedEvents.add("UNKNOWN")
break
- elif flag == "U":
- expandedEvents.add("UNKNOWN")
- elif flag == "R":
- expandedEvents = expandedEvents.union(set(["DEBUG", "INFO", "NOTICE", "WARN", "ERR"]))
+ elif flag == "X":
+ expandedEvents = set()
+ break
+ elif flag == "U": expandedEvents.add("UNKNOWN")
+ elif flag == "D": expandedEvents = expandedEvents.union(set(["DEBUG", "INFO", "NOTICE", "WARN", "ERR"]))
+ elif flag == "I": expandedEvents = expandedEvents.union(set(["INFO", "NOTICE", "WARN", "ERR"]))
+ elif flag == "N": expandedEvents = expandedEvents.union(set(["NOTICE", "WARN", "ERR"]))
+ elif flag == "W": expandedEvents = expandedEvents.union(set(["WARN", "ERR"]))
+ elif flag == "E": expandedEvents.add("ERR")
elif flag in EVENT_TYPES:
expandedEvents.add(EVENT_TYPES[flag])
else:
@@ -70,7 +78,7 @@
self.isPaused = False
self.pauseBuffer = [] # location where messages are buffered if paused
self.loggedEvents = loggedEvents # events we're listening to
- self.lastHeartbeat = time.time() # time of last BW event
+ self.lastHeartbeat = time.time() # time of last event
# Listens for all event types and redirects to registerEvent
def circ_status_event(self, event):
@@ -104,15 +112,16 @@
self.registerEvent("STREAM_BW", "DEBUG -> ID: %s READ: %s WRITTEN: %s" % (type(event.strm_id), type(event.bytes_read), type(event.bytes_written)), "white")
def bandwidth_event(self, event):
- self.lastHeartbeat = time.time()
+ self.lastHeartbeat = time.time() # ensures heartbeat at least once a second
if "BW" in self.loggedEvents: self.registerEvent("BW", "READ: %i, WRITTEN: %i" % (event.read, event.written), "cyan")
def msg_event(self, event):
self.registerEvent(event.level, event.msg, RUNLEVEL_EVENT_COLOR[event.level])
def new_desc_event(self, event):
- idlistStr = [str(item) for item in event.idlist]
- self.registerEvent("NEWDESC", ", ".join(idlistStr), "white")
+ if "NEWDESC" in self.loggedEvents:
+ idlistStr = [str(item) for item in event.idlist]
+ self.registerEvent("NEWDESC", ", ".join(idlistStr), "white")
def address_mapped_event(self, event):
self.registerEvent("ADDRMAP", "%s, %s -> %s" % (event.when, event.from_addr, event.to_addr), "white")
@@ -126,10 +135,11 @@
self.registerEvent("NS", "Listed (%i): %s" % (len(event.nslist), msg), "blue")
def new_consensus_event(self, event):
- msg = ""
- for ns in event.nslist:
- msg += ", %s (%s:%i)" % (ns.nickname, ns.ip, ns.orport)
- self.registerEvent("NEWCONSENSUS", "Listed (%i): %s" % (len(event.nslist), msg), "magenta")
+ if "NEWCONSENSUS" in self.loggedEvents:
+ msg = ""
+ for ns in event.nslist:
+ msg += ", %s (%s:%i)" % (ns.nickname, ns.ip, ns.orport)
+ self.registerEvent("NEWCONSENSUS", "Listed (%i): %s" % (len(event.nslist), msg), "magenta")
def unknown_event(self, event):
if "UNKNOWN" in self.loggedEvents: self.registerEvent("UNKNOWN", event.event_string, "red")
@@ -143,6 +153,8 @@
Notes event and redraws log. If paused it's held in a temporary buffer.
"""
+ self.lastHeartbeat = time.time()
+
# strips control characters to avoid screwing up the terminal
msg = "".join([char for char in msg if isprint(char)])
@@ -222,7 +234,9 @@
def getHeartbeat(self):
"""
- Provides the number of seconds since the last BW event.
+ Provides the number of seconds since the last registered event (this always
+ listens to BW events so should be less than a second if relay's still
+ responsive).
"""
return time.time() - self.lastHeartbeat
More information about the tor-commits
mailing list