// Copyright Epic Games, Inc. All Rights Reserved. "use strict"; import { ZenPage } from "./page.js" import { Fetcher } from "../util/fetcher.js" import { Friendly } from "../util/friendly.js" import { PropTable, Toolbar } from "../util/widgets.js" //////////////////////////////////////////////////////////////////////////////// class TemporalStat { constructor(data, as_bytes) { this._data = data; this._as_bytes = as_bytes; } toString() { const columns = [ /* count */ {}, /* rate */ {}, /* t */ {}, {}, ]; const data = this._data; for (var key in data) { var out = columns[0]; if (key.startsWith("rate_")) out = columns[1]; else if (key.startsWith("t_p")) out = columns[3]; else if (key.startsWith("t_")) out = columns[2]; out[key] = data[key]; } var friendly = this._as_bytes ? Friendly.kib : Friendly.sep; var content = ""; for (var i = 0; i < columns.length; ++i) { content += "
";
const column = columns[i];
for (var key in column)
{
var value = column[key];
if (i)
{
value = Friendly.sep(value, 2);
key = key.padStart(9);
content += key + ": " + value;
}
else
content += friendly(value);
content += "\n";
}
content += "";
}
return content;
}
}
////////////////////////////////////////////////////////////////////////////////
export class Page extends ZenPage
{
async main()
{
const provider = this.get_param("provider", "z$");
var stats = new Fetcher()
.resource("stats", provider)
.param("cidstorestats", "true")
.param("cachestorestats", "true")
.json();
this.set_title("stat - " + provider);
const section = this.add_section(provider);
var toolbar = section.add_widget(Toolbar);
var tb_right = toolbar.right();
tb_right.add("filter:");
tb_right.add("-none-").on_click((x) => this.update_filter(""));
for (var preset of ["read.", "write.", ".request", ".bytes"])
tb_right.add(preset).on_click((x) => this.update_filter(x), preset);
this._filter_input = tb_right.add("", "label").tag("input");
this._filter_input.on("change", (x) => this.update_filter(x.inner().value), this._filter_input);
this._table = section.add_widget(PropTable);
this._stats = stats = await stats;
this._condense(stats);
var first = undefined;
for (var name in stats)
{
first = first || name;
toolbar.left().add(name).on_click((x) => this.view_category(x), name);
}
var filter = this.get_param("filter");
first = this.get_param("view", first);
this.view_category(first);
if (filter)
this.update_filter(filter);
}
view_category(name)
{
const friendly = (this.get_param("raw") == undefined);
this._table.clear();
this._table.add_object(this._stats[name], friendly, 3);
this.set_param("view", name);
this.update_filter("");
}
update_filter(needle)
{
this._filter_input.attr("value", needle);
this.set_param("filter", needle);
if (!needle)
return this._table.filter();
var needles = needle.split(" ");
this._table.filter(...needles);
}
_condense(stats)
{
const impl = function(node)
{
for (var name in node)
{
const candidate = node[name];
if (!(candidate instanceof Object))
continue;
if (candidate["rate_mean"] != undefined)
{
const as_bytes = (name.indexOf("bytes") >= 0);
node[name] = new TemporalStat(candidate, as_bytes);
continue;
}
impl(candidate);
}
}
for (var name in stats)
impl(stats[name]);
}
}