Created
July 22, 2015 06:43
-
-
Save Ivlyth/263822365eac47ca001d to your computer and use it in GitHub Desktop.
redis publish handler for logging, copy from logging.handler.SocketHandler
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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