class SipLogger(object): app = None call_id = None level = None write = None logfile = None discarded = 0 pid = None logger = None signal_handler = None def __init__(self, app, call_id="GLOBAL", logfile="/var/log/sip.log"): self.app = "/%s" % app self.call_id = call_id bend = os.environ.get("SIPLOG_BEND", "stderr").lower() if bend == "stderr": self.write = self.write_stderr elif bend == "none": self.write = self.donoting else: self.write = self.write_logfile self.wi_available = Condition() self.wi = [] if bend != "syslog": self.logger = AsyncLogger(app, self) self.logfile = os.environ.get("SIPLOG_LOGFILE_FILE", logfile) self.signal_handler = LogSignal(self, SIGUSR1, self.reopen) else: self.logger = AsyncLoggerSyslog(app, self) self.app = "" self.level = eval("SIPLOG_" + os.environ.get("SIPLOG_LVL", "INFO")) def donoting(self, *args, **kwargs): pass def write_stderr(self, *args, **kwargs): if kwargs.get("level", SIPLOG_INFO) < self.level: return sys.__stderr__.write(self.format(args, kwargs)) def write_logfile(self, *args, **kwargs): if kwargs.get("level", SIPLOG_INFO) < self.level: return discarded = False self.wi_available.acquire() if len(self.wi) > 1000: # Discard some items, as the writer doesn't seems to be able # to keep up pace with incoming requests self.discarded += len(self.wi) - 1000 self.wi = self.wi[-1000:] discarded = True self.wi.append(("write", args, kwargs)) self.wi_available.notify() self.wi_available.release() if discarded and self.discarded % 1000 == 0: print "SipLogger: discarded %d requests, I/O too slow" % self.discarded def format(self, args, kwargs): ltime = kwargs.get("ltime", None) if ltime == None: ltime = time() call_id = kwargs.get("call_id", self.call_id) if self.pid != None: pid = "[%d]" % self.pid else: pid = "" return "%s.%.3d/%s%s%s: %s\n" % ( strftime("%d %b %H:%M:%S", localtime(ltime)), (ltime % 1) * 1000, call_id, self.app, pid, reduce(lambda x, y: x + y, [str(x) for x in args]), ) def reopen(self, signum=None): self.wi_available.acquire() self.wi.append(("reopen", None, None)) self.wi_available.notify() self.wi_available.release() def shutdown(self): if self.logger == None: return if self.signal_handler != None: self.signal_handler.calcel() self.signal_handler = None self.logger.shutdown() self.logger = None