blob: e4b54c3988bf7e218a2d2b5090c7e19b3fc6265d [file] [log] [blame]
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
import SocketServer
import socket
import json
class LogMessageServer(SocketServer.TCPServer):
def __init__(self, server_address, logger, message_callback=None, timeout=3):
SocketServer.TCPServer.__init__(self, server_address, LogMessageHandler)
self._logger = logger
self._message_callback = message_callback
self.timeout = timeout
class LogMessageHandler(SocketServer.BaseRequestHandler):
"""Processes output from a connected log source, logging to an
existing logger upon receipt of a well-formed log messsage."""
def handle(self):
"""Continually listens for log messages."""
self._partial_message = ''
self.request.settimeout(self.server.timeout)
while True:
try:
data = self.request.recv(1024)
if not data:
return
self.process_message(data)
except socket.timeout:
return
def process_message(self, data):
"""Processes data from a connected log source. Messages are assumed
to be newline delimited, and generally well-formed JSON."""
for part in data.split('\n'):
msg_string = self._partial_message + part
try:
msg = json.loads(msg_string)
self._partial_message = ''
self.server._logger.log_structured(msg.get('action', 'UNKNOWN'), msg)
if self.server._message_callback:
self.server._message_callback()
except ValueError:
self._partial_message = msg_string