Skip to content

Instantly share code, notes, and snippets.

@Ivlyth
Created July 22, 2015 06:43
Show Gist options
  • Save Ivlyth/263822365eac47ca001d to your computer and use it in GitHub Desktop.
Save Ivlyth/263822365eac47ca001d to your computer and use it in GitHub Desktop.
redis publish handler for logging, copy from logging.handler.SocketHandler
#!/usr/bin/env python
# -*- coding:utf-8 -*-
'''
Author : myth
Date : 15-7-22
Email : belongmyth at 163.com
'''
import logging
import redis
from redis import ConnectionError
import time
import struct
import cPickle
class RedisPublishHandler(logging.Handler):
def __init__(self, channel, host=u'localhost', port=6379, db=0, password=None):
logging.Handler.__init__(self)
self.channel = channel
self.host = host
self.port = port
self.db = db
self.password = password
self.client = None
self.closeOnError = 0
self.retryTime = None
self.retryStart = 1.0
self.retryMax = 30.0
self.retryFactor = 2.0
def makeClient(self):
c = redis.StrictRedis(host=self.host, port=self.port, db=self.db, password=self.password)
c.ping()
return c
def createClient(self):
now = time.time()
if self.retryTime is None:
attempt = 1
else:
attempt = (now >= self.retryTime)
if attempt:
try:
self.client = self.makeClient()
self.retryTime = None
except ConnectionError:
if self.retryTime is None:
self.retryPeriod = self.retryStart
else:
self.retryPeriod = self.retryPeriod * self.retryFactor
if self.retryPeriod > self.retryMax:
self.retryPeriod = self.retryMax
self.retryTime = now + self.retryPeriod
def send(self, s):
if self.client is None:
self.createClient()
if self.client:
try:
self.client.publish(self.channel, s)
except ConnectionError:
self.client = None
def makePickle(self, record):
ei = record.exc_info
if ei:
dummy = self.format(record)
record.exc_info = None
d = dict(record.__dict__)
d['msg'] = record.getMessage()
d['args'] = None
s = cPickle.dumps(d, 1)
if ei:
record.exc_info = ei # for next handler
slen = struct.pack(">L", len(s))
return slen + s
def handleError(self, record):
if self.closeOnError and self.client:
self.client = None #try to reconnect next time
else:
logging.Handler.handleError(self, record)
def emit(self, record):
try:
s = self.makePickle(record)
self.send(s)
except (KeyboardInterrupt, SystemExit):
raise
except:
self.handleError(record)
def close(self):
self.acquire()
try:
if self.client:
self.client = None
finally:
self.release()
logging.Handler.close(self)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment