logclient.py
andlogserver.py
are just copied from ネットワーク越しの logging イベントの送受信 (Original).
Last active
May 24, 2016 07:12
-
-
Save tell/087de677c0d4340f4cae0ecfc6491fe0 to your computer and use it in GitHub Desktop.
Python logging on the socket
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
import logging, logging.handlers | |
rootLogger = logging.getLogger('') | |
rootLogger.setLevel(logging.DEBUG) | |
socketHandler = logging.handlers.SocketHandler('localhost', | |
logging.handlers.DEFAULT_TCP_LOGGING_PORT) | |
# don't bother with a formatter, since a socket handler sends the event as | |
# an unformatted pickle | |
rootLogger.addHandler(socketHandler) | |
# Now, we can log to the root logger, or any other logger. First the root... | |
logging.info('Jackdaws love my big sphinx of quartz.') | |
# Now, define a couple of other loggers which might represent areas in your | |
# application: | |
logger1 = logging.getLogger('myapp.area1') | |
logger2 = logging.getLogger('myapp.area2') | |
logger1.debug('Quick zephyrs blow, vexing daft Jim.') | |
logger1.info('How quickly daft jumping zebras vex.') | |
logger2.warning('Jail zesty vixen who grabbed pay from quack.') | |
logger2.error('The five boxing wizards jump quickly.') |
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
import pickle | |
import logging | |
import logging.handlers | |
import SocketServer | |
import struct | |
class LogRecordStreamHandler(SocketServer.StreamRequestHandler): | |
"""Handler for a streaming logging request. | |
This basically logs the record using whatever logging policy is | |
configured locally. | |
""" | |
def handle(self): | |
""" | |
Handle multiple requests - each expected to be a 4-byte length, | |
followed by the LogRecord in pickle format. Logs the record | |
according to whatever policy is configured locally. | |
""" | |
while True: | |
chunk = self.connection.recv(4) | |
if len(chunk) < 4: | |
break | |
slen = struct.unpack('>L', chunk)[0] | |
chunk = self.connection.recv(slen) | |
while len(chunk) < slen: | |
chunk = chunk + self.connection.recv(slen - len(chunk)) | |
obj = self.unPickle(chunk) | |
record = logging.makeLogRecord(obj) | |
self.handleLogRecord(record) | |
def unPickle(self, data): | |
return pickle.loads(data) | |
def handleLogRecord(self, record): | |
# if a name is specified, we use the named logger rather 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 wasting | |
# cycles and network bandwidth! | |
logger.handle(record) | |
class LogRecordSocketReceiver(SocketServer.ThreadingTCPServer): | |
""" | |
Simple TCP socket-based logging receiver suitable for testing. | |
""" | |
allow_reuse_address = 1 | |
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 | |
def serve_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 | |
def main(): | |
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() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment