Python performs multi-process operations and logs each process on a log server, or part of an application's internal process.
As it is part of the application's internal process, I would like to complete this log server process successfully when I close the application.
The log server process cannot be successfully terminated because the following parts of the reference code cannot be answered while waiting for socket reception:
chunk=self.connection.recv(slen)
I think I should turn the loop with receive buffer checks like the empty method of Queue, but is there such a mechanism?
Python Document Logging Cookbook
Send and receive logging events across the network
Keep the receiving end source code in the Logging Cookbook.
import pickle
import logging
import logging.handlers
import socketserver
import structure
classLogRecordStreamHandler(socketserver.StreamRequestHandler):
"""Handler for a streaming logging request."
This basic logs the record using whatver logging policy is
configured locally.
"""
default(self):
"""
Handle multiple requests-each expected to be a 4-byte length,
followed by the LogRecord in pickle format. Logs the record
recording to whatver policy is configured locally.
"""
while True:
chunk=self.connection.recv(4)
iflen(chunk)<4:
break
slen=structure.unpack('>L', chunk) [0]
chunk=self.connection.recv(slen)
whilelen(chunk)<slen:
chunk=chunk+self.connection.recv(slen-len(chunk))
obj=self.unPickle(chunk)
record=logging.makeLogRecord(obj)
self.handleLogRecord(record)
defunPickle (self, data):
return pickle.loads(data)
defaultLogRecord (self, record):
# if a name is specified, we use the named logger than the one
# implied by the record.
if self.server.logname is not None:
name = self.server.logname
else:
name=record.name
logger=logging.getLogger(name)
# N.B.EVERY record gets logged.This is because Logger.handle
# is normally called AFTER logger-level filtering. If you want
# to do filtering, do it at the client end to save washing
# cycles and network bandwidth!
logger.handle(record)
classLogRecordSocketReceiver(socketserver.ThreadingTCPServer):
"""
Simple TCP socket-based logging receiver suite for testing.
"""
allow_reuse_address = True
def__init__(self, host='localhost',
port = logging.handlers.DEFAULT_TCP_LOGGING_PORT,
handler=LogRecordStreamHandler):
socketserver.ThreadingTCPServer.__init__(self, (host, port), handler)
self.abort = 0
self.timeout = 1
self.logname = None
defserve_until_stopped(self):
import select
abort = 0
while not abort:
rd,wr,ex = select.select([self.socket.fileno(),
[], [],
self.timeout)
if rd:
self.handle_request()
abort = self.abort
defmain():
logging.basicConfig(
format='%(relativeCreated)5d%(name)-15s%(levelname)-8s%(message)s')
tcpserver=LogRecordSocketReceiver()
print('About to start TCP server...')
tcpserver.serve_until_stopped()
if__name__=='__main__':
main()
As I mentioned in the comment, is the waiting list for socket reception chunk=self.connection.recv(slen)
?
Are you actually waiting in the rd,wr,ex=select.select([self.socket.fileno(),...
section?
If so, for example, could you register a signal handler and send a signal from the main process to end the process?
classLogRecordSocketReceiver(socketserver.ThreadingTCPServer):
has a message processing looped defserve_until_stopped(self):
while not absolute: loop continuity conditions and finally abort=selfode.
If you add the
def_init__(...
to register the signal handler at the end of def_init__(...
and set the self.abort
flag in the signal handler, and send a signal from the main process, the log server process should end normally.
def__init__(self, host='localhost',
port = logging.handlers.DEFAULT_TCP_LOGGING_PORT,
handler=LogRecordStreamHandler):
socketserver.ThreadingTCPServer.__init__(self, (host, port), handler)
self.abort = 0
self.timeout = 1
self.logname = None
signal.signal(signal.SIGINT,self.signal_handler)####Signal handler registration
def signal_handler(self, signum, stack):####Signal handler
self.abort=1###abort flag setting
defserve_until_stopped(self):
import select
abort = 0
while not abort:
rd,wr,ex = select.select([self.socket.fileno(),
[], [],
self.timeout)
if rd:
self.handle_request()
abort = self.abort
However, it seems that there are many operating conditions and restrictions in the Windows environment.
signal.signal(signalnum, handler)
Does this not concern the operating system?
If the thread is enabled, this function can only be run from the main thread.If you try to run this function from any other thread, a ValueError exception occurs.
This is a reminder for Windows
On Windows, signal() can only be called with SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM, or SIBREAK.A ValueError will be raised in any other case. Note that not all systems defined the same set of signal names; an AttributeError will be made as a sign is not required.
On Windows, signal() can only be invoked on SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM, or SIGBREAK. Otherwise, a ValueError will occur. Note that not all systems define the same set of signal names. AttributeError occurs if the signal name is not defined as a SIG* module level constant.
This article, too.
Not receiving Python signals in a Windows environment
See @sayuri's answer
2022-09-30 21:55
If you have any answers or tips
Popular Tags
python x 4647
android x 1593
java x 1494
javascript x 1427
c x 927
c++ x 878
ruby-on-rails x 696
php x 692
python3 x 685
html x 656
Popular Questions
1557 When building Fast API+Uvicorn environment with PyInstaller, console=False results in an error
1009 Error in x, y, and format string must not be None
1052 Uncaught (inpromise) Error on Electron: An object could not be cloned
869 GDB gets version error when attempting to debug with the Presense SDK (IDE)
© 2025 OneMinuteCode. All rights reserved.