[tor-commits] [nyx/master] Register stem/nyx events from before curses starts
atagar at torproject.org
atagar at torproject.org
Tue May 5 05:42:06 UTC 2015
commit 59b6dabb2ce64684069a1a9fa796a586302acb23
Author: Damian Johnson <atagar at torproject.org>
Date: Mon Apr 27 09:07:42 2015 -0700
Register stem/nyx events from before curses starts
Recording events from when the log panel is imported, rather than after curses
starts (which misses a lot of potentially interesting events).
---
nyx/log_panel.py | 121 +++++++++++++++++++++++++-----------------------------
nyx/util/log.py | 2 +-
2 files changed, 57 insertions(+), 66 deletions(-)
diff --git a/nyx/log_panel.py b/nyx/log_panel.py
index fe75e18..3bfa739 100644
--- a/nyx/log_panel.py
+++ b/nyx/log_panel.py
@@ -8,7 +8,6 @@ import re
import os
import time
import curses
-import logging
import threading
import stem
@@ -64,6 +63,13 @@ CONTENT_HEIGHT_REDRAW_THRESHOLD = 3
MAX_REGEX_FILTERS = 5
+# Log buffer so we start collecting stem/nyx events when imported. This is used
+# to make our LogPanel when curses initializes.
+
+stem_logger = stem.util.log.get_logger()
+NYX_LOGGER = log.LogBuffer(log.Runlevel.DEBUG, yield_records = True)
+stem_logger.addHandler(NYX_LOGGER)
+
def log_file_path():
for log_entry in tor_controller().get_conf('Log', [], True):
@@ -73,7 +79,7 @@ def log_file_path():
return CONFIG['tor.chroot'] + entry_comp[2]
-class LogPanel(panel.Panel, threading.Thread, logging.Handler):
+class LogPanel(panel.Panel, threading.Thread):
"""
Listens for and displays tor, nyx, and stem events. This can prepopulate
from tor's log file if it exists.
@@ -81,13 +87,6 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler):
def __init__(self, stdscr, logged_events):
panel.Panel.__init__(self, stdscr, 'log', 0)
- logging.Handler.__init__(self, level = log.logging_level(log.DEBUG))
-
- self.setFormatter(logging.Formatter(
- fmt = '%(asctime)s [%(levelname)s] %(message)s',
- datefmt = '%m/%d/%Y %H:%M:%S'),
- )
-
threading.Thread.__init__(self)
self.setDaemon(True)
@@ -155,6 +154,13 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler):
except ValueError as exc:
log.info(str(exc))
+ # stop logging to NYX_LOGGER, adding its event backlog and future ones
+
+ for event in NYX_LOGGER:
+ self._register_nyx_event(event)
+
+ NYX_LOGGER.emit = self._register_nyx_event
+
# leaving last_content_height as being too low causes initialization problems
self.last_content_height = len(self._msg_log)
@@ -191,15 +197,6 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler):
log.error('Unable to write to log file: %s' % exc)
self.log_file = None
- stem_logger = log.get_logger()
- stem_logger.addHandler(self)
-
- def emit(self, record):
- if record.levelname == 'WARNING':
- record.levelname = 'WARN'
-
- self.register_event(LogEntry(int(record.created), 'NYX_%s' % record.levelname, record.msg))
-
def set_duplicate_visability(self, is_visible):
"""
Sets if duplicate log entries are collaped or expanded.
@@ -212,51 +209,6 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler):
nyx_config = conf.get_config('nyx')
nyx_config.set('features.log.showDuplicateEntries', str(is_visible))
- def register_tor_event(self, event):
- """
- Translates a stem.response.event.Event instance into a LogEvent, and calls
- register_event().
- """
-
- msg = ' '.join(str(event).split(' ')[1:])
-
- if isinstance(event, stem.response.events.BandwidthEvent):
- msg = 'READ: %i, WRITTEN: %i' % (event.read, event.written)
- elif isinstance(event, stem.response.events.LogEvent):
- msg = event.message
-
- self.register_event(LogEntry(event.arrived_at, event.type, msg))
-
- def register_event(self, event):
- """
- Notes event and redraws log. If paused it's held in a temporary buffer.
-
- Arguments:
- event - LogEntry for the event that occurred
- """
-
- if event.type not in self.logged_events:
- return
-
- # note event in the log file if we're saving them
-
- if self.log_file:
- try:
- self.log_file.write(event.display_message + '\n')
- self.log_file.flush()
- except IOError as exc:
- log.error('Unable to write to log file: %s' % exc.strerror)
- self.log_file = None
-
- with self.vals_lock:
- self._msg_log.add(event.timestamp, event.type, event.message)
-
- # notifies the display that it has new content
-
- if not self.regex_filter or self.regex_filter.search(event.display_message):
- with self._cond:
- self._cond.notifyAll()
-
def set_logged_events(self, event_types):
"""
Sets the event types recognized by the panel.
@@ -761,14 +713,53 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler):
tor_events.update(set(nyx.arguments.missing_event_types()))
controller = tor_controller()
- controller.remove_event_listener(self.register_tor_event)
+ controller.remove_event_listener(self._register_tor_event)
for event_type in list(tor_events):
try:
- controller.add_event_listener(self.register_tor_event, event_type)
+ controller.add_event_listener(self._register_tor_event, event_type)
except stem.ProtocolError:
tor_events.remove(event_type)
# provides back the input set minus events we failed to set
return sorted(tor_events.union(nyx_events))
+
+ def _register_tor_event(self, event):
+ msg = ' '.join(str(event).split(' ')[1:])
+
+ if isinstance(event, stem.response.events.BandwidthEvent):
+ msg = 'READ: %i, WRITTEN: %i' % (event.read, event.written)
+ elif isinstance(event, stem.response.events.LogEvent):
+ msg = event.message
+
+ self._register_event(LogEntry(event.arrived_at, event.type, msg))
+
+ def _register_nyx_event(self, record):
+ if record.levelname == 'WARNING':
+ record.levelname = 'WARN'
+
+ self._register_event(LogEntry(int(record.created), 'NYX_%s' % record.levelname, record.msg))
+
+ def _register_event(self, event):
+ if event.type not in self.logged_events:
+ return
+
+ # note event in the log file if we're saving them
+
+ if self.log_file:
+ try:
+ self.log_file.write(event.display_message + '\n')
+ self.log_file.flush()
+ except IOError as exc:
+ log.error('Unable to write to log file: %s' % exc.strerror)
+ self.log_file = None
+
+ with self.vals_lock:
+ self._msg_log.add(event.timestamp, event.type, event.message)
+
+ # notifies the display that it has new content
+
+ if not self.regex_filter or self.regex_filter.search(event.display_message):
+ with self._cond:
+ self._cond.notifyAll()
diff --git a/nyx/util/log.py b/nyx/util/log.py
index 42c7ed5..279a390 100644
--- a/nyx/util/log.py
+++ b/nyx/util/log.py
@@ -39,7 +39,7 @@ def condense_runlevels(*events):
"""
Provides runlevel events with condensed. For example...
- >>> condense_runlevels(['DEBUG', 'NOTICE', 'WARN', 'ERR', 'NYX_NOTICE', 'NYX_WARN', 'NYX_ERR', 'BW'])
+ >>> condense_runlevels('DEBUG', 'NOTICE', 'WARN', 'ERR', 'NYX_NOTICE', 'NYX_WARN', 'NYX_ERR', 'BW')
['TOR/NYX NOTICE-ERROR', 'DEBUG', 'BW']
:param list events: event types to be condensed
More information about the tor-commits
mailing list