[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r23410: {arm} added: log cropping based on time (requested by voidzero) fi (in arm/trunk: . src src/interface)
Author: atagar
Date: 2010-10-05 16:44:47 +0000 (Tue, 05 Oct 2010)
New Revision: 23410
Modified:
arm/trunk/TODO
arm/trunk/src/armrc.defaults
arm/trunk/src/interface/logPanel.py
Log:
added: log cropping based on time (requested by voidzero)
fix: cropping prepopulated events if it exceeds caching size
Modified: arm/trunk/TODO
===================================================================
--- arm/trunk/TODO 2010-10-05 10:12:02 UTC (rev 23409)
+++ arm/trunk/TODO 2010-10-05 16:44:47 UTC (rev 23410)
@@ -9,12 +9,14 @@
progress - /init and /util are done and /interface is partly done. Known
bugs are being fixed while refactoring.
- [ ] log panel
- - log cropping based on time (idea by voidzero)
+ [X] log panel
[ ] conf panel
- move torrc validation into util
- fetch text via getinfo rather than reading directly?
conn.get_info("config-text")
+ - improve parsing failure notice to give line number
+ just giving "[ARM-WARN] Unable to validate torrc" isn't very
+ helpful...
* release prep
* ask helix about steps for getting a deb and rpm included in the tor repo
* check performance of this version vs last version (general screen refresh
Modified: arm/trunk/src/armrc.defaults
===================================================================
--- arm/trunk/src/armrc.defaults 2010-10-05 10:12:02 UTC (rev 23409)
+++ arm/trunk/src/armrc.defaults 2010-10-05 16:44:47 UTC (rev 23410)
@@ -26,6 +26,9 @@
# showDuplicateEntries
# shows all log entries if true, otherwise collapses similar entries with an
# indicator for how much is hidden
+# entryDuration
+# number of days log entries are kept before being dropped (if zero then
+# they're kept until cropped due to caching limits)
# maxLinesPerEntry
# max number of lines to display for a single log entry
# prepopulate
@@ -39,6 +42,7 @@
features.log.showDateDividers true
features.log.showDuplicateEntries false
+features.log.entryDuration 7
features.log.maxLinesPerEntry 4
features.log.prepopulate true
features.log.prepopulateReadLimit 5000
Modified: arm/trunk/src/interface/logPanel.py
===================================================================
--- arm/trunk/src/interface/logPanel.py 2010-10-05 10:12:02 UTC (rev 23409)
+++ arm/trunk/src/interface/logPanel.py 2010-10-05 16:44:47 UTC (rev 23410)
@@ -36,11 +36,13 @@
RUNLEVELS = ["DEBUG", "INFO", "NOTICE", "WARN", "ERR"]
RUNLEVEL_EVENT_COLOR = {"DEBUG": "magenta", "INFO": "blue", "NOTICE": "green", "WARN": "yellow", "ERR": "red"}
DAYBREAK_EVENT = "DAYBREAK" # special event for marking when the date changes
+TIMEZONE_OFFSET = time.altzone if time.localtime()[8] else time.timezone
ENTRY_INDENT = 2 # spaces an entry's message is indented after the first line
DEFAULT_CONFIG = {"features.logFile": "",
"features.log.showDateDividers": True,
"features.log.showDuplicateEntries": False,
+ "features.log.entryDuration": 7,
"features.log.maxLinesPerEntry": 4,
"features.log.prepopulate": True,
"features.log.prepopulateReadLimit": 5000,
@@ -70,6 +72,18 @@
CACHED_DUPLICATES_ARGUMENTS = None # events
CACHED_DUPLICATES_RESULT = None
+def daysSince(timestamp=None):
+ """
+ Provides the number of days since the epoch converted to local time (rounded
+ down).
+
+ Arguments:
+ timestamp - unix timestamp to convert, current time if undefined
+ """
+
+ if timestamp == None: timestamp = time.time()
+ return int((timestamp - TIMEZONE_OFFSET) / 86400)
+
def expandEvents(eventAbbr):
"""
Expands event abbreviations to their full names. Beside mappings provided in
@@ -280,8 +294,7 @@
if not events: return []
newListing = []
- timezoneOffset = time.altzone if time.localtime()[8] else time.timezone
- currentDay = int((time.time() - timezoneOffset) / 86400)
+ currentDay = daysSince()
lastDay = currentDay
if CACHED_DAYBREAKS_ARGUMENTS[0] == events and \
@@ -289,9 +302,9 @@
return list(CACHED_DAYBREAKS_RESULT)
for entry in events:
- eventDay = int((entry.timestamp - timezoneOffset) / 86400) # days since epoch
+ eventDay = daysSince(entry.timestamp)
if eventDay != lastDay:
- markerTimestamp = (eventDay * 86400) + timezoneOffset
+ markerTimestamp = (eventDay * 86400) + TIMEZONE_OFFSET
newListing.append(LogEntry(markerTimestamp, DAYBREAK_EVENT, "", "white"))
newListing.append(entry)
@@ -507,8 +520,9 @@
self._halt = False # terminates thread if true
self._cond = threading.Condition() # used for pausing/resuming the thread
- # restricts concurrent write access to attributes used to draw the display:
- # msgLog, loggedEvents, regexFilter, scroll
+ # restricts concurrent write access to attributes used to draw the display
+ # and pausing:
+ # msgLog, loggedEvents, regexFilter, scroll, _pauseBuffer
self.valsLock = threading.RLock()
# cached parameters (invalidated if arguments for them change)
@@ -558,6 +572,9 @@
finally:
log.LOG_LOCK.release()
+ # crops events that are either too old, or more numerous than the caching size
+ self._trimEvents(self.msgLog)
+
# leaving lastContentHeight as being too low causes initialization problems
self.lastContentHeight = len(self.msgLog)
@@ -605,12 +622,14 @@
cacheSize = self._config["cache.logPanel.size"]
if self._isPaused:
+ self.valsLock.acquire()
self._pauseBuffer.insert(0, event)
- if len(self._pauseBuffer) > cacheSize: del self._pauseBuffer[cacheSize:]
+ self._trimEvents(self._pauseBuffer)
+ self.valsLock.release()
else:
self.valsLock.acquire()
self.msgLog.insert(0, event)
- if len(self.msgLog) > cacheSize: del self.msgLog[cacheSize:]
+ self._trimEvents(self.msgLog)
# notifies the display that it has new content
if not self.regexFilter or self.regexFilter.search(event.getDisplayMessage()):
@@ -875,12 +894,10 @@
responsive if additions are less frequent.
"""
- timezoneOffset = time.altzone if time.localtime()[8] else time.timezone
- currentTime = time.time()
-
# unix time for the start of the current day (local time), used so we
# can redraw when the date changes
- dayStartTime = currentTime - (currentTime - timezoneOffset) % 86400
+ currentTime = time.time()
+ dayStartTime = currentTime - (currentTime - TIMEZONE_OFFSET) % 86400
while not self._halt:
currentTime = time.time()
timeSinceReset = currentTime - self._lastUpdate
@@ -897,7 +914,7 @@
if not self._halt: self._cond.wait(sleepTime)
self._cond.release()
else:
- dayStartTime = currentTime - (currentTime - timezoneOffset) % 86400
+ dayStartTime = currentTime - (currentTime - TIMEZONE_OFFSET) % 86400
self.redraw(True)
def stop(self):
@@ -1009,3 +1026,30 @@
self.valsLock.release()
return panelLabel
+ def _trimEvents(self, eventListing):
+ """
+ Crops events that have either:
+ - grown beyond the cache limit
+ - outlived the configured log duration
+
+ """
+
+ self.valsLock.acquire()
+ cacheSize = self._config["cache.logPanel.size"]
+ if len(eventListing) > cacheSize: del eventListing[cacheSize:]
+
+ logTTL = self._config["features.log.entryDuration"]
+ if logTTL > 0:
+ currentDay = daysSince()
+
+ breakpoint = None # index at which to crop from
+ for i in range(len(eventListing) - 1, -1, -1):
+ daysSinceEvent = currentDay - daysSince(eventListing[i].timestamp)
+ if daysSinceEvent > logTTL: breakpoint = i # older than the ttl
+ else: break
+
+ # removes entries older than the ttl
+ if breakpoint != None: del eventListing[breakpoint:]
+
+ self.valsLock.release()
+