Example #1
0
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