21 import matplotlib.pyplot
as plt
22 import matplotlib.gridspec
as gridspec
25 def get_queue(query, sfrom: List[str], sto: List[str], filter_key_fields):
31 item_d = [q
for q
in query.dicts()]
35 for f
in filter_key_fields:
38 if item[
'state']
in sfrom
and key
not in active:
42 elif item[
'state']
in sto
and key
in active:
48 qtime.append(item[
'time'])
52 def plot(query, axs, subplot:int, title: str, sfrom: List[str], sto: List[str], extra: str, extra2, filter_key_fields):
56 qlength, qtime =
get_queue(query, sfrom, sto, filter_key_fields)
57 axs[subplot][extra].
plot(qtime, qlength)
58 axs[subplot][extra].set_ylabel(f
"{title}")
61 item_d2 = [q
for q
in extra2.dicts()]
62 q1time = [ i[
'time']
for i
in item_d2]
63 q1nr = [ i[
'NR']
for i
in item_d2]
64 axs[subplot][extra].
plot(q1time, q1nr)
68 for cli_pid
in cli_pids:
70 {
"query": client_req.select().where(client_req.pid==cli_pid).order_by(client_req.time),
71 "title":
"Client",
"from": [
"launched"],
"to": [
"stable"]},
72 {
"query": rpc_req.select(rpc_req, rpc_to_sxid.xid, rpc_to_sxid.session_id).\
73 join(rpc_to_sxid, on=((rpc_req.id == rpc_to_sxid.id)&\
74 (rpc_req.pid == rpc_to_sxid.pid))).\
75 order_by(rpc_req.time).where(rpc_req.pid==cli_pid),
76 "title":
"rpc-cli",
"from": [
"INITIALISED"],
"to": [
"REPLIED"]}
83 for srv_pid
in srv_pids:
85 {
"query": rpc_req.select(rpc_req, sxid_to_rpc.xid, sxid_to_rpc.session_id).\
86 join(sxid_to_rpc, on=((sxid_to_rpc.id==rpc_req.id)&\
87 (sxid_to_rpc.pid==rpc_req.pid))).\
88 order_by(rpc_req.time).where(rpc_req.pid==srv_pid),
89 "title":
"rpc-srv",
"from":
"ACCEPTED",
"to":
"REPLIED"},
90 {
"query": stio_req.select().order_by(stio_req.time).where(stio_req.pid==srv_pid),
91 "title": f
"stob-io",
"from": [
"M0_AVI_AD_PREPARE"],
"to": [
"M0_AVI_AD_ENDIO"]},
92 {
"query": be_tx.select().order_by(be_tx.time).where(be_tx.pid==srv_pid),
93 "title":
"TXs",
"from": [
"prepare"],
"to": [
"done"]},
94 {
"query": be_tx.select().order_by(be_tx.time).where(be_tx.pid==srv_pid),
95 "title":
"TXs:active",
"from": [
"active"],
"to": [
"closed"]},
96 {
"query": fom_req_state.select().order_by(fom_req_state.time).where(fom_req_state.pid==srv_pid),
97 "title":
"FOMs",
"from": [
"Init"],
"to": [
"Finished"]},
98 {
"query": fom_req_state.select().order_by(fom_req_state.time).where(fom_req_state.pid==1010101),
99 "title":
"FOMs-act",
"from": [
"Init"],
"to": [
"Finished"],
100 "extra2": queues.select(queues.time, queues.avg.alias(
'NR')).order_by(queues.time).where((queues.pid==srv_pid)&(queues.type==
"fom-active")),
102 {
"query": fom_req_state.select().order_by(fom_req_state.time).where(fom_req_state.pid==1010101),
103 "title":
"FOMs-runq",
"from": [
"Init"],
"to": [
"Finished"],
104 "extra2": queues.select(queues.time, queues.avg.alias(
'NR')).order_by(queues.time).where((queues.pid==srv_pid)&(queues.type==
"runq")),
106 {
"query": fom_req_state.select().order_by(fom_req_state.time).where(fom_req_state.pid==1010101),
107 "title":
"FOMs-wail",
"from": [
"Init"],
"to": [
"Finished"],
108 "extra2": queues.select(queues.time, queues.avg.alias(
'NR')).order_by(queues.time).where((queues.pid==srv_pid)&(queues.type==
"wail")),
117 CONV={
"us": 1000,
"ms": 1000*1000}
120 cursor={
"x0":0,
"y0":0,
"x1": 0,
"y1": 0,
"on":
False}
124 cursor.update({
"on":
True })
125 elif event.key ==
'd':
127 for an
in undo.pop():
131 def onrelease(event):
134 cursor.update({
"x1": event.xdata,
"y1": event.ydata })
135 cursor.update({
"on":
False })
137 an1=event.inaxes.axvspan(cursor[
"x0"], cursor[
"x1"], facecolor=
'0.9', alpha=.5)
138 an2=event.inaxes.annotate(
'', xy=(cursor[
"x0"], cursor[
"y0"]),
139 xytext=(cursor[
"x1"], cursor[
"y0"]),
140 xycoords=
'data', textcoords=
'data',
141 arrowprops={
'arrowstyle':
'|-|'})
142 an3=event.inaxes.annotate(str(round((cursor[
"x1"]-cursor[
"x0"])/CONV[time_unit],2))+f
" {time_unit}",
143 xy=(
min(cursor[
"x1"], cursor[
"x0"])+
144 abs(cursor[
"x1"]-cursor[
"x0"])/2, 0.5+cursor[
"y0"]),
145 ha=
'center', va=
'center')
146 undo.append([an1, an2, an3])
152 cursor.update({
"x0": event.xdata,
"y0": event.ydata })
156 cli_nrows = len(q_cli) * len(q_cli[0])
if len(q_cli) > 0
else 0
157 srv_nrows = len(q_srv[0])
if len(q_srv) > 0
else 0
159 ncols = 1
if cli_nrows > 0
else 0
162 fig, axs = plt.subplots(ncols=ncols, nrows=
max(cli_nrows, srv_nrows), sharex=
True)
164 fig.canvas.mpl_connect(
'key_press_event', onpress)
165 fig.canvas.mpl_connect(
'button_press_event', onclick)
166 fig.canvas.mpl_connect(
'button_release_event', onrelease)
172 filter_fields = (
'id',
'pid')
173 if q[
'title'] ==
"rpc-cli":
174 filter_fields = (
'xid',
'session_id',
'pid')
175 plot(q[
'query'], axs, sub, q[
'title'], q[
'from'], q[
'to'], 0, q.get(
"extra2"), filter_fields)
178 row = 1
if len(q_cli) > 0
else 0
182 filter_fields = (
'id',
'pid')
183 if q[
'title'] ==
"rpc-srv":
184 filter_fields = (
'xid',
'session_id',
'pid')
185 plot(q[
'query'], axs, sub, q[
'title'], q[
'from'], q[
'to'], row, q.get(
"extra2"), filter_fields)
193 parser = argparse.ArgumentParser(prog=sys.argv[0], description=
""" 194 queues.py: Display queues. 196 parser.add_argument(
"--cpids", required=
False,
197 help=
"Comma separated list of client PIDs, example: --cpids 42642,43132")
198 parser.add_argument(
"--spids", required=
False,
199 help=
"Comma separated list of server PIDs, example: --spids 29,78")
200 parser.add_argument(
"-d",
"--db", type=str, default=
"m0play.db",
201 help=
"Performance database (m0play.db)")
203 return parser, parser.parse_args()
205 if __name__ ==
'__main__':
212 cli_pids = args.cpids.split(
",")
214 srv_pids = args.spids.split(
",")
216 if len(cli_pids) == 0
and len(srv_pids) == 0:
217 print(
"At least one PID must be specified")
218 parser.print_help(sys.stderr)
224 main(cli_pids, srv_pids)
static struct m0_list list
static M0_UNUSED void print(struct m0_be_list *list)
static long long max(long long a, long long b)
def main(cli_pids, srv_pids)
static long long min(long long a, long long b)