Fix stats reporting. Add Vite compatibility
This commit is contained in:
@@ -1,22 +1,21 @@
|
||||
<script>
|
||||
import { onDestroy, onMount } from "svelte";
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import { formatDataVolume, formatThousands, formatDate, formatNumber, formatDuration } from "util/Formatting";
|
||||
import Chart from "util/Chart.svelte";
|
||||
import { color_by_name } from "util/Util";
|
||||
import ServerDiagnostics from "./ServerDiagnostics.svelte";
|
||||
import PeerTable from "./PeerTable.svelte";
|
||||
import { get_endpoint } from "lib/PixeldrainAPI";
|
||||
|
||||
let graphViews = $state()
|
||||
let graphBandwidth = $state()
|
||||
let graphTimeout = null
|
||||
let graphEgress: Chart = $state()
|
||||
let graphDownloads: Chart = $state()
|
||||
let graphTimeout: NodeJS.Timeout = null
|
||||
|
||||
let start_time = $state("")
|
||||
let end_time = $state("")
|
||||
let total_bandwidth = $state(0)
|
||||
let total_bandwidth_paid = $state(0)
|
||||
let total_views = $state(0)
|
||||
let total_egress = $state(0)
|
||||
let total_downloads = $state(0)
|
||||
const loadGraph = (minutes, interval, live) => {
|
||||
const loadGraph = (minutes: number, interval: number, live: boolean) => {
|
||||
if (graphTimeout !== null) { clearTimeout(graphTimeout) }
|
||||
if (live) {
|
||||
graphTimeout = setTimeout(() => { loadGraph(minutes, interval, true) }, 10000)
|
||||
@@ -27,7 +26,7 @@ const loadGraph = (minutes, interval, live) => {
|
||||
start.setMinutes(start.getMinutes() - minutes)
|
||||
|
||||
fetch(
|
||||
window.api_endpoint + "/admin/files/timeseries" +
|
||||
get_endpoint() + "/admin/files/timeseries" +
|
||||
"?start=" + start.toISOString() +
|
||||
"&end=" + today.toISOString() +
|
||||
"&interval=" + interval
|
||||
@@ -35,37 +34,34 @@ const loadGraph = (minutes, interval, live) => {
|
||||
if (!resp.ok) { return Promise.reject("Error: " + resp.status); }
|
||||
return resp.json();
|
||||
}).then(resp => {
|
||||
resp.views.timestamps.forEach((val, idx) => {
|
||||
resp.egress.timestamps.forEach((val, idx) => {
|
||||
let date = new Date(val);
|
||||
let dateStr = date.getFullYear();
|
||||
let dateStr: string = date.getFullYear().toString();
|
||||
dateStr += "-" + ("00" + (date.getMonth() + 1)).slice(-2);
|
||||
dateStr += "-" + ("00" + date.getDate()).slice(-2);
|
||||
dateStr += " " + ("00" + date.getHours()).slice(-2);
|
||||
dateStr += ":" + ("00" + date.getMinutes()).slice(-2);
|
||||
resp.views.timestamps[idx] = " " + dateStr + " "; // Poor man's padding
|
||||
resp.egress.timestamps[idx] = " " + dateStr + " "; // Poor man's padding
|
||||
});
|
||||
graphViews.data().labels = resp.views.timestamps;
|
||||
graphViews.data().datasets[0].data = resp.views.amounts;
|
||||
graphViews.data().datasets[1].data = resp.downloads.amounts;
|
||||
graphBandwidth.data().labels = resp.views.timestamps;
|
||||
graphBandwidth.data().datasets[0].data = resp.bandwidth.amounts
|
||||
graphBandwidth.data().datasets[1].data = resp.bandwidth_paid.amounts
|
||||
graphViews.update()
|
||||
graphBandwidth.update()
|
||||
graphEgress.data().labels = resp.egress.timestamps;
|
||||
graphEgress.data().datasets[0].data = resp.egress.amounts;
|
||||
graphDownloads.data().labels = resp.downloads.timestamps;
|
||||
graphDownloads.data().datasets[0].data = resp.downloads.amounts
|
||||
graphEgress.update()
|
||||
graphDownloads.update()
|
||||
|
||||
start_time = resp.views.timestamps[0]
|
||||
end_time = resp.views.timestamps.slice(-1)[0];
|
||||
total_bandwidth = resp.bandwidth.amounts.reduce((acc, val) => acc + val)
|
||||
total_bandwidth_paid = resp.bandwidth_paid.amounts.reduce((acc, val) => acc + val)
|
||||
total_views = resp.views.amounts.reduce((acc, val) => acc + val)
|
||||
start_time = resp.egress.timestamps[0]
|
||||
end_time = resp.egress.timestamps.slice(-1)[0];
|
||||
total_egress = resp.egress.amounts.reduce((acc, val) => acc + val)
|
||||
total_downloads = resp.downloads.amounts.reduce((acc, val) => acc + val)
|
||||
})
|
||||
}
|
||||
|
||||
// Load performance statistics
|
||||
|
||||
let lastOrder = $state();
|
||||
let lastOrder: string = $state();
|
||||
let status = $state({
|
||||
pid: 0,
|
||||
cpu_profile_running_since: "",
|
||||
db_latency: 0,
|
||||
db_time: "",
|
||||
@@ -74,33 +70,32 @@ let status = $state({
|
||||
local_read_size_per_sec: 0,
|
||||
local_reads: 0,
|
||||
local_reads_per_sec: 0,
|
||||
local_readers: 0,
|
||||
neighbour_read_size: 0,
|
||||
neighbour_read_size_per_sec: 0,
|
||||
neighbour_reads: 0,
|
||||
neighbour_reads_per_sec: 0,
|
||||
peers: [],
|
||||
query_statistics: [],
|
||||
neighbour_readers: 0,
|
||||
remote_read_size: 0,
|
||||
remote_read_size_per_sec: 0,
|
||||
remote_reads: 0,
|
||||
remote_reads_per_sec: 0,
|
||||
remote_readers: 0,
|
||||
peers: [],
|
||||
query_statistics: [],
|
||||
running_since: "",
|
||||
stats_watcher_listeners: 0,
|
||||
stats_watcher_threads: 0,
|
||||
filesystem_watcher_listeners: 0,
|
||||
filesystem_watcher_threads: 0,
|
||||
rate_limit_watcher_threads: 0,
|
||||
rate_limit_watcher_listeners: 0,
|
||||
download_clients: 0,
|
||||
download_connections: 0,
|
||||
})
|
||||
let total_reads = $derived(status.local_reads + status.neighbour_reads + status.remote_reads)
|
||||
let total_read_size = $derived(status.local_read_size + status.neighbour_read_size + status.remote_read_size)
|
||||
|
||||
function getStats(order) {
|
||||
function getStats(order: string) {
|
||||
lastOrder = order
|
||||
|
||||
fetch(window.api_endpoint + "/status").then(
|
||||
fetch(get_endpoint() + "/status").then(
|
||||
resp => resp.json()
|
||||
).then(resp => {
|
||||
// Sort all queries by the selected sort column
|
||||
@@ -126,37 +121,25 @@ function getStats(order) {
|
||||
let statsInterval = null
|
||||
onMount(() => {
|
||||
// Prepare chart datasets
|
||||
graphBandwidth.data().datasets = [
|
||||
graphEgress.data().datasets = [
|
||||
{
|
||||
label: "Bandwidth (free)",
|
||||
label: "Egress",
|
||||
data: [],
|
||||
borderWidth: 2,
|
||||
pointRadius: 0,
|
||||
borderColor: color_by_name("highlight_color"),
|
||||
backgroundColor: color_by_name("highlight_color"),
|
||||
},
|
||||
{
|
||||
label: "Bandwidth (premium)",
|
||||
borderWidth: 2,
|
||||
pointRadius: 0,
|
||||
borderColor: color_by_name("danger_color"),
|
||||
backgroundColor: color_by_name("danger_color"),
|
||||
},
|
||||
];
|
||||
graphViews.data().datasets = [
|
||||
graphDownloads.data().datasets = [
|
||||
{
|
||||
label: "Views",
|
||||
label: "Downloads",
|
||||
data: [],
|
||||
borderWidth: 2,
|
||||
pointRadius: 0,
|
||||
borderColor: color_by_name("highlight_color"),
|
||||
backgroundColor: color_by_name("highlight_color"),
|
||||
},
|
||||
{
|
||||
label: "Downloads",
|
||||
borderWidth: 2,
|
||||
pointRadius: 0,
|
||||
borderColor: color_by_name("danger_color"),
|
||||
backgroundColor: color_by_name("danger_color"),
|
||||
},
|
||||
];
|
||||
|
||||
loadGraph(10080, 10, true);
|
||||
@@ -164,13 +147,14 @@ onMount(() => {
|
||||
statsInterval = setInterval(() => {
|
||||
getStats(lastOrder)
|
||||
}, 10000)
|
||||
})
|
||||
onDestroy(() => {
|
||||
if (graphTimeout !== null) {
|
||||
clearTimeout(graphTimeout)
|
||||
}
|
||||
if (statsInterval !== null) {
|
||||
clearInterval(statsInterval)
|
||||
|
||||
return () => {
|
||||
if (graphTimeout !== null) {
|
||||
clearTimeout(graphTimeout)
|
||||
}
|
||||
if (statsInterval !== null) {
|
||||
clearInterval(statsInterval)
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -188,14 +172,12 @@ onDestroy(() => {
|
||||
<button onclick={() => loadGraph(1051200, 1440, false)}>Two Years 1d</button>
|
||||
<button onclick={() => loadGraph(2628000, 1440, false)}>Five Years 1d</button>
|
||||
</div>
|
||||
<Chart bind:this={graphBandwidth} data_type="bytes" />
|
||||
<Chart bind:this={graphViews} data_type="number" />
|
||||
<Chart bind:this={graphEgress} data_type="bytes" />
|
||||
<Chart bind:this={graphDownloads} data_type="number" />
|
||||
<div class="highlight_border">
|
||||
Total usage from {start_time} to {end_time}<br/>
|
||||
{formatDataVolume(total_bandwidth, 3)} bandwidth,
|
||||
{formatDataVolume(total_bandwidth_paid, 3)} paid bandwidth,
|
||||
{formatThousands(total_views, 3)} views and
|
||||
{formatThousands(total_downloads, 3)} downloads
|
||||
{formatDataVolume(total_egress, 3)} egress,
|
||||
{formatThousands(total_downloads)} downloads
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
@@ -222,6 +204,7 @@ onDestroy(() => {
|
||||
<thead>
|
||||
<tr>
|
||||
<td>Source</td>
|
||||
<td>Current</td>
|
||||
<td>Reads</td>
|
||||
<td>Reads %</td>
|
||||
<td>Reads / s</td>
|
||||
@@ -233,6 +216,7 @@ onDestroy(() => {
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Local cache</td>
|
||||
<td>{status.local_readers}</td>
|
||||
<td>{status.local_reads}</td>
|
||||
<td>{((status.local_reads / total_reads) * 100).toPrecision(3)}%</td>
|
||||
<td>{status.local_reads_per_sec.toPrecision(4)}/s</td>
|
||||
@@ -242,6 +226,7 @@ onDestroy(() => {
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Neighbour</td>
|
||||
<td>{status.neighbour_readers}</td>
|
||||
<td>{status.neighbour_reads}</td>
|
||||
<td>{((status.neighbour_reads / total_reads) * 100).toPrecision(3)}%</td>
|
||||
<td>{status.neighbour_reads_per_sec.toPrecision(4)}/s</td>
|
||||
@@ -251,6 +236,7 @@ onDestroy(() => {
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Reed-solomon</td>
|
||||
<td>{status.remote_readers}</td>
|
||||
<td>{status.remote_reads}</td>
|
||||
<td>{((status.remote_reads / total_reads) * 100).toPrecision(3)}%</td>
|
||||
<td>{status.remote_reads_per_sec.toPrecision(4)}/s</td>
|
||||
@@ -258,6 +244,16 @@ onDestroy(() => {
|
||||
<td>{((status.remote_read_size / total_read_size) * 100).toPrecision(3)}%</td>
|
||||
<td>{formatDataVolume(status.remote_read_size_per_sec, 4)}/s</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Total</td>
|
||||
<td>{status.local_readers+status.neighbour_readers+status.remote_readers}</td>
|
||||
<td>{status.local_reads+status.neighbour_reads+status.remote_reads}</td>
|
||||
<td></td>
|
||||
<td>{(status.local_reads_per_sec+status.neighbour_reads_per_sec+status.remote_reads_per_sec).toPrecision(4)}/s</td>
|
||||
<td>{formatDataVolume(status.local_read_size+status.neighbour_read_size+status.remote_read_size, 4)}</td>
|
||||
<td></td>
|
||||
<td>{formatDataVolume(status.local_read_size_per_sec+status.neighbour_read_size_per_sec+status.remote_read_size_per_sec, 4)}/s</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -282,12 +278,6 @@ onDestroy(() => {
|
||||
<td>{status.filesystem_watcher_listeners}</td>
|
||||
<td>{(status.filesystem_watcher_listeners / status.filesystem_watcher_threads).toPrecision(3)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Downloads (per IP)</td>
|
||||
<td>{status.download_clients}</td>
|
||||
<td>{status.download_connections}</td>
|
||||
<td>{(status.download_connections / status.download_clients).toPrecision(3)}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user