2017-08-25 22:41:41 +03:00
|
|
|
#!/usr/bin/env python3
|
2019-06-20 02:58:25 +03:00
|
|
|
# Copyright (c) Facebook, Inc. and its affiliates.
|
2017-08-25 22:41:41 +03:00
|
|
|
#
|
2019-06-20 02:58:25 +03:00
|
|
|
# This software may be used and distributed according to the terms of the
|
|
|
|
# GNU General Public License version 2.
|
2017-08-25 22:41:41 +03:00
|
|
|
|
|
|
|
# Helper function to print the heading of a Stat Call.
|
|
|
|
|
|
|
|
from typing import TextIO
|
|
|
|
|
|
|
|
|
|
|
|
def write_heading(heading: str, out: TextIO) -> None:
|
2018-05-10 07:33:49 +03:00
|
|
|
border = "*" * len(heading)
|
2017-12-02 04:16:59 +03:00
|
|
|
out.write(_center_strip_right(border, 80))
|
|
|
|
out.write(_center_strip_right(heading, 80))
|
2018-05-10 07:33:49 +03:00
|
|
|
out.write(_center_strip_right(border, 80) + "\n")
|
2017-08-25 22:41:41 +03:00
|
|
|
|
|
|
|
|
|
|
|
def write_mem_status_table(fuse_counters, out: TextIO) -> None:
|
2018-05-10 07:33:49 +03:00
|
|
|
format_str = "{:>40} {:^1} {:<20}"
|
2017-08-25 22:41:41 +03:00
|
|
|
keys = [
|
2018-05-19 09:05:39 +03:00
|
|
|
"memory_free",
|
|
|
|
"memory_free_percent",
|
|
|
|
"memory_usage",
|
|
|
|
"memory_usage_percent",
|
2017-08-25 22:41:41 +03:00
|
|
|
]
|
|
|
|
for key in keys:
|
2018-05-10 07:33:49 +03:00
|
|
|
if key.endswith("_percent"):
|
|
|
|
value = "%d%s" % (fuse_counters[key], "%")
|
2017-08-25 22:41:41 +03:00
|
|
|
else:
|
2018-05-10 07:33:49 +03:00
|
|
|
value = "%f(GB)" % (fuse_counters[key] / (10 ** 6))
|
|
|
|
centered_text = format_str.format(key.replace("_", " "), ":", value)
|
|
|
|
out.write(centered_text.rstrip() + "\n")
|
2017-08-25 22:41:41 +03:00
|
|
|
|
|
|
|
|
2018-05-10 07:33:49 +03:00
|
|
|
LATENCY_FORMAT_STR = "{:<12} {:^4} {:^10} {:>10} {:>15} {:>10} {:>10}\n"
|
2017-10-21 00:00:28 +03:00
|
|
|
|
|
|
|
|
2018-08-30 16:17:28 +03:00
|
|
|
# Prints a record of latencies with avg, 50'th,90'th and 99'th percentile.
|
|
|
|
def write_latency_record(operation: str, matrix, out: TextIO) -> None:
|
2018-05-10 07:33:49 +03:00
|
|
|
border = "-" * 80
|
2018-08-30 16:17:28 +03:00
|
|
|
percentile = {0: "avg", 1: "p50", 2: "p90", 3: "p99"}
|
2017-08-25 22:41:41 +03:00
|
|
|
|
|
|
|
for i in range(len(percentile)):
|
2018-08-30 16:17:28 +03:00
|
|
|
operation_name = ""
|
2017-08-25 22:41:41 +03:00
|
|
|
if i == int(len(percentile) / 2):
|
2018-08-30 16:17:28 +03:00
|
|
|
operation_name = operation
|
2017-08-25 22:41:41 +03:00
|
|
|
out.write(
|
2017-10-21 00:00:28 +03:00
|
|
|
LATENCY_FORMAT_STR.format(
|
2018-08-30 16:17:28 +03:00
|
|
|
operation_name,
|
2018-05-10 07:33:49 +03:00
|
|
|
"|",
|
|
|
|
percentile[i],
|
|
|
|
matrix[i][0],
|
|
|
|
matrix[i][1],
|
|
|
|
matrix[i][2],
|
|
|
|
matrix[i][3],
|
2017-08-25 22:41:41 +03:00
|
|
|
)
|
|
|
|
)
|
2018-05-10 07:33:49 +03:00
|
|
|
out.write(border + "\n")
|
2017-08-25 22:41:41 +03:00
|
|
|
|
|
|
|
|
|
|
|
def write_latency_table(table, out: TextIO) -> None:
|
|
|
|
out.write(
|
2017-10-21 00:00:28 +03:00
|
|
|
LATENCY_FORMAT_STR.format(
|
2018-05-10 07:33:49 +03:00
|
|
|
"SystemCall",
|
|
|
|
"|",
|
|
|
|
"Percentile",
|
|
|
|
"Last Minute",
|
|
|
|
"Last 10 Minutes",
|
|
|
|
"Last Hour",
|
|
|
|
"All Time",
|
2017-08-25 22:41:41 +03:00
|
|
|
)
|
|
|
|
)
|
2018-05-10 07:33:49 +03:00
|
|
|
border = "-" * 80
|
|
|
|
out.write(border + "\n")
|
2017-08-25 22:41:41 +03:00
|
|
|
for key in table:
|
|
|
|
write_latency_record(key, table[key], out)
|
|
|
|
|
|
|
|
|
|
|
|
def write_table(table, heading: str, out: TextIO) -> None:
|
2017-11-04 02:54:37 +03:00
|
|
|
key_width = max([len(heading)] + list(map(len, table.keys()))) + 2
|
|
|
|
|
2018-05-10 07:33:49 +03:00
|
|
|
format_str = "{:<{}}{:>15}{:>15}{:>15}{:>15}\n"
|
2017-08-25 22:41:41 +03:00
|
|
|
out.write(
|
|
|
|
format_str.format(
|
2018-05-10 07:33:49 +03:00
|
|
|
heading, key_width, "Last Minute", "Last 10m", "Last Hour", "All Time"
|
2017-08-25 22:41:41 +03:00
|
|
|
)
|
|
|
|
)
|
2018-05-10 07:33:49 +03:00
|
|
|
border = "-" * (key_width + 60)
|
|
|
|
out.write(border + "\n")
|
2017-08-25 22:41:41 +03:00
|
|
|
for key in table:
|
|
|
|
value = table[key]
|
|
|
|
out.write(
|
2017-11-04 02:54:37 +03:00
|
|
|
format_str.format(key, key_width, value[0], value[1], value[2], value[3])
|
2017-08-25 22:41:41 +03:00
|
|
|
)
|
2017-12-02 04:16:59 +03:00
|
|
|
|
|
|
|
|
|
|
|
def _center_strip_right(text: str, width: int) -> str:
|
2018-05-10 07:33:49 +03:00
|
|
|
"""Returns a string with sufficient leading whitespace such that `text`
|
|
|
|
would be centered within the specified `width` plus a trailing newline."""
|
2017-12-02 04:16:59 +03:00
|
|
|
space = (width - len(text)) // 2
|
2018-05-10 07:33:49 +03:00
|
|
|
return space * " " + text + "\n"
|
2017-12-18 22:39:47 +03:00
|
|
|
|
|
|
|
|
|
|
|
def format_size(size: int) -> str:
|
|
|
|
if size > 1000000000:
|
2018-05-10 07:33:49 +03:00
|
|
|
return "{:.1f} GB".format(size / 1000000000)
|
2017-12-18 22:39:47 +03:00
|
|
|
if size > 1000000:
|
2018-05-10 07:33:49 +03:00
|
|
|
return "{:.1f} MB".format(size / 1000000)
|
2017-12-18 22:39:47 +03:00
|
|
|
if size > 1000:
|
2018-05-10 07:33:49 +03:00
|
|
|
return "{:.1f} KB".format(size / 1000)
|
2017-12-18 22:39:47 +03:00
|
|
|
if size > 0:
|
2018-05-10 07:33:49 +03:00
|
|
|
return "{} B".format(size)
|
|
|
|
return "0"
|
2019-06-29 02:37:43 +03:00
|
|
|
|
|
|
|
|
|
|
|
def format_time(time: int) -> str:
|
|
|
|
if time >= 86400:
|
|
|
|
return "{:.1f} day(s)".format(time / 86400)
|
|
|
|
elif time >= 3600:
|
|
|
|
return "{:.1f} hour(s)".format(time / 3600)
|
|
|
|
elif time >= 60:
|
|
|
|
return "{:.1f} minute(s)".format(time / 60)
|
|
|
|
else:
|
|
|
|
return "{} second(s)".format(time)
|