Skip to content

Commit

Permalink
Merge pull request #2 from ksckaan1/make-reactive
Browse files Browse the repository at this point in the history
Make reactive
  • Loading branch information
ksckaan1 authored Jun 22, 2024
2 parents 086936a + 118b808 commit 3c222ac
Show file tree
Hide file tree
Showing 14 changed files with 563 additions and 589 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ Open [http://localhost:3000/stati](http://localhost:3000/stati) on your browser.

## Dependencies
- [Templ](https://github.com/a-h/templ)
- [Alpine.js](https://github.com/alpinejs/alpine)
- [Chart.js](https://github.com/chartjs/Chart.js)
- [Tailwindcss](https://github.com/tailwindlabs/tailwindcss)

Expand Down
9 changes: 9 additions & 0 deletions assets/alpine.js

Large diffs are not rendered by default.

238 changes: 238 additions & 0 deletions assets/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
setTimeout(() => {
document.querySelector("#splash").classList.add("hidden")
}, 1500)

document.addEventListener("alpine:init", () => {
Alpine.store("table", {
goroutine_num: {},
sys: {},
other_sys: {},
heap_sys: {},
heap_inuse: {},
heap_alloc: {},
heap_released: {},
heap_idle: {},
heap_objects: {},
mallocs: {},
frees: {},
gc_sys: {},
gc_num: {},
gc_num_forced: {},
gc_cpu_fraction: 0,
total_pause: 0,
last_gc: "None",
next_gc_byte_target: 0,
})
})
const dataset = document.currentScript.dataset
const cfg = {
Interval: +dataset.interval,
ChartBuffer: +dataset.chartBuffer,
IsGCOn: !!dataset.isGcOn
}



let isPaused = false
let showWarning = false

const pause = () => {
isPaused = true
}

const resume = () => {
isPaused = false
}

const warningToast = document.getElementById("warning")

const options = {
responsive: true,
maintainAspectRatio: false,
interaction: {
intersect: false,
mode: "nearest"
},
}

const newChart = (chartID, fields) => {
const ch = new Chart(document.getElementById(chartID), {
type: 'line',
data: {
labels: [],
datasets: fields.map(fieldName => {
return {
label: fieldName,
data: [],
borderWidth: 1,
pointBorderColor: "transparent",
pointBackgroundColor: "transparent",
}
})
},
options
});
return ch
}

const addValue = (chart, time, field, value) => {
const index = chart.data.datasets.findIndex(d => d.label === field)
if (index === -1) return;

if (chart.data.datasets[index].data.length >= cfg.ChartBuffer) {
chart.data.datasets[index].data.shift()
}

chart.data.datasets[index].data.push(value)

try {
const sum = chart.data.datasets[index].data.reduce((a, b) => a + b, 0);
const avg = (sum / chart.data.datasets[index].data.length) || 0;

Alpine.store("table")[field] = {
latest: Number(value),
min: Math.min(...chart.data.datasets[index].data),
max: Math.max(...chart.data.datasets[index].data),
avg: avg
}
} catch (err) {
console.error(err)
}
if (chart.data.labels.length != chart.data.datasets[index].data.length) {
chart.data.labels.push(time)
}
}

const updateGC = (gcCpuFraction, totalPause, lastGc, nextGcByteTarget) => {
try {
Alpine.store("table").gc_cpu_fraction = gcCpuFraction
Alpine.store("table").total_pause = totalPause
Alpine.store("table").last_gc = formatTime(lastGc)
Alpine.store("table").next_gc_byte_target = nextGcByteTarget
} catch (err) {
console.error(err)
}
}

const goroutineChart = newChart("goroutine-chart", [
"goroutine_num"
])

const sysChart = newChart("sys-chart", [
"sys",
"other_sys"
])

const heapByteChart = newChart("heap-byte-chart", [
"heap_sys",
"heap_inuse",
"heap_alloc",
"heap_released",
"heap_idle"
])

const heapCountChart = newChart("heap-count-chart", [
"heap_objects",
"mallocs",
"frees"
])

let gcByteChart;
let gcNumChart;

if (cfg.IsGCOn) {
gcByteChart = newChart("gc-byte-chart", [
"gc_sys"
])

gcNumChart = newChart("gc-num-chart", [
"gc_num",
"gc_num_forced"
])
}

setInterval(async () => {
if (isPaused) return;

try {
const resp = await fetch("/debug/stati/info")
const body = await resp.json()

const time = new Date().toLocaleTimeString()

// Goroutine (num)
addValue(goroutineChart, time, "goroutine_num", body.num_goroutines)

// Sys (byte)
addValue(sysChart, time, "sys", body.sys)
addValue(sysChart, time, "other_sys", body.other_sys)

// Heap (byte)
addValue(heapByteChart, time, "heap_sys", body.heap_sys)
addValue(heapByteChart, time, "heap_inuse", body.heap_inuse)
addValue(heapByteChart, time, "heap_alloc", body.heap_alloc)
addValue(heapByteChart, time, "heap_released", body.heap_released)
addValue(heapByteChart, time, "heap_idle", body.heap_idle)

// Heap (count)
addValue(heapCountChart, time, "heap_objects", body.heap_objects)
addValue(heapCountChart, time, "mallocs", body.mallocs)
addValue(heapCountChart, time, "frees", body.frees)

if (cfg.IsGCOn) {
// GC (byte)
addValue(gcByteChart, time, "gc_sys", body.gc_sys)

// GC (num)
addValue(gcNumChart, time, "gc_num", body.num_gc)
addValue(gcNumChart, time, "gc_num_forced", body.num_forced_gc)
}

goroutineChart.update()
sysChart.update()
heapByteChart.update()
heapCountChart.update()

if (cfg.IsGCOn) {
gcByteChart.update()
gcNumChart.update()
updateGC(body.gc_cpu_fraction, body.pause_total_ns, body.last_gc, body.next_gc)
}


if (showWarning) {
showWarning = false
warningToast.classList.remove("block")
warningToast.classList.add("hidden")
}
} catch (err) {
console.error(err)
if (!showWarning) {
showWarning = true
warningToast.classList.remove("hidden")
warningToast.classList.add("block")
}
}
}, cfg.Interval);

const humanReadable = (bytes) => {
const units = ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"]

let unitIndex = 0
while (bytes >= 1024) {
bytes /= 1024
unitIndex++
}

return `${bytes.toFixed(2)} ${units[unitIndex]}`
}

const formatTime = (time) => {
if (time.includes("1970")) return "None";

const ymd = time.split("T")[0]
const hms = time.split("T")[1]


return `${ymd}<br>${hms}`
}
45 changes: 13 additions & 32 deletions assets/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -592,18 +592,14 @@ video {
margin-top: 1.25rem;
}

.block {
display: block;
}

.inline {
display: inline;
}

.flex {
display: flex;
}

.table {
display: table;
}

.grid {
display: grid;
}
Expand Down Expand Up @@ -673,12 +669,13 @@ video {
column-gap: 0.5rem;
}

.overflow-hidden {
overflow: hidden;
.gap-x-3 {
-moz-column-gap: 0.75rem;
column-gap: 0.75rem;
}

.overflow-y-hidden {
overflow-y: hidden;
.overflow-hidden {
overflow: hidden;
}

.rounded {
Expand Down Expand Up @@ -743,6 +740,10 @@ video {
background-color: rgb(127 29 29 / 0.2);
}

.bg-white\/20 {
background-color: rgb(255 255 255 / 0.2);
}

.bg-white\/5 {
background-color: rgb(255 255 255 / 0.05);
}
Expand Down Expand Up @@ -819,10 +820,6 @@ video {
text-decoration-line: underline;
}

.opacity-0 {
opacity: 0;
}

.opacity-100 {
opacity: 1;
}
Expand Down Expand Up @@ -851,22 +848,6 @@ video {
opacity: 0.7;
}

.\[\&\+\.stats\]\:hidden+.stats {
display: none;
}

.\[\&\:checked\+\.stats\]\:block:checked+.stats {
display: block;
}

.\[\&\:has\(input\:checked\)_\.less\]\:inline:has(input:checked) .less {
display: inline;
}

.\[\&\:has\(input\:checked\)_\.more\]\:hidden:has(input:checked) .more {
display: none;
}

.\[\&\>\.row\:last-child\]\:border-b-0>.row:last-child {
border-bottom-width: 0px;
}
Expand Down
Binary file modified img/ss.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion stati.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (s *Stati) StatsPage(w http.ResponseWriter, r *http.Request) {
GOARCH: runtime.GOARCH,
NumCPU: runtime.NumCPU(),
GOVERSION: runtime.Version(),
Version: "v0.0.4",
Version: "v0.0.5",
})
page.Render(r.Context(), w)
}
Expand Down
16 changes: 8 additions & 8 deletions templates/garbage_collector.templ
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,34 @@ templ GarbageCollector(cfg StatsConfig) {
<div class="bg-green-900 px-3 py-1 border-b border-white/20">Garbage Collector</div>
<div class="grid grid-cols-4 gap-5 p-5 border-b border-white/20">
<div class="bg-green-900 p-3 rounded border border-white/20">
<h2>
<h2 class="text-white/50">
GC CPU Fraction
</h2>
<div id="gc_cpu_fraction">
<div x-text="$store.table.gc_cpu_fraction">
0
</div>
</div>
<div class="bg-green-900 p-3 rounded border border-white/20">
<h2>
<h2 class="text-white/50">
Total Pause
</h2>
<div id="total_pause">
<div x-text="$store.table.total_pause">
0ns
</div>
</div>
<div class="bg-green-900 p-3 rounded border border-white/20">
<h2>
<h2 class="text-white/50">
Last GC
</h2>
<div id="last_gc">
<div x-html="$store.table.last_gc">
None
</div>
</div>
<div class="bg-green-900 p-3 rounded border border-white/20">
<h2>
<h2 class="text-white/50">
Next GC Byte Target
</h2>
<div id="next_gc_byte_target">
<div x-text="$store.table.next_gc_byte_target">
0
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion templates/garbage_collector_templ.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 3c222ac

Please sign in to comment.