host now generates a piechart for memory usage

This commit is contained in:
Matthew Stobbs 2024-03-16 11:34:17 -06:00
parent d10aea8d8c
commit 5ae4fb3ab9
5 changed files with 119 additions and 34 deletions

View File

@ -1,6 +1,7 @@
package host package host
import ( import (
"log"
"strings" "strings"
"github.com/wcharczuk/go-chart/v2" "github.com/wcharczuk/go-chart/v2"
@ -10,16 +11,21 @@ import (
// When a chart is rendered, it can return either an SVG or PNG. SVG is preferrable. // When a chart is rendered, it can return either an SVG or PNG. SVG is preferrable.
func (h *Host) ChartMemory() string { func (h *Host) ChartMemory() string {
h.getNodeInfo()
log.Println("Generating Chart")
c := chart.PieChart{ c := chart.PieChart{
Width: 256, Width: 128,
Height: 256, Height: 128,
Values: []chart.Value{ Values: []chart.Value{
{Value: float64(h.NodeMemory.Free / h.NodeMemory.Total), Label: "Free"}, {Value: float64(h.NodeMemory.Free) / float64(h.NodeMemory.Total), Label: "Free"},
{Value: float64(h.NodeMemory.Cached / h.NodeMemory.Total), Label: "Cached"}, {Value: float64(h.NodeMemory.Cached) / float64(h.NodeMemory.Total), Label: "Cached"},
{Value: float64(h.NodeMemory.Buffers / h.NodeMemory.Total), Label: "Buffers"}, {Value: float64(h.NodeMemory.Buffers) / float64(h.NodeMemory.Total), Label: "Buffers"},
}, },
} }
sb := new(strings.Builder) sb := new(strings.Builder)
c.Render(chart.SVG, sb) log.Println("Rendering chart")
if err := c.Render(chart.SVG, sb); err != nil {
return err.Error()
}
return sb.String() return sb.String()
} }

View File

@ -228,9 +228,9 @@ func (h *Host) Close() error {
// private methods that load the different informational parts // private methods that load the different informational parts
func (h *Host) getInfo() { func (h *Host) getInfo() {
var wg sync.WaitGroup var wg = new(sync.WaitGroup)
infoFuncs := []func(*sync.WaitGroup){ infoFuncs := []func(){
h.getDevicesInfo, h.getDevicesInfo,
h.getDomainInfo, h.getDomainInfo,
h.getIfaceInfo, h.getIfaceInfo,
@ -243,14 +243,16 @@ func (h *Host) getInfo() {
for _, f := range infoFuncs { for _, f := range infoFuncs {
wg.Add(1) wg.Add(1)
f(&wg) go func(wg *sync.WaitGroup) {
defer wg.Done()
f()
}(wg)
} }
wg.Wait() wg.Wait()
} }
func (h *Host) getStoragePools(wg *sync.WaitGroup) { func (h *Host) getStoragePools() {
defer wg.Done()
spools, err := h.conn.ListAllStoragePools(0) spools, err := h.conn.ListAllStoragePools(0)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
@ -321,8 +323,7 @@ func (h *Host) getStoragePools(wg *sync.WaitGroup) {
} }
} }
func (h *Host) getSecretsInfo(wg *sync.WaitGroup) { func (h *Host) getSecretsInfo() {
defer wg.Done()
nsecrets, err := h.conn.ListAllSecrets(0) nsecrets, err := h.conn.ListAllSecrets(0)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
@ -344,8 +345,7 @@ func (h *Host) getSecretsInfo(wg *sync.WaitGroup) {
} }
} }
func (h *Host) getNodeInfo(wg *sync.WaitGroup) { func (h *Host) getNodeInfo() {
defer wg.Done()
var err error var err error
h.AvailableCPUTypes, err = h.conn.GetCPUModelNames("x86_64", 0) h.AvailableCPUTypes, err = h.conn.GetCPUModelNames("x86_64", 0)
if err != nil { if err != nil {
@ -413,8 +413,7 @@ func (h *Host) getNodeInfo(wg *sync.WaitGroup) {
} }
} }
func (h *Host) getSEVInfo(wg *sync.WaitGroup) { func (h *Host) getSEVInfo() {
defer wg.Done()
// getSEVInfo // getSEVInfo
h.HostSEVInfo.SEVEnabled = true h.HostSEVInfo.SEVEnabled = true
ns, err := h.conn.GetSEVInfo(0) ns, err := h.conn.GetSEVInfo(0)
@ -442,8 +441,7 @@ func (h *Host) getSEVInfo(wg *sync.WaitGroup) {
} }
} }
func (h *Host) getDomainInfo(wg *sync.WaitGroup) { func (h *Host) getDomainInfo() {
defer wg.Done()
// getDomainInfo // getDomainInfo
doms, err := h.conn.ListAllDomains(0) doms, err := h.conn.ListAllDomains(0)
if err != nil { if err != nil {
@ -471,8 +469,7 @@ func (h *Host) getDomainInfo(wg *sync.WaitGroup) {
} }
} }
func (h *Host) getIfaceInfo(wg *sync.WaitGroup) { func (h *Host) getIfaceInfo() {
defer wg.Done()
// getIfaceInfo // getIfaceInfo
ifaces, err := h.conn.ListInterfaces() ifaces, err := h.conn.ListInterfaces()
if err != nil { if err != nil {
@ -498,8 +495,7 @@ func (h *Host) getIfaceInfo(wg *sync.WaitGroup) {
} }
} }
func (h *Host) getNetsInfo(wg *sync.WaitGroup) { func (h *Host) getNetsInfo() {
defer wg.Done()
// getNetsInfo // getNetsInfo
nets, err := h.conn.ListNetworks() nets, err := h.conn.ListNetworks()
if err != nil { if err != nil {
@ -527,8 +523,7 @@ func (h *Host) getNetsInfo(wg *sync.WaitGroup) {
} }
} }
func (h *Host) getDevicesInfo(wg *sync.WaitGroup) { func (h *Host) getDevicesInfo() {
defer wg.Done()
ndevs, err := h.conn.ListAllNodeDevices(0) ndevs, err := h.conn.ListAllNodeDevices(0)
if err != nil { if err != nil {
log.Println(err) log.Println(err)

View File

@ -852,6 +852,11 @@ span>a:visited {
display: contents; display: contents;
} }
.size-64 {
width: 16rem;
height: 16rem;
}
.h-28 { .h-28 {
height: 7rem; height: 7rem;
} }

View File

@ -1,12 +1,21 @@
package components package components
import ( import (
"fmt"
"git.staur.ca/stobbsm/clustvirt/lib/host" "git.staur.ca/stobbsm/clustvirt/lib/host"
) )
// HostInfo is meant to be an HTMX response // HostInfo is meant to be an HTMX response
templ HostInfo(h *host.Host) { templ HostInfo(h *host.Host) {
<body> <body>
<div class={ "size-64" }>
@templ.Raw(h.ChartMemory()) @templ.Raw(h.ChartMemory())
</div>
<ul>
<li>Free: { fmt.Sprintf("%d MB", h.NodeMemory.Free / 1024) }</li>
<li>Cached: { fmt.Sprintf("%d MB", h.NodeMemory.Cached / 1024) }</li>
<li>Buffers: { fmt.Sprintf("%d MB", h.NodeMemory.Buffers / 1024) }</li>
<li>Total: { fmt.Sprintf("%d MB", h.NodeMemory.Total / 1024) }</li>
</ul>
</body> </body>
} }

View File

@ -11,6 +11,7 @@ import "io"
import "bytes" import "bytes"
import ( import (
"fmt"
"git.staur.ca/stobbsm/clustvirt/lib/host" "git.staur.ca/stobbsm/clustvirt/lib/host"
) )
@ -32,11 +33,80 @@ func HostInfo(h *host.Host) templ.Component {
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
var templ_7745c5c3_Var2 = []any{"size-64"}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var2).String()))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.Raw(h.ChartMemory()).Render(ctx, templ_7745c5c3_Buffer) templ_7745c5c3_Err = templ.Raw(h.ChartMemory()).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</body>") _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><ul><li>Free: ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d MB", h.NodeMemory.Free/1024))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/components/hostinfo.templ`, Line: 14, Col: 61}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</li><li>Cached: ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d MB", h.NodeMemory.Cached/1024))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/components/hostinfo.templ`, Line: 15, Col: 65}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</li><li>Buffers: ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d MB", h.NodeMemory.Buffers/1024))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/components/hostinfo.templ`, Line: 16, Col: 67}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</li><li>Total: ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d MB", h.NodeMemory.Total/1024))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/components/hostinfo.templ`, Line: 17, Col: 63}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</li></ul></body>")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }