From 2bb944e2d76c4bd434e36bbafe1d29522a1a75d4 Mon Sep 17 00:00:00 2001 From: Feng Shengqin Date: Fri, 3 Mar 2017 10:24:46 +0800 Subject: [PATCH] Container logs is not good user experience Zun only supports stdout and stderr arguments, users need more options like tail, since, time period etc. Change-Id: I150e9c1bd8e4099d575624b1e0cbed7b00f63c35 Closes-Bug: #1667182 --- zunclient/osc/v1/containers.py | 30 +++++++++++++++++++--- zunclient/tests/unit/v1/test_containers.py | 12 ++++++--- zunclient/v1/containers.py | 11 ++++---- zunclient/v1/containers_shell.py | 24 ++++++++++++++++- 4 files changed, 63 insertions(+), 14 deletions(-) diff --git a/zunclient/osc/v1/containers.py b/zunclient/osc/v1/containers.py index 511c4949..23af4799 100644 --- a/zunclient/osc/v1/containers.py +++ b/zunclient/osc/v1/containers.py @@ -407,14 +407,36 @@ class LogsContainer(command.Command): '--stderr', action='store_true', help='Only stderr logs of container.') + parser.add_argument( + '--since', + metavar='', + default=None, + help='Show logs since a given datetime or integer ' + 'epoch (in seconds).') + parser.add_argument( + '--timestamps', + dest='timestamps', + action='store_true', + default=False, + help='Show timestamps.') + parser.add_argument( + '--tail', + metavar='', + default='all', + help='Number of lines to show from the end of the logs.') return parser def take_action(self, parsed_args): client = _get_client(self, parsed_args) - container = parsed_args.container - stdout = parsed_args.stdout - stderr = parsed_args.stderr - logs = client.containers.logs(container, stdout, stderr) + opts = {} + opts['id'] = parsed_args.container + opts['stdout'] = parsed_args.stdout + opts['stderr'] = parsed_args.stderr + opts['since'] = parsed_args.since + opts['timestamps'] = parsed_args.timestamps + opts['tail'] = parsed_args.tail + opts = zun_utils._remove_null_parms(**opts) + logs = client.containers.logs(**opts) print(logs) diff --git a/zunclient/tests/unit/v1/test_containers.py b/zunclient/tests/unit/v1/test_containers.py index a7556f0b..ac37647a 100644 --- a/zunclient/tests/unit/v1/test_containers.py +++ b/zunclient/tests/unit/v1/test_containers.py @@ -176,7 +176,9 @@ fake_responses = { ), }, '/v1/containers/%s/logs?%s' - % (CONTAINER1['id'], parse.urlencode({'stdout': True, 'stderr': True})): + % (CONTAINER1['id'], parse.urlencode({'stdout': True, 'stderr': True, + 'timestamps': False, 'tail': 'all', + 'since': None})): { 'GET': ( {}, @@ -423,11 +425,15 @@ class ContainerManagerTest(testtools.TestCase): self.assertTrue(containers) def test_containers_logs(self): - containers = self.mgr.logs(CONTAINER1['id'], stdout=True, stderr=True) + containers = self.mgr.logs(CONTAINER1['id'], stdout=True, stderr=True, + timestamps=False, tail='all', since=None) expect = [ ('GET', '/v1/containers/%s/logs?%s' % (CONTAINER1['id'], parse.urlencode({'stdout': True, - 'stderr': True})), + 'stderr': True, + 'timestamps': False, + 'tail': 'all', + 'since': None})), {'Content-Length': '0'}, None) ] self.assertEqual(expect, self.api.calls) diff --git a/zunclient/v1/containers.py b/zunclient/v1/containers.py index 33305b44..08c1e088 100644 --- a/zunclient/v1/containers.py +++ b/zunclient/v1/containers.py @@ -134,13 +134,12 @@ class ContainerManager(base.Manager): def unpause(self, id): return self._action(id, '/unpause') - def logs(self, id, stdout, stderr): - if stdout is False and stderr is False: - stdout = True - stderr = True + def logs(self, id, **kwargs): + if kwargs['stdout'] is False and kwargs['stderr'] is False: + kwargs['stdout'] = True + kwargs['stderr'] = True return self._action(id, '/logs', method='GET', - qparams={'stdout': stdout, - 'stderr': stderr})[1] + qparams=kwargs)[1] def execute(self, id, command): return self._action(id, '/execute', diff --git a/zunclient/v1/containers_shell.py b/zunclient/v1/containers_shell.py index 21b91f45..8009a8a7 100644 --- a/zunclient/v1/containers_shell.py +++ b/zunclient/v1/containers_shell.py @@ -316,9 +316,31 @@ def do_unpause(cs, args): @utils.arg('--stderr', action='store_true', help='Only stderr logs of container.') +@utils.arg('--since', + metavar='', + default=None, + help='Show logs since a given datetime or integer ' + 'epoch (in seconds).') +@utils.arg('-t', '--timestamps', + dest='timestamps', + action='store_true', + default=False, + help='Show timestamps.') +@utils.arg('--tail', + metavar='', + default='all', + help='Number of lines to show from the end of the logs.') def do_logs(cs, args): """Get logs of a container.""" - logs = cs.containers.logs(args.container, args.stdout, args.stderr) + opts = {} + opts['id'] = args.container + opts['stdout'] = args.stdout + opts['stderr'] = args.stderr + opts['since'] = args.since + opts['timestamps'] = args.timestamps + opts['tail'] = args.tail + opts = zun_utils._remove_null_parms(**opts) + logs = cs.containers.logs(**opts) print(logs)