launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #19729
[Merge] lp:~wgrant/turnip/pack-logging into lp:turnip
William Grant has proposed merging lp:~wgrant/turnip/pack-logging into lp:turnip.
Commit message:
Give each pack frontend request an ID, and log it through the stack.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~wgrant/turnip/pack-logging/+merge/277545
Give each pack frontend request an ID, and log it through the stack. It's now vaguely possible to see what the services are doing, though there are a few iterations to go.
--
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wgrant/turnip/pack-logging into lp:turnip.
=== modified file 'turnip/pack/git.py'
--- turnip/pack/git.py 2015-06-02 12:52:50 +0000
+++ turnip/pack/git.py 2015-11-16 10:04:20 +0000
@@ -12,12 +12,14 @@
from twisted.internet import (
defer,
+ error,
protocol,
reactor,
)
from twisted.internet.interfaces import IHalfCloseableProtocol
# twisted.web.xmlrpc doesn't exist for Python 3 yet, but the non-XML-RPC
# bits of this module work.
+from twisted.logger import Logger
if sys.version_info.major < 3: # noqa
from twisted.web import xmlrpc
from zope.interface import implementer
@@ -40,6 +42,15 @@
SAFE_PARAMS = frozenset(['host'])
+class RequestIDLogger(Logger):
+
+ def emit(self, level, format=None, **kwargs):
+ request_id = getattr(self.source, 'request_id')
+ if format is not None and request_id is not None:
+ format = '[request-id=%s] %s' % (request_id, format)
+ super(RequestIDLogger, self).emit(level, format=format, **kwargs)
+
+
class UnstoppableProducerWrapper(object):
"""An `IPushProducer` that won't be stopped.
@@ -149,6 +160,15 @@
got_request = False
peer = None
+ request_id = None
+ log = RequestIDLogger()
+
+ def extractRequestMeta(self, command, pathname, params):
+ self.request_id = params.get(b'turnip-request-id', None)
+ self.log.info(
+ "Request received: '{command} {pathname}', params={params}",
+ command=command, pathname=pathname, params=params)
+
def requestReceived(self, command, pathname, params):
"""Begin handling of a git pack protocol request.
@@ -180,7 +200,15 @@
def rawDataReceived(self, data):
self.peer.sendRawData(data)
+ def connectionLost(self, reason):
+ if reason.check(error.ConnectionDone):
+ self.log.info('Connection closed.')
+ else:
+ self.log.failure('Connection closed.', failure=reason)
+ PackProxyProtocol.connectionLost(self, reason)
+
def die(self, message):
+ self.log.info('Dying: {message}', message=message)
self.sendPacket(ERROR_PREFIX + message + b'\n')
self.transport.loseConnection()
@@ -291,6 +319,9 @@
self.command = command
self.pathname = pathname
self.params = params
+ self.log.info(
+ "Connecting to backend: {command} {pathname}, params={params}",
+ command=command, pathname=pathname, params=params)
client = self.client_factory(self)
reactor.connectTCP(
self.factory.backend_host, self.factory.backend_port, client)
@@ -315,6 +346,8 @@
hookrpc_key = None
def requestReceived(self, command, raw_pathname, params):
+ self.extractRequestMeta(command, raw_pathname, params)
+
path = compose_path(self.factory.root, raw_pathname)
if command == b'git-upload-pack':
subcmd = b'upload-pack'
@@ -344,6 +377,7 @@
env[b'TURNIP_HOOK_RPC_SOCK'] = self.factory.hookrpc_sock
env[b'TURNIP_HOOK_RPC_KEY'] = self.hookrpc_key
+ self.log.info('Spawning {args}', args=args)
self.peer = GitProcessProtocol(self)
reactor.spawnProcess(self.peer, cmd, args, env=env)
@@ -380,16 +414,20 @@
@defer.inlineCallbacks
def requestReceived(self, command, pathname, params):
+ self.extractRequestMeta(command, pathname, params)
permission = b'read' if command == b'git-upload-pack' else b'write'
proxy = xmlrpc.Proxy(self.factory.virtinfo_endpoint, allowNone=True)
try:
can_authenticate = (
params.get(b'turnip-can-authenticate') == b'yes')
auth_uid = params.get(b'turnip-authenticated-uid')
+ self.log.info("Translating request.")
translated = yield proxy.callRemote(
b'translatePath', pathname, permission,
int(auth_uid) if auth_uid is not None else None,
can_authenticate)
+ self.log.info(
+ "Translation result: {translated}", translated=translated)
if 'trailing' in translated and translated['trailing']:
self.die(
VIRT_ERROR_PREFIX +
@@ -450,9 +488,14 @@
client_factory = PackFrontendClientFactory
def requestReceived(self, command, pathname, params):
+ self.request_id = str(uuid.uuid4())
+ self.log.info(
+ "Request received: '{command} {pathname}', params={params}",
+ command=command, pathname=pathname, params=params)
if set(params.keys()) - SAFE_PARAMS:
self.die(b'Illegal request parameters')
return
+ params[b'turnip-request-id'] = self.request_id
self.connectToBackend(command, pathname, params)
=== modified file 'turnip/pack/http.py'
--- turnip/pack/http.py 2015-11-12 11:43:11 +0000
+++ turnip/pack/http.py 2015-11-16 10:04:20 +0000
@@ -17,6 +17,7 @@
except ImportError:
from urllib import urlencode
import sys
+import uuid
import zlib
from openid.consumer import consumer
@@ -258,7 +259,10 @@
The turnip-authenticated-user parameter is set to the username
returned by the virt service, if any.
"""
- params = {b'turnip-can-authenticate': b'yes'}
+ params = {
+ b'turnip-can-authenticate': b'yes',
+ b'turnip-request-id': str(uuid.uuid4()),
+ }
authenticated_user, authenticated_uid = yield self.authenticateUser(
request)
if authenticated_user:
=== modified file 'turnip/pack/ssh.py'
--- turnip/pack/ssh.py 2015-07-09 12:23:31 +0000
+++ turnip/pack/ssh.py 2015-11-16 10:04:20 +0000
@@ -8,6 +8,7 @@
)
import shlex
+import uuid
from lazr.sshserver.auth import (
LaunchpadAvatar,
@@ -151,6 +152,7 @@
params = {
b'turnip-authenticated-user': self.avatar.username.encode('utf-8'),
b'turnip-authenticated-uid': str(self.avatar.user_id),
+ b'turnip-request-id': str(uuid.uuid4()),
}
d = defer.Deferred()
client_factory = factory(service, path, params, ssh_protocol, d)
Follow ups