Hi,

please ignore my former post about performance issue. The issue was in
another thread and not in the client server communication thread.

I would like to propose a threaded logger (here was actually my
problem) that uses a queue to speed up the client server interaction.

If the network is fast, then the writing of the server log is a bottle
neg. Either one switches off the logging or one uses a separate thread
for the logging. This is what I would like to propose.

The threaded logger would look like this:

class Logger(object):
    def __init__(self, name, console = sys.stderr, file = None,
show_name = True,
    show_pid = False, show_tid = False, show_date = False, show_time =
True,
    show_label = True, quiet = False):
        self.name = name
        self.console = console
        self.file = file
        self.show_name = show_name
        self.show_pid = show_pid
        self.show_tid = show_tid
        self.show_date = show_date
        self.show_time = show_time
        self.show_label = show_label
        self.quiet = quiet
        self.filter = set()
# additions for the threaded logger start here ==========
        self.QueueEvent=THG.Event()
        self.QueueEvent.clear()
        self.QueueLock=TH.allocate_lock()
        self.Queue=deque([])
        self.useQueue=True  #one might use an additional parameter
use_queue = True
        self.QueueThd=THG.Thread(target=self.DoQueue)
        self.QueueThd.setDaemon(True)
        self.QueueThd.start()

    def StopQueue(self):
        self.useQueue=False
        self.QueueEvent.set()
        self.QueueThd.join()

    def DoQueue(self):
        while self.useQueue:
            self.QueueEvent.wait()
            self.QueueEvent.clear()
            self.QueueLock.acquire()
            s=''
            while len(self.Queue):
                s+=self.Queue.popleft()
            self.QueueLock.release()
            self._Write(s)

    def Write(self,s):
        if self.useQueue:
            self.QueueLock.acquire()
            self.Queue.append(s)
            self.QueueLock.release()
            self.QueueEvent.set()
        else:
            self._Write(s)

    def _Write(self,text):
        if self.console:
            self.console.write(text)
        if self.file:
            self.file.write(text)
# additions for the threaded logger end here ==========

    def log(self, label, msg):
        if label in self.filter:
            return
        header = []
        if self.show_name:
            header.append("%-10s" % (self.name,))
        if self.show_label:
            header.append("%-10s" % (label,))
        if self.show_date:
            header.append(time.strftime("%Y-%m-%d"))
        if self.show_time:
            header.append(time.strftime("%H:%M:%S"))
        if self.show_pid:
            header.append("pid=%d" % (os.getpid(),))
        if self.show_tid:
            header.append("tid=%d" % (thread.get_ident(),))
        if header:
            header = "[" + " ".join(header) + "] "
        sep = "\n...." + " " * (len(header) - 4)
        text = header + sep.join(msg.splitlines()) + "\n"
# here the queued Write() procedure must be called
        self.Write(text)

    def debug(self, msg, *args, **kwargs):
        if self.quiet: return
        if args: msg %= args
        self.log("DEBUG", msg)
    def info(self, msg, *args, **kwargs):
        if self.quiet: return
        if args: msg %= args
        self.log("INFO", msg)
    def warn(self, msg, *args, **kwargs):
        if self.quiet: return
        if args: msg %= args
        self.log("WARNING", msg)
    def error(self, msg, *args, **kwargs):
        if args: msg %= args
        self.log("ERROR", msg)
    def traceback(self, excinfo = None):
        if not excinfo:
            excinfo = sys.exc_info()
        self.log("TRACEBACK",
"".join(traceback.format_exception(*excinfo)))

Greetings
Ruediger

Reply via email to