Clean up raw policy stats in account stat
Storage policy stats was not well parsed in account stat. This patch parses the stats and print out the stats in a format like below: $swift -A http://swift_cluster/auth/v1.0 -U test:tester -K testing stat Account: AUTH_test Containers: 5 Objects: 1 Bytes: 2097152 Objects in policy "golden": 1 Bytess in policy "golden": 2097152 Objects in policy "silver": 0 Bytes in policy "silver": 0 X-Timestamp: 1404697760.88809 X-Trans-Id: txec519e24b44a413abb705-0053da2dcb Content-Type: text/plain; charset=utf-8 Accept-Ranges: bytes Change-Id: I7ad0ee6d88f8393e3a93e90cd52b9b592da7072d
This commit is contained in:
@@ -15,9 +15,11 @@ from swiftclient.utils import prt_bytes
|
|||||||
|
|
||||||
|
|
||||||
def stat_account(conn, options, thread_manager):
|
def stat_account(conn, options, thread_manager):
|
||||||
|
items_to_print = []
|
||||||
|
|
||||||
headers = conn.head_account()
|
headers = conn.head_account()
|
||||||
if options.verbose > 1:
|
if options.verbose > 1:
|
||||||
thread_manager.print_items((
|
items_to_print.extend((
|
||||||
('StorageURL', conn.url),
|
('StorageURL', conn.url),
|
||||||
('Auth Token', conn.token),
|
('Auth Token', conn.token),
|
||||||
))
|
))
|
||||||
@@ -26,19 +28,40 @@ def stat_account(conn, options, thread_manager):
|
|||||||
options.human).lstrip()
|
options.human).lstrip()
|
||||||
bytes_used = prt_bytes(headers.get('x-account-bytes-used', 0),
|
bytes_used = prt_bytes(headers.get('x-account-bytes-used', 0),
|
||||||
options.human).lstrip()
|
options.human).lstrip()
|
||||||
thread_manager.print_items((
|
items_to_print.extend((
|
||||||
('Account', conn.url.rsplit('/', 1)[-1]),
|
('Account', conn.url.rsplit('/', 1)[-1]),
|
||||||
('Containers', container_count),
|
('Containers', container_count),
|
||||||
('Objects', object_count),
|
('Objects', object_count),
|
||||||
('Bytes', bytes_used),
|
('Bytes', bytes_used),
|
||||||
))
|
))
|
||||||
thread_manager.print_headers(headers,
|
policies = set()
|
||||||
meta_prefix='x-account-meta-',
|
exclude_policy_headers = []
|
||||||
exclude_headers=(
|
ps_header_prefix = 'x-account-storage-policy-'
|
||||||
'content-length', 'date',
|
for header_key, header_value in headers.items():
|
||||||
'x-account-container-count',
|
if header_key.lower().startswith(ps_header_prefix):
|
||||||
'x-account-object-count',
|
policy_name = header_key.rsplit('-', 2)[0].split('-', 4)[-1]
|
||||||
'x-account-bytes-used'))
|
policies.add(policy_name)
|
||||||
|
exclude_policy_headers.append(header_key)
|
||||||
|
for policy in policies:
|
||||||
|
items_to_print.extend((
|
||||||
|
('Objects in policy "' + policy + '"',
|
||||||
|
prt_bytes(headers.get(ps_header_prefix + policy + '-object-count',
|
||||||
|
0), options.human).lstrip()),
|
||||||
|
('Bytes in policy "' + policy + '"',
|
||||||
|
prt_bytes(headers.get(ps_header_prefix + policy + '-bytes-used',
|
||||||
|
0), options.human).lstrip()),
|
||||||
|
))
|
||||||
|
|
||||||
|
items_to_print.extend(thread_manager.headers_to_items(
|
||||||
|
headers, meta_prefix='x-account-meta-',
|
||||||
|
exclude_headers=([
|
||||||
|
'content-length', 'date',
|
||||||
|
'x-account-container-count',
|
||||||
|
'x-account-object-count',
|
||||||
|
'x-account-bytes-used'] + exclude_policy_headers)))
|
||||||
|
# line up the items nicely
|
||||||
|
offset = max(len(item) for item, value in items_to_print)
|
||||||
|
thread_manager.print_items(items_to_print, offset=offset)
|
||||||
|
|
||||||
|
|
||||||
def stat_container(conn, options, args, thread_manager):
|
def stat_container(conn, options, args, thread_manager):
|
||||||
|
@@ -193,6 +193,7 @@ class MultiThreadingManager(object):
|
|||||||
The swift command-line tool uses this to exit non-zero if any error strings
|
The swift command-line tool uses this to exit non-zero if any error strings
|
||||||
were printed.
|
were printed.
|
||||||
"""
|
"""
|
||||||
|
DEFAULT_OFFSET = 14
|
||||||
|
|
||||||
def __init__(self, print_stream=sys.stdout, error_stream=sys.stderr):
|
def __init__(self, print_stream=sys.stdout, error_stream=sys.stderr):
|
||||||
"""
|
"""
|
||||||
@@ -231,7 +232,7 @@ class MultiThreadingManager(object):
|
|||||||
msg = msg % fmt_args
|
msg = msg % fmt_args
|
||||||
self.printer.queue.put(msg)
|
self.printer.queue.put(msg)
|
||||||
|
|
||||||
def print_items(self, items, offset=14, skip_missing=False):
|
def print_items(self, items, offset=DEFAULT_OFFSET, skip_missing=False):
|
||||||
lines = []
|
lines = []
|
||||||
template = '%%%ds: %%s' % offset
|
template = '%%%ds: %%s' % offset
|
||||||
for k, v in items:
|
for k, v in items:
|
||||||
@@ -241,7 +242,7 @@ class MultiThreadingManager(object):
|
|||||||
self.print_msg('\n'.join(lines))
|
self.print_msg('\n'.join(lines))
|
||||||
|
|
||||||
def print_headers(self, headers, meta_prefix='', exclude_headers=None,
|
def print_headers(self, headers, meta_prefix='', exclude_headers=None,
|
||||||
offset=14):
|
offset=DEFAULT_OFFSET):
|
||||||
exclude_headers = exclude_headers or []
|
exclude_headers = exclude_headers or []
|
||||||
meta_headers = []
|
meta_headers = []
|
||||||
other_headers = []
|
other_headers = []
|
||||||
@@ -254,6 +255,18 @@ class MultiThreadingManager(object):
|
|||||||
other_headers.append(template % (key.title(), value))
|
other_headers.append(template % (key.title(), value))
|
||||||
self.print_msg('\n'.join(chain(meta_headers, other_headers)))
|
self.print_msg('\n'.join(chain(meta_headers, other_headers)))
|
||||||
|
|
||||||
|
def headers_to_items(self, headers, meta_prefix='', exclude_headers=None):
|
||||||
|
exclude_headers = exclude_headers or []
|
||||||
|
meta_items = []
|
||||||
|
other_items = []
|
||||||
|
for key, value in headers.items():
|
||||||
|
if key.startswith(meta_prefix):
|
||||||
|
meta_key = 'Meta %s' % key[len(meta_prefix):].title()
|
||||||
|
meta_items.append((meta_key, value))
|
||||||
|
elif key not in exclude_headers:
|
||||||
|
other_items.append((key.title(), value))
|
||||||
|
return meta_items + other_items
|
||||||
|
|
||||||
def error(self, msg, *fmt_args):
|
def error(self, msg, *fmt_args):
|
||||||
if fmt_args:
|
if fmt_args:
|
||||||
msg = msg % fmt_args
|
msg = msg % fmt_args
|
||||||
|
@@ -69,10 +69,10 @@ class TestStatHelpers(testtools.TestCase):
|
|||||||
with self.thread_manager as thread_manager:
|
with self.thread_manager as thread_manager:
|
||||||
h.stat_account(self.conn, self.options, thread_manager)
|
h.stat_account(self.conn, self.options, thread_manager)
|
||||||
expected = """
|
expected = """
|
||||||
Account: a
|
Account: a
|
||||||
Containers: 42
|
Containers: 42
|
||||||
Objects: 976K
|
Objects: 976K
|
||||||
Bytes: 1.0G
|
Bytes: 1.0G
|
||||||
"""
|
"""
|
||||||
self.assertOut(expected)
|
self.assertOut(expected)
|
||||||
|
|
||||||
@@ -89,12 +89,35 @@ class TestStatHelpers(testtools.TestCase):
|
|||||||
with self.thread_manager as thread_manager:
|
with self.thread_manager as thread_manager:
|
||||||
h.stat_account(self.conn, self.options, thread_manager)
|
h.stat_account(self.conn, self.options, thread_manager)
|
||||||
expected = """
|
expected = """
|
||||||
StorageURL: http://storage/v1/a
|
StorageURL: http://storage/v1/a
|
||||||
Auth Token: tk12345
|
Auth Token: tk12345
|
||||||
Account: a
|
Account: a
|
||||||
Containers: 42
|
Containers: 42
|
||||||
Objects: 1000000
|
Objects: 1000000
|
||||||
Bytes: 1073741824
|
Bytes: 1073741824
|
||||||
|
"""
|
||||||
|
self.assertOut(expected)
|
||||||
|
|
||||||
|
def test_stat_account_policy_stat(self):
|
||||||
|
# stub head_account
|
||||||
|
stub_headers = {
|
||||||
|
'x-account-container-count': 42,
|
||||||
|
'x-account-object-count': 1000000,
|
||||||
|
'x-account-bytes-used': 2 ** 30,
|
||||||
|
'x-account-storage-policy-nada-object-count': 1000000,
|
||||||
|
'x-account-storage-policy-nada-bytes-used': 2 ** 30,
|
||||||
|
}
|
||||||
|
self.conn.head_account.return_value = stub_headers
|
||||||
|
|
||||||
|
with self.thread_manager as thread_manager:
|
||||||
|
h.stat_account(self.conn, self.options, thread_manager)
|
||||||
|
expected = """
|
||||||
|
Account: a
|
||||||
|
Containers: 42
|
||||||
|
Objects: 1000000
|
||||||
|
Bytes: 1073741824
|
||||||
|
Objects in policy "nada": 1000000
|
||||||
|
Bytes in policy "nada": 1073741824
|
||||||
"""
|
"""
|
||||||
self.assertOut(expected)
|
self.assertOut(expected)
|
||||||
|
|
||||||
|
@@ -63,11 +63,11 @@ class TestShell(unittest.TestCase):
|
|||||||
connection.return_value.head_account.return_value = return_headers
|
connection.return_value.head_account.return_value = return_headers
|
||||||
connection.return_value.url = 'http://127.0.0.1/v1/AUTH_account'
|
connection.return_value.url = 'http://127.0.0.1/v1/AUTH_account'
|
||||||
swiftclient.shell.main(argv)
|
swiftclient.shell.main(argv)
|
||||||
calls = [mock.call(' Account: AUTH_account\n' +
|
calls = [mock.call(' Account: AUTH_account\n' +
|
||||||
' Containers: 1\n' +
|
'Containers: 1\n' +
|
||||||
' Objects: 2\n' +
|
' Objects: 2\n' +
|
||||||
' Bytes: 3'),
|
' Bytes: 3'),
|
||||||
mock.call('')]
|
]
|
||||||
mock_print.assert_has_calls(calls)
|
mock_print.assert_has_calls(calls)
|
||||||
|
|
||||||
@mock.patch('swiftclient.shell.MultiThreadingManager._print')
|
@mock.patch('swiftclient.shell.MultiThreadingManager._print')
|
||||||
|
Reference in New Issue
Block a user