[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r23378: {arm} added: option to save log events to a file change: bolding E (in arm/trunk: . src src/interface)
Author: atagar
Date: 2010-10-01 16:36:12 +0000 (Fri, 01 Oct 2010)
New Revision: 23378
Added:
arm/trunk/src/version.py
Modified:
arm/trunk/armrc.sample
arm/trunk/setup.py
arm/trunk/src/interface/logPanel.py
arm/trunk/src/starter.py
Log:
added: option to save log events to a file
change: bolding ERR events
Modified: arm/trunk/armrc.sample
===================================================================
--- arm/trunk/armrc.sample 2010-10-01 15:18:17 UTC (rev 23377)
+++ arm/trunk/armrc.sample 2010-10-01 16:36:12 UTC (rev 23378)
@@ -7,6 +7,10 @@
features.colorInterface true
+# If set, arm saves any log messages it reports while running to the given
+# path. This does not take filters into account or include prepopulated events.
+features.logPath
+
# log panel parameters
# showDateDividers: show borders with dates for entries from previous days
# maxLinesPerEntry: max number of lines to display for a single log entry
@@ -101,6 +105,8 @@
log.graph.bw.prepopulateFailure NOTICE
log.logPanel.prepopulateSuccess INFO
log.logPanel.prepopulateFailed WARN
+log.logPanel.logFileOpened NOTICE
+log.logPanel.logFileWriteFailed ERR
log.connLookupFailed INFO
log.connLookupFailover NOTICE
log.connLookupAbandon WARN
Modified: arm/trunk/setup.py
===================================================================
--- arm/trunk/setup.py 2010-10-01 15:18:17 UTC (rev 23377)
+++ arm/trunk/setup.py 2010-10-01 16:36:12 UTC (rev 23378)
@@ -1,10 +1,9 @@
#!/usr/bin/env python
import os
import sys
+from src.version import VERSION
from distutils.core import setup
-VERSION = '1.3.6_dev'
-
setup(name='arm',
version=VERSION,
description='Terminal tor status monitor',
Modified: arm/trunk/src/interface/logPanel.py
===================================================================
--- arm/trunk/src/interface/logPanel.py 2010-10-01 15:18:17 UTC (rev 23377)
+++ arm/trunk/src/interface/logPanel.py 2010-10-01 16:36:12 UTC (rev 23378)
@@ -5,12 +5,14 @@
"""
import time
+import os
import curses
import threading
from curses.ascii import isprint
from TorCtl import TorCtl
+from version import VERSION
from util import log, panel, sysTools, torTools, uiTools
TOR_EVENT_TYPES = {
@@ -36,14 +38,17 @@
DAYBREAK_EVENT = "DAYBREAK" # special event for marking when the date changes
ENTRY_INDENT = 2 # spaces an entry's message is indented after the first line
-DEFAULT_CONFIG = {"features.log.showDateDividers": True,
+DEFAULT_CONFIG = {"features.logPath": "",
+ "features.log.showDateDividers": True,
"features.log.maxLinesPerEntry": 4,
"features.log.prepopulate": True,
"features.log.prepopulateReadLimit": 5000,
"features.log.maxRefreshRate": 300,
"cache.logPanel.size": 1000,
"log.logPanel.prepopulateSuccess": log.INFO,
- "log.logPanel.prepopulateFailed": log.WARN}
+ "log.logPanel.prepopulateFailed": log.WARN,
+ "log.logPanel.logFileOpened": log.NOTICE,
+ "log.logPanel.logFileWriteFailed": log.ERR}
DUPLICATE_MSG = " [%i duplicate%s hidden]"
@@ -59,6 +64,7 @@
# [ARM_DEBUG] system call: ps
# [ARM_DEBUG] system call: netstat
# [ARM_DEBUG] GETINFO accounting/
+# [BW] READ: 0, WRITTEN: 0
COMMON_LOG_MESSAGES = {"NOTICE": [
"We stalled too much while trying to write",
"I learned some more directory information, but not enough to build a circuit",
@@ -71,7 +77,9 @@
"refresh rate: ",
"system call: ps",
"system call: netstat",
- "GETINFO accounting/"]
+ "GETINFO accounting/"],
+ "BW": [
+ "READ:"]
}
# cached values and the arguments that generated it for the getDaybreaks and
@@ -369,11 +377,20 @@
self.color = color
self._displayMessage = None
- def getDisplayMessage(self):
+ def getDisplayMessage(self, includeDate = False):
"""
Provides the entry's message for the log.
+
+ Arguments:
+ includeDate - appends the event's date to the start of the message
"""
+ if includeDate:
+ # not the common case so skip caching
+ entryTime = time.localtime(self.timestamp)
+ timeLabel = "%i/%i/%i %02i:%02i:%02i" % (entryTime[1], entryTime[2], entryTime[0], entryTime[3], entryTime[4], entryTime[5])
+ return "%s [%s] %s" % (timeLabel, self.type, self.msg)
+
if not self._displayMessage:
entryTime = time.localtime(self.timestamp)
self._displayMessage = "%02i:%02i:%02i [%s] %s" % (entryTime[3], entryTime[4], entryTime[5], self.type, self.msg)
@@ -480,6 +497,7 @@
self.loggedEvents = loggedEvents # events we're listening to
self.regexFilter = None # filter for presented log events (no filtering if None)
self.lastContentHeight = 0 # height of the rendered content when last drawn
+ self.logFile = None # file log messages are saved to (skipped if None)
self.scroll = 0
self._isPaused = False
self._pauseBuffer = [] # location where messages are buffered if paused
@@ -546,6 +564,21 @@
conn = torTools.getConn()
conn.addEventListener(TorEventObserver(self.registerEvent))
conn.addTorCtlListener(self._registerTorCtlEvent)
+
+ # opens log file if we'll be saving entries
+ if self._config["features.logPath"]:
+ logPath = self._config["features.logPath"]
+
+ # make dir if the path doesn't already exist
+ baseDir = os.path.dirname(logPath)
+ if not os.path.exists(baseDir): os.makedirs(baseDir)
+
+ try:
+ self.logFile = open(logPath, "a")
+ log.log(self._config["log.logPanel.logFileOpened"], "arm %s opening log file (%s)" % (VERSION, logPath))
+ except IOError, exc:
+ log.log(self._config["log.logPanel.logFileWriteFailed"], "Unable to write to log file: %s" % exc)
+ self.logFile = None
def registerEvent(self, event):
"""
@@ -560,6 +593,15 @@
# strips control characters to avoid screwing up the terminal
event.msg = "".join([char for char in event.msg if (isprint(char) or char == "\n")])
+ # note event in the log file if we're saving them
+ if self.logFile:
+ try:
+ self.logFile.write(event.getDisplayMessage(True) + "\n")
+ self.logFile.flush()
+ except IOError, exc:
+ log.log(self._config["log.logPanel.logFileWriteFailed"], "Unable to write to log file: %s" % exc)
+ self.logFile = None
+
cacheSize = self._config["cache.logPanel.size"]
if self._isPaused:
self._pauseBuffer.insert(0, event)
@@ -729,7 +771,8 @@
msgComp = entry.getDisplayMessage().split("\n")
for i in range(len(msgComp)):
- displayQueue.append((msgComp[i].strip(), uiTools.getColor(entry.color), i != len(msgComp) - 1))
+ font = curses.A_BOLD if "ERR" in entry.type else curses.A_NORMAL # emphasizes ERR messages
+ displayQueue.append((msgComp[i].strip(), font | uiTools.getColor(entry.color), i != len(msgComp) - 1))
if duplicateCount:
pluralLabel = "s" if duplicateCount > 1 else ""
Modified: arm/trunk/src/starter.py
===================================================================
--- arm/trunk/src/starter.py 2010-10-01 15:18:17 UTC (rev 23377)
+++ arm/trunk/src/starter.py 2010-10-01 16:36:12 UTC (rev 23378)
@@ -10,6 +10,7 @@
import sys
import getopt
+import version
import interface.controller
import interface.logPanel
import util.conf
@@ -23,9 +24,6 @@
import TorCtl.TorCtl
import TorCtl.TorUtil
-VERSION = "1.3.6_dev"
-LAST_MODIFIED = "July 7, 2010"
-
DEFAULT_CONFIG = os.path.expanduser("~/.armrc")
DEFAULTS = {"startup.controlPassword": None,
"startup.interface.ipAddress": "127.0.0.1",
@@ -110,7 +108,7 @@
elif opt in ("-e", "--event"):
param["startup.events"] = arg # set event flags
elif opt in ("-v", "--version"):
- print "arm version %s (released %s)\n" % (VERSION, LAST_MODIFIED)
+ print "arm version %s (released %s)\n" % (version.VERSION, version.LAST_MODIFIED)
sys.exit()
elif opt in ("-h", "--help"):
print HELP_MSG
Added: arm/trunk/src/version.py
===================================================================
--- arm/trunk/src/version.py (rev 0)
+++ arm/trunk/src/version.py 2010-10-01 16:36:12 UTC (rev 23378)
@@ -0,0 +1,7 @@
+"""
+Provides arm's version and release date.
+"""
+
+VERSION = '1.3.6_dev'
+LAST_MODIFIED = "July 7, 2010"
+