So I've got the following 3 classes that play the role of PUB(Publisher) and SUB(Subscriber).
formatters = {
logging.DEBUG: logging.Formatter("[%(name)s] %(message)s"),
logging.INFO: logging.Formatter("[%(name)s] %(message)s"),
logging.WARN: logging.Formatter("[%(name)s] %(message)s"),
logging.ERROR: logging.Formatter("[%(name)s] %(message)s"),
logging.CRITICAL: logging.Formatter("[%(name)s] %(message)s")
}
class PUBLogger:
def __init__(self, host, port = 5555, level = logging.DEBUG):
self._logger = logging.getLogger(__name__)
self._logger.setLevel(level)
self.ctx = zmq.Context()
self.pub = self.ctx.socket(zmq.PUB)
# self.pub.setsockopt(zmq.LINGER, 0)
self.pub.connect('tcp://{0}:{1}'.format(socket.gethostbyname(host), port))
self._handler = PUBHandler(self.pub)
self._handler.formatters = formatters
self._logger.addHandler(self._handler)
@property
def logger(self):
return self._logger
class SUBLogger:
def __init__(self,
ip,
port = 5555,
output_dir = '',
logfile_name = 'output.log',
stdout = False,
level = logging.DEBUG):
self.output_dir = output_dir
self._logger = logging.getLogger()
self._logger.setLevel(level)
self.ctx = zmq.Context()
self._sub = self.ctx.socket(zmq.SUB)
self._sub.bind('tcp://*:{1}'.format(ip, port))
self._sub.setsockopt_string(zmq.SUBSCRIBE, "")
formatter = logging.Formatter("%(asctime)s;%(levelname)s;%(funcName)s - %(message)s")
handler = handlers.RotatingFileHandler(os.path.join(output_dir, logfile_name), "w", 100 * 1024 * 1024, 10)
handler.setLevel(level)
handler.setFormatter(formatter)
self._logger.addHandler(handler)
if stdout is True:
handler_stdout = logging.StreamHandler(sys.stdout)
handler_stdout.setLevel(level)
handler_stdout.setFormatter(formatter)
self._logger.addHandler(handler_stdout)
@property
def sub(self):
return self._sub
@property
def logger(self):
return self._logger
class ThreadedLoggerSUB(Thread):
def __init__(self, ip, port = 5555, stdout = False, level = logging.DEBUG):
super(ThreadedLoggerSUB, self).__init__()
self._sub_logger = SUBLogger(ip, port, stdout = stdout, level = level)
self._event = Event()
self._ready = Event()
def run(self):
self._ready.set()
while not self._event.is_set():
try:
topic, message = self._sub_logger.sub.recv_multipart(flags = zmq.NOBLOCK)
if isinstance(topic, str):
log_msg = getattr(logging, topic.lower())
log_msg(message)
except zmq.ZMQError as zmq_error:
if zmq_error.errno == zmq.EAGAIN:
pass
self._sub_logger.sub.close()
def stop(self):
self._event.set()
def wait(self):
self._ready.wait()
In the main process where everything is coordinated, I start a ThreadedLoggerSUB thread that runs throughout the runtime of the program.
During its runtime, I spin a process within the program with a manager (from multiprocessing module) and in the constructor of the class (let's call the class ThreadToBeRunInSeparateProcess, it's basically inherited from Thread) that's getting instantiated in this separate process, a PUBLogger object is created and the logger object is returned from it.
The problem is that in roughly ~50% of the cases, the logger object in this separate process hangs when I want to log something. When it doesn't hang, I get to see the logs in the main process.
What's interesting is that if I run a ThreadToBeRunInSeparateProcess thread in the main process, it works just fine - I never get to see it hanging up, which tells me, there has got be something going on with the managers.
Do you have any idea why pyzmq is having this problem?
Thank you!
Robert
So I've got the following 3 classes that play the role of PUB(Publisher) and SUB(Subscriber).
In the main process where everything is coordinated, I start a
ThreadedLoggerSUBthread that runs throughout the runtime of the program.During its runtime, I spin a process within the program with a manager (from
multiprocessingmodule) and in the constructor of the class (let's call the classThreadToBeRunInSeparateProcess, it's basically inherited fromThread) that's getting instantiated in this separate process, aPUBLoggerobject is created and theloggerobject is returned from it.The problem is that in roughly ~50% of the cases, the
loggerobject in this separate process hangs when I want to log something. When it doesn't hang, I get to see the logs in the main process.What's interesting is that if I run a
ThreadToBeRunInSeparateProcessthread in the main process, it works just fine - I never get to see it hanging up, which tells me, there has got be something going on with the managers.Do you have any idea why
pyzmqis having this problem?Thank you!
Robert