Add logging hooks for things like runserver

This commit is contained in:
Andrew Godwin 2016-02-10 20:26:30 +00:00
parent 8c1b7f8a5a
commit ccd8d18da8
3 changed files with 31 additions and 4 deletions

View File

@ -132,6 +132,12 @@ class WebRequest(http.Request):
logger.debug("HTTP %s response for %s", message['status'], self.reply_channel) logger.debug("HTTP %s response for %s", message['status'], self.reply_channel)
else: else:
logger.debug("HTTP %s response chunk for %s", message['status'], self.reply_channel) logger.debug("HTTP %s response chunk for %s", message['status'], self.reply_channel)
self.factory.log_action("http", "complete", {
"path": self.path.decode("ascii"),
"status": message['status'],
"method": self.method.decode("ascii"),
"client": "%s:%s" % (self.client.host, self.client.port),
})
class HTTPProtocol(http.HTTPChannel): class HTTPProtocol(http.HTTPChannel):
@ -149,9 +155,10 @@ class HTTPFactory(http.HTTPFactory):
protocol = HTTPProtocol protocol = HTTPProtocol
def __init__(self, channel_layer): def __init__(self, server):
http.HTTPFactory.__init__(self) http.HTTPFactory.__init__(self)
self.channel_layer = channel_layer self.channel_layer = server.channel_layer
self.action_logger = server.action_logger
# We track all sub-protocols for response channel mapping # We track all sub-protocols for response channel mapping
self.reply_protocols = {} self.reply_protocols = {}
# Make a factory for WebSocket protocols # Make a factory for WebSocket protocols
@ -174,3 +181,10 @@ class HTTPFactory(http.HTTPFactory):
self.reply_protocols[channel].serverClose() self.reply_protocols[channel].serverClose()
else: else:
raise ValueError("Cannot dispatch message on channel %r" % channel) raise ValueError("Cannot dispatch message on channel %r" % channel)
def log_action(self, protocol, action, details):
"""
Dispatches to any registered action logger, if there is one.
"""
if self.action_logger:
self.action_logger(protocol, action, details)

View File

@ -6,14 +6,15 @@ from .http_protocol import HTTPFactory
class Server(object): class Server(object):
def __init__(self, channel_layer, host="127.0.0.1", port=8000, signal_handlers=True): def __init__(self, channel_layer, host="127.0.0.1", port=8000, signal_handlers=True, action_logger=None):
self.channel_layer = channel_layer self.channel_layer = channel_layer
self.host = host self.host = host
self.port = port self.port = port
self.signal_handlers = signal_handlers self.signal_handlers = signal_handlers
self.action_logger = action_logger
def run(self): def run(self):
self.factory = HTTPFactory(self.channel_layer) self.factory = HTTPFactory(self)
reactor.listenTCP(self.port, self.factory, interface=self.host) reactor.listenTCP(self.port, self.factory, interface=self.host)
reactor.callInThread(self.backend_reader) reactor.callInThread(self.backend_reader)
reactor.run(installSignalHandlers=self.signal_handlers) reactor.run(installSignalHandlers=self.signal_handlers)

View File

@ -21,6 +21,7 @@ class WebSocketProtocol(WebSocketServerProtocol):
self.channel_layer = self.main_factory.channel_layer self.channel_layer = self.main_factory.channel_layer
def onConnect(self, request): def onConnect(self, request):
self.request = request
try: try:
# Sanitize and decode headers # Sanitize and decode headers
clean_headers = {} clean_headers = {}
@ -55,6 +56,10 @@ class WebSocketProtocol(WebSocketServerProtocol):
# Send news that this channel is open # Send news that this channel is open
logger.debug("WebSocket open for %s", self.reply_channel) logger.debug("WebSocket open for %s", self.reply_channel)
self.channel_layer.send("websocket.connect", self.request_info) self.channel_layer.send("websocket.connect", self.request_info)
self.factory.log_action("websocket", "connected", {
"path": self.request.path,
"client": "%s:%s" % (self.transport.getPeer().host, self.transport.getPeer().port),
})
def onMessage(self, payload, isBinary): def onMessage(self, payload, isBinary):
logger.debug("WebSocket incoming packet on %s", self.reply_channel) logger.debug("WebSocket incoming packet on %s", self.reply_channel)
@ -92,6 +97,10 @@ class WebSocketProtocol(WebSocketServerProtocol):
self.channel_layer.send("websocket.disconnect", { self.channel_layer.send("websocket.disconnect", {
"reply_channel": self.reply_channel, "reply_channel": self.reply_channel,
}) })
self.factory.log_action("websocket", "disconnected", {
"path": self.request.path,
"client": "%s:%s" % (self.transport.getPeer().host, self.transport.getPeer().port),
})
else: else:
logger.debug("WebSocket closed before handshake established") logger.debug("WebSocket closed before handshake established")
@ -106,3 +115,6 @@ class WebSocketFactory(WebSocketServerFactory):
def __init__(self, main_factory, *args, **kwargs): def __init__(self, main_factory, *args, **kwargs):
self.main_factory = main_factory self.main_factory = main_factory
WebSocketServerFactory.__init__(self, *args, **kwargs) WebSocketServerFactory.__init__(self, *args, **kwargs)
def log_action(self, *args, **kwargs):
self.main_factory.log_action(*args, **kwargs)