[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r12849: Add python logging support, better message templates, and su (in bridgedb/trunk: . lib/bridgedb)
Author: nickm
Date: 2007-12-17 22:34:02 -0500 (Mon, 17 Dec 2007)
New Revision: 12849
Modified:
bridgedb/trunk/
bridgedb/trunk/bridgedb.conf
bridgedb/trunk/lib/bridgedb/Bridges.py
bridgedb/trunk/lib/bridgedb/Dist.py
bridgedb/trunk/lib/bridgedb/Main.py
bridgedb/trunk/lib/bridgedb/Server.py
Log:
r17219@catbus: nickm | 2007-12-17 22:33:55 -0500
Add python logging support, better message templates, and support for partially empty rings.
Property changes on: bridgedb/trunk
___________________________________________________________________
svk:merge ticket from /bridgedb/trunk [r17219] on 8246c3cf-6607-4228-993b-4d95d33730f1
Modified: bridgedb/trunk/bridgedb.conf
===================================================================
--- bridgedb/trunk/bridgedb.conf 2007-12-18 03:34:00 UTC (rev 12848)
+++ bridgedb/trunk/bridgedb.conf 2007-12-18 03:34:02 UTC (rev 12849)
@@ -9,6 +9,11 @@
# Either a file in which to write our pid, or None
PIDFILE = "bridgedb.pid"
+# Either a file to log to, or None if we should log to the console.
+LOGFILE = "bridgedb.log"
+# One of "DEBUG", "INFO", "WARNING", "ERROR"...
+LOGLEVEL = "INFO"
+
# Files from which we read descriptors on start and SIGHUP
# XXXX SIGHUP not implemented.
BRIDGE_FILES = [ "./cached-descriptors", "./cached-descriptors.new" ]
Modified: bridgedb/trunk/lib/bridgedb/Bridges.py
===================================================================
--- bridgedb/trunk/lib/bridgedb/Bridges.py 2007-12-18 03:34:00 UTC (rev 12848)
+++ bridgedb/trunk/lib/bridgedb/Bridges.py 2007-12-18 03:34:02 UTC (rev 12849)
@@ -5,6 +5,7 @@
import binascii
import bisect
import hmac
+import logging
import re
import sha
import socket
@@ -153,6 +154,7 @@
self.hmac = get_hmac_fn(key, hex=False)
self.isSorted = False
self.sortedKeys = []
+ self.name = "Ring"
def __len__(self):
return len(self.bridgesByID)
@@ -165,6 +167,7 @@
self.isSorted = False
self.bridges[pos] = bridge
self.bridgesByID[id] = bridge
+ logging.debug("Adding %s to %s", bridge.getConfigLine(), self.name)
def sort(self):
if not self.isSorted:
@@ -270,7 +273,7 @@
class UnallocatedHolder(BridgeHolder):
def insert(self, bridge):
- pass
+ logging.debug("Leaving %s unallocated", bridge.getConfigLine())
def assignmentsArePersistent(self):
return False
Modified: bridgedb/trunk/lib/bridgedb/Dist.py
===================================================================
--- bridgedb/trunk/lib/bridgedb/Dist.py 2007-12-18 03:34:00 UTC (rev 12848)
+++ bridgedb/trunk/lib/bridgedb/Dist.py 2007-12-18 03:34:02 UTC (rev 12849)
@@ -4,6 +4,7 @@
import bridgedb.Bridges
+import logging
import re
import socket
@@ -24,6 +25,7 @@
for n in xrange(nClusters):
key1 = bridgedb.Bridges.get_hmac(key, "Order-Bridges-In-Ring-%d"%n)
self.rings.append( bridgedb.Bridges.BridgeRing(key1) )
+ self.rings[-1].name = "IP ring %s"%len(self.rings)
key2 = bridgedb.Bridges.get_hmac(key, "Assign-Bridges-To-Rings")
self.splitter = bridgedb.Bridges.FixedBridgeSplitter(key2, self.rings)
@@ -38,20 +40,25 @@
self.splitter.insert(bridge)
def getBridgesForIP(self, ip, epoch, N=1):
+ if not len(self.splitter):
+ return []
+
area = self.areaMapper(ip)
# Which bridge cluster should we look at?
- h = int( self.areaClusterHmac(area)[:8], 16 )
+ h = int( self.areaClusterHmac(area)[:8], 16)
clusterNum = h % len(self.rings)
ring = self.rings[clusterNum]
+ # If a ring is empty, consider the next.
+ while not len(ring):
+ clusterNum = (clusterNum + 1) % len(self.rings)
+ ring = self.rings[clusterNum]
# Now get the bridge.
pos = self.areaOrderHmac("<%s>%s" % (epoch, area))
return ring.getBridges(pos, N)
-
-
# These characters are the ones that RFC2822 allows.
#ASPECIAL = '!#$%&*+-/=?^_`{|}~'
#ASPECIAL += "\\\'"
@@ -129,6 +136,7 @@
key2 = bridgedb.Bridges.get_hmac(key, "Order-Bridges-In-Ring")
self.ring = bridgedb.Bridges.BridgeRing(key2)
+ self.ring.name = "email ring"
self.store = store
self.domainmap = domainmap
@@ -141,8 +149,11 @@
return [] #XXXX raise an exception.
if self.store.has_key(emailaddress):
result = []
- ids = self.store[emailaddress]
- for id in bridgedb.Bridges.chopString(ids, bridgedb.Bridges.ID_LEN):
+ ids_str = self.store[emailaddress]
+ ids = bridgedb.Bridges.chopString(ids_str, bridgedb.Bridges.ID_LEN)
+ logging.info("We've seen %r before. Sending the same %d bridges"
+ " as last time", emailaddress, len(ids))
+ for id in ids:
b = self.ring.getBridgeByID(id)
if b != None:
result.append(b)
@@ -165,4 +176,3 @@
print normal
except BadEmail, e:
print line, e
-
Modified: bridgedb/trunk/lib/bridgedb/Main.py
===================================================================
--- bridgedb/trunk/lib/bridgedb/Main.py 2007-12-18 03:34:00 UTC (rev 12848)
+++ bridgedb/trunk/lib/bridgedb/Main.py 2007-12-18 03:34:02 UTC (rev 12849)
@@ -6,6 +6,7 @@
import os
import signal
import sys
+import logging
from twisted.internet import reactor
@@ -22,6 +23,9 @@
RUN_IN_DIR = ".",
PIDFILE = "bridgedb.pid",
+ LOGFILE = None,
+ LOGLEVEL = "DEBUG",
+
BRIDGE_FILES = [ "./cached-descriptors", "./cached-descriptors.new" ],
BRIDGE_PURPOSE = "bridge",
DB_FILE = "./bridgedist.db",
@@ -53,6 +57,18 @@
RESERVED_SHARE=2,
)
+def configureLogging(cfg):
+ level = getattr(cfg, 'LOGLEVEL', 'WARNING')
+ level = getattr(logging, level)
+ extra = {}
+ if getattr(cfg, "LOGFILE"):
+ extra['filename'] = cfg.LOGFILE
+
+ logging.basicConfig(format='%(asctime)s [%(levelname)s] %(message)s',
+ datefmt="%b %d %H:%M:%S",
+ level=level,
+ **extra)
+
def getKey(fname):
"""Load the key stored in fname, or create a new 32-byte key and store
it in fname.
@@ -97,7 +113,7 @@
def startup(cfg):
cfg.BRIDGE_FILES = [ os.path.expanduser(fn) for fn in cfg.BRIDGE_FILES ]
for key in ("RUN_IN_DIR", "DB_FILE", "DB_LOG_FILE", "MASTER_KEY_FILE",
- "HTTPS_CERT_FILE", "HTTPS_KEY_FILE", "PIDFILE"):
+ "HTTPS_CERT_FILE", "HTTPS_KEY_FILE", "PIDFILE", "LOGFILE"):
v = getattr(cfg, key)
if v:
setattr(cfg, key, os.path.expanduser(v))
@@ -110,6 +126,8 @@
f.write("%s\n"%os.getpid())
f.close()
+ configureLogging(cfg)
+
key = getKey(cfg.MASTER_KEY_FILE)
dblogfile = None
emailDistributor = ipDistributor = None
@@ -149,14 +167,15 @@
Bridges.PrefixStore(store, "ls|"))
splitter.addTracker(stats)
- print "Loading bridges"
+ logging.info("Loading bridges")
load(cfg, splitter)
- print "%d bridges loaded" % len(splitter)
+ logging.info("%d bridges loaded", len(splitter))
if emailDistributor:
- print "%d for email" % len(emailDistributor.ring)
+ logging.info("%d for email", len(emailDistributor.ring))
if ipDistributor:
- print "%d for web:" % len(ipDistributor.splitter)
- print " by location set:", " ".join(str(len(r)) for r in ipDistributor.rings)
+ logging.info("%d for web:", len(ipDistributor.splitter))
+ logging.info(" by location set: %s",
+ " ".join(str(len(r)) for r in ipDistributor.rings))
if cfg.HTTPS_DIST and cfg.HTTPS_SHARE:
Server.addWebServer(cfg, ipDistributor, webSchedule)
@@ -172,7 +191,7 @@
signal.signal(signal.SIGHUP, _handleSIGHUP)
try:
- print "Starting reactors."
+ logging.info("Starting reactors.")
Server.runServers()
finally:
baseStore.close()
Modified: bridgedb/trunk/lib/bridgedb/Server.py
===================================================================
--- bridgedb/trunk/lib/bridgedb/Server.py 2007-12-18 03:34:00 UTC (rev 12848)
+++ bridgedb/trunk/lib/bridgedb/Server.py 2007-12-18 03:34:02 UTC (rev 12849)
@@ -82,6 +82,7 @@
else:
answer = "No bridges available."
+ logging.info("Replying to web request from %s", ip)
return HTML_MESSAGE_TEMPLAY % answer
def addWebServer(cfg, dist, sched):
@@ -125,13 +126,14 @@
elif clientFromAddr and clientFromAddr[1]:
clientAddr = clientFromAddr[1]
else:
- print "No from header. WTF."
+ logging.info("No From or Sender header on incoming mail.")
return None,None
for ln in lines:
if ln.strip().lower() in ("get bridges", "subject: get bridges"):
break
else:
- print "No request for bridges."
+ logging.info("Got a mail from %r with no bridge request; dropping",
+ clientAddr)
return None,None
try:
@@ -139,10 +141,11 @@
bridges = ctx.distributor.getBridgesForEmail(clientAddr,
interval, ctx.N)
except bridgedb.Dist.BadEmail, e:
- print "Bad email addr in request: %s"%e
+ logging.info("Got a mail from a bad email address %r: %s.",
+ clientAddr, e)
return None, None
if not bridges:
- print "No bridges available."
+ logging.warning("No bridges available to send to %r", clientAddr)
return None, None
# Generate the message.
@@ -164,7 +167,7 @@
return clientAddr, f
def replyToMail(lines, ctx):
- print "Got complete email; attempting to reply."
+ logging.info("Got a completed email; attempting to reply.")
sendToUser, response = getMailResponse(lines, ctx)
if response is None:
return
@@ -176,7 +179,7 @@
response,
d)
reactor.connectTCP(ctx.smtpServer, ctx.smtpPort, factory)
- print "Sending reply."
+ logging.info("Sending reply to %r", sendToUser)
return d
class MailContext: