From 899dca48051ba988d33cc4fa556016bde08876d7 Mon Sep 17 00:00:00 2001 From: Marko Kreen Date: Thu, 5 Apr 2012 14:04:26 +0300 Subject: skylog: stop using standard SysLogHandler, it's broken It fails to handle unicode strings - it puts BOM in wrong place. Wrap logging.handlers implementation in class that simply drops the BOM addition. --- python/skytools/skylog.py | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) (limited to 'python/skytools/skylog.py') diff --git a/python/skytools/skylog.py b/python/skytools/skylog.py index 330de053..354ef916 100644 --- a/python/skytools/skylog.py +++ b/python/skytools/skylog.py @@ -232,7 +232,48 @@ class LogDBHandler(logging.handlers.SocketHandler): query = "select * from log.add(%s, %s, %s)" logcur.execute(query, [type, service, msg]) -# send messages to syslog +# fix unicode bug in SysLogHandler +class SysLogHandler(logging.handlers.SysLogHandler): + """Fixes unicode bug in logging.handlers.SysLogHandler.""" + + def emit(self, record): + """ + Emit a record. + + The record is formatted, and then sent to the syslog server. If + exception information is present, it is NOT sent to the server. + """ + msg = self.format(record) + '\000' + """ + We need to convert record level to lowercase, maybe this will + change in the future. + """ + prio = '<%d>' % self.encodePriority(self.facility, + self.mapPriority(record.levelname)) + # Message is a string. Convert to bytes as required by RFC 5424 + if type(msg) is unicode: + msg = msg.encode('utf-8') + ## this puts BOM in wrong place + #if codecs: + # msg = codecs.BOM_UTF8 + msg + msg = prio + msg + try: + if self.unixsocket: + try: + self.socket.send(msg) + except socket.error: + self._connect_unixsocket(self.address) + self.socket.send(msg) + elif self.socktype == socket.SOCK_DGRAM: + self.socket.sendto(msg, self.address) + else: + self.socket.sendall(msg) + except (KeyboardInterrupt, SystemExit): + raise + except: + self.handleError(record) + + class SysLogHostnameHandler(logging.handlers.SysLogHandler): """Slightly modified standard SysLogHandler - sends also hostname and service type""" @@ -243,6 +284,8 @@ class SysLogHostnameHandler(logging.handlers.SysLogHandler): _hostname, _service_name, msg) + if type(msg) is unicode: + msg = msg.encode('utf-8') try: if self.unixsocket: try: -- cgit v1.2.3