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
This commit is contained in:
Feng Shengqin
2017-03-03 10:24:46 +08:00
parent 56dc05c9d2
commit 2bb944e2d7
4 changed files with 63 additions and 14 deletions

View File

@@ -407,14 +407,36 @@ class LogsContainer(command.Command):
'--stderr',
action='store_true',
help='Only stderr logs of container.')
parser.add_argument(
'--since',
metavar='<since>',
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='<tail>',
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)

View File

@@ -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)

View File

@@ -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',

View File

@@ -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='<since>',
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='<tail>',
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)