Make devserver record and present a detailed log of client events.
The devserver now stores a complete list of timestamped attributes, as
they are extracted from client messages. A log is indexed by client IP
addresses. Each of the events in a client's log is a set of attributes
and values, including the type of the event, a status code, the reported
board and OS version, and a timestamp. A dedicated HTTP API allows to
read client logs in JSON encoding. Previous client tracking
functionality is preserved for backward compatibility.
TEST=Unittests; complete update cycle of a chromebook client over
a network connection.
BUG=chromium-os:25028
Change-Id: I579d2daf5bf925bd1a75e1a27585f62a59442967
Reviewed-on: https://gerrit.chromium.org/gerrit/14090
Commit-Ready: Gilad Arnold <garnold@chromium.org>
Reviewed-by: Gilad Arnold <garnold@chromium.org>
Tested-by: Gilad Arnold <garnold@chromium.org>
diff --git a/devserver.py b/devserver.py
index 4e304ec..4185407 100755
--- a/devserver.py
+++ b/devserver.py
@@ -145,6 +145,13 @@
return updater.HandleHostInfoPing(ip)
@cherrypy.expose
+ def hostlog(self, ip):
+ """Returns a JSON object containing a log of events pertaining to a
+ particular host, or all hosts. Log events contain a timestamp and any
+ subset of the attributes listed for the hostinfo method."""
+ return updater.HandleHostLogPing(ip)
+
+ @cherrypy.expose
def setnextupdate(self, ip):
"""Allows the response to the next update ping from a host to be set.
@@ -243,14 +250,14 @@
@cherrypy.expose
def update(self, *args):
label = '/'.join(args)
- body_length = int(cherrypy.request.headers['Content-Length'])
+ body_length = int(cherrypy.request.headers.get('Content-Length', 0))
data = cherrypy.request.rfile.read(body_length)
return updater.HandleUpdatePing(data, label)
if __name__ == '__main__':
usage = 'usage: %prog [options]'
- parser = optparse.OptionParser(usage)
+ parser = optparse.OptionParser(usage=usage)
parser.add_option('--archive_dir', dest='archive_dir',
help='serve archived builds only.')
parser.add_option('--board', dest='board',
@@ -280,7 +287,7 @@
parser.add_option('--payload', dest='payload',
help='Use update payload from specified directory.')
parser.add_option('--port', default=8080,
- help='Port for the dev server to use.')
+ help='Port for the dev server to use (default: 8080).')
parser.add_option('--private_key', default=None,
help='Path to the private key in pem format.')
parser.add_option('--production', action='store_true', default=False,
@@ -295,7 +302,8 @@
parser.add_option('--validate_factory_config', action="store_true",
dest='validate_factory_config',
help='Validate factory config file, then exit.')
- parser.set_usage(parser.format_help())
+ parser.add_option('-l', '--logging', action="store_true", default=False,
+ help='Enable logging and reporting of update processes.')
(options, _) = parser.parse_args()
devserver_dir = os.path.dirname(os.path.abspath(sys.argv[0]))