Skip to content

Instantly share code, notes, and snippets.

@klovanone
Created July 4, 2019 22:48
Show Gist options
  • Save klovanone/3cbe4284f48ffdb1c22081cd24f9a9c7 to your computer and use it in GitHub Desktop.
Save klovanone/3cbe4284f48ffdb1c22081cd24f9a9c7 to your computer and use it in GitHub Desktop.
PubLRHandler class
class PUBLRHandler(logging.Handler):
"""A slightly more advanced logging handler that emits log messages through a PUB socket.
Differs from the standard PUBHandler in that it serializes the full python logger logrecord before sending to SUB.
Takes a PUB socket already bound to interfaces or an interface to bind to.
Example::
sock = context.socket(zmq.PUB)
sock.bind('inproc://log')
handler = PUBLRHandler(sock)
Or::
handler = PUBLRHandler('inproc://loc')
These are equivalent.
Log messages handled by this handler are broadcast with ZMQ topics
``this.root_topic`` comes first, followed by the log level
(DEBUG,INFO,etc.), followed by any additional subtopics specified in the
message by: log.debug("subtopic.subsub::the real message")
"""
root_topic = ""
socket = None
def __init__(self, interface_or_socket, context=None):
logging.Handler.__init__(self)
if isinstance(interface_or_socket, zmq.Socket):
self.socket = interface_or_socket
self.ctx = self.socket.context
else:
self.ctx = context or zmq.Context()
self.socket = self.ctx.socket(zmq.PUB)
self.socket.bind(interface_or_socket)
def serialize(self, record):
if record.exc_info:
# replace msg with exception information since exc_info cannot be easily converted into JSON
record.msg = record.msg + str(traceback.format_exception(record.exc_info[0], record.exc_info[1], record.exc_info[2]))
record.exc_info = None
return json.dumps(record.__dict__)
def emit(self, record):
"""Emit a log message on my socket."""
try:
topic, record.msg = record.msg.split(TOPIC_DELIM, 1)
except Exception:
topic = ""
try:
bmsg = cast_bytes(self.serialize(record))
except Exception:
self.handleError(record)
return
topic_list = []
if self.root_topic:
topic_list.append(self.root_topic)
topic_list.append(record.levelname)
if topic:
topic_list.append(topic)
btopic = b'.'.join(cast_bytes(t) for t in topic_list)
self.socket.send_multipart([btopic, bmsg])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment