speed up vm trace pages
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -20,7 +20,7 @@ const (
|
||||
|
||||
// VcenterList renders a list of vCenters being monitored.
|
||||
// @Summary List vCenters
|
||||
// @Description Lists all vCenters with recorded snapshot totals.
|
||||
// @Description Lists all vCenters with recorded snapshot totals, linking to the fast daily aggregated totals page.
|
||||
// @Tags vcenters
|
||||
// @Produce text/html
|
||||
// @Success 200 {string} string "HTML page"
|
||||
@@ -72,7 +72,7 @@ func (h *Handler) VcenterTotals(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// VcenterTotalsDaily renders the daily-aggregation totals page for one vCenter.
|
||||
// @Summary vCenter daily totals
|
||||
// @Description Shows daily aggregated VM count/vCPU/RAM totals for a vCenter.
|
||||
// @Description Shows daily aggregated VM count/vCPU/RAM totals for a vCenter (cache-backed for fast loading).
|
||||
// @Tags vcenters
|
||||
// @Produce text/html
|
||||
// @Param vcenter query string true "vCenter URL"
|
||||
|
||||
@@ -3,20 +3,22 @@ package handler
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
"vctp/components/views"
|
||||
"vctp/db"
|
||||
)
|
||||
|
||||
// VmTrace shows per-snapshot details for a VM across all snapshots.
|
||||
// VmTrace shows VM history in either hourly-detail or daily-aggregated mode.
|
||||
// @Summary Trace VM history
|
||||
// @Description Shows VM resource history across snapshots, with chart and table.
|
||||
// @Description Shows VM resource history with an hourly detail view and a daily aggregated view, with chart and table output.
|
||||
// @Tags vm
|
||||
// @Produce text/html
|
||||
// @Param vm_id query string false "VM ID"
|
||||
// @Param vm_uuid query string false "VM UUID"
|
||||
// @Param name query string false "VM name"
|
||||
// @Param view query string false "hourly|daily (default: hourly)"
|
||||
// @Success 200 {string} string "HTML page"
|
||||
// @Failure 400 {string} string "Missing identifier"
|
||||
// @Router /vm/trace [get]
|
||||
@@ -25,6 +27,11 @@ func (h *Handler) VmTrace(w http.ResponseWriter, r *http.Request) {
|
||||
vmID := r.URL.Query().Get("vm_id")
|
||||
vmUUID := r.URL.Query().Get("vm_uuid")
|
||||
name := r.URL.Query().Get("name")
|
||||
viewType := strings.ToLower(strings.TrimSpace(r.URL.Query().Get("view")))
|
||||
if viewType != "daily" {
|
||||
viewType = "hourly"
|
||||
}
|
||||
meta := buildVmTraceMeta(viewType, vmID, vmUUID, name)
|
||||
|
||||
var entries []views.VmTraceEntry
|
||||
chart := views.VmTraceChart{}
|
||||
@@ -39,12 +46,20 @@ func (h *Handler) VmTrace(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Only fetch data when a query is provided; otherwise render empty page with form.
|
||||
if vmID != "" || vmUUID != "" || name != "" {
|
||||
h.Logger.Info("vm trace request", "vm_id", vmID, "vm_uuid", vmUUID, "name", name)
|
||||
h.Logger.Info("vm trace request", "view", viewType, "vm_id", vmID, "vm_uuid", vmUUID, "name", name)
|
||||
lifecycle, lifeErr := db.FetchVmLifecycle(ctx, h.Database.DB(), vmID, vmUUID, name)
|
||||
if lifeErr != nil {
|
||||
h.Logger.Warn("failed to fetch VM lifecycle", "error", lifeErr)
|
||||
}
|
||||
rows, err := db.FetchVmTrace(ctx, h.Database.DB(), vmID, vmUUID, name)
|
||||
var (
|
||||
rows []db.VmTraceRow
|
||||
err error
|
||||
)
|
||||
if viewType == "daily" {
|
||||
rows, err = db.FetchVmTraceDaily(ctx, h.Database.DB(), vmID, vmUUID, name)
|
||||
} else {
|
||||
rows, err = db.FetchVmTrace(ctx, h.Database.DB(), vmID, vmUUID, name)
|
||||
}
|
||||
if err != nil {
|
||||
h.Logger.Error("failed to fetch VM trace", "error", err)
|
||||
http.Error(w, fmt.Sprintf("failed to fetch VM trace: %v", err), http.StatusInternalServerError)
|
||||
@@ -99,11 +114,47 @@ func (h *Handler) VmTrace(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
if err := views.VmTracePage(queryLabel, displayQuery, vmID, vmUUID, name, creationLabel, deletionLabel, creationApprox, entries, chart).Render(ctx, w); err != nil {
|
||||
if err := views.VmTracePage(queryLabel, displayQuery, vmID, vmUUID, name, creationLabel, deletionLabel, creationApprox, entries, chart, meta).Render(ctx, w); err != nil {
|
||||
http.Error(w, "Failed to render template", http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
func buildVmTraceMeta(viewType, vmID, vmUUID, name string) views.VmTraceMeta {
|
||||
if viewType != "daily" {
|
||||
viewType = "hourly"
|
||||
}
|
||||
addQuery := func(targetView string) string {
|
||||
q := url.Values{}
|
||||
q.Set("view", targetView)
|
||||
if strings.TrimSpace(vmID) != "" {
|
||||
q.Set("vm_id", vmID)
|
||||
}
|
||||
if strings.TrimSpace(vmUUID) != "" {
|
||||
q.Set("vm_uuid", vmUUID)
|
||||
}
|
||||
if strings.TrimSpace(name) != "" {
|
||||
q.Set("name", name)
|
||||
}
|
||||
return "/vm/trace?" + q.Encode()
|
||||
}
|
||||
|
||||
meta := views.VmTraceMeta{
|
||||
ViewType: viewType,
|
||||
TypeLabel: "Hourly",
|
||||
HourlyLink: addQuery("hourly"),
|
||||
DailyLink: addQuery("daily"),
|
||||
HourlyClass: "web3-button",
|
||||
DailyClass: "web3-button",
|
||||
}
|
||||
if viewType == "daily" {
|
||||
meta.TypeLabel = "Daily"
|
||||
meta.DailyClass = "web3-button active"
|
||||
} else {
|
||||
meta.HourlyClass = "web3-button active"
|
||||
}
|
||||
return meta
|
||||
}
|
||||
|
||||
func buildVmTraceChart(entries []views.VmTraceEntry) views.VmTraceChart {
|
||||
if len(entries) == 0 {
|
||||
return views.VmTraceChart{}
|
||||
|
||||
@@ -876,7 +876,7 @@ const docTemplate = `{
|
||||
},
|
||||
"/vcenters": {
|
||||
"get": {
|
||||
"description": "Lists all vCenters with recorded snapshot totals.",
|
||||
"description": "Lists all vCenters with recorded snapshot totals, linking to the fast daily aggregated totals page.",
|
||||
"produces": [
|
||||
"text/html"
|
||||
],
|
||||
@@ -943,7 +943,7 @@ const docTemplate = `{
|
||||
},
|
||||
"/vcenters/totals/daily": {
|
||||
"get": {
|
||||
"description": "Shows daily aggregated VM count/vCPU/RAM totals for a vCenter.",
|
||||
"description": "Shows daily aggregated VM count/vCPU/RAM totals for a vCenter (cache-backed for fast loading).",
|
||||
"produces": [
|
||||
"text/html"
|
||||
],
|
||||
@@ -1019,7 +1019,7 @@ const docTemplate = `{
|
||||
},
|
||||
"/vm/trace": {
|
||||
"get": {
|
||||
"description": "Shows VM resource history across snapshots, with chart and table.",
|
||||
"description": "Shows VM resource history with an hourly detail view and a daily aggregated view, with chart and table output.",
|
||||
"produces": [
|
||||
"text/html"
|
||||
],
|
||||
@@ -1045,6 +1045,12 @@ const docTemplate = `{
|
||||
"description": "VM name",
|
||||
"name": "name",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "hourly|daily (default: hourly)",
|
||||
"name": "view",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
||||
@@ -865,7 +865,7 @@
|
||||
},
|
||||
"/vcenters": {
|
||||
"get": {
|
||||
"description": "Lists all vCenters with recorded snapshot totals.",
|
||||
"description": "Lists all vCenters with recorded snapshot totals, linking to the fast daily aggregated totals page.",
|
||||
"produces": [
|
||||
"text/html"
|
||||
],
|
||||
@@ -932,7 +932,7 @@
|
||||
},
|
||||
"/vcenters/totals/daily": {
|
||||
"get": {
|
||||
"description": "Shows daily aggregated VM count/vCPU/RAM totals for a vCenter.",
|
||||
"description": "Shows daily aggregated VM count/vCPU/RAM totals for a vCenter (cache-backed for fast loading).",
|
||||
"produces": [
|
||||
"text/html"
|
||||
],
|
||||
@@ -1008,7 +1008,7 @@
|
||||
},
|
||||
"/vm/trace": {
|
||||
"get": {
|
||||
"description": "Shows VM resource history across snapshots, with chart and table.",
|
||||
"description": "Shows VM resource history with an hourly detail view and a daily aggregated view, with chart and table output.",
|
||||
"produces": [
|
||||
"text/html"
|
||||
],
|
||||
@@ -1034,6 +1034,12 @@
|
||||
"description": "VM name",
|
||||
"name": "name",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "hourly|daily (default: hourly)",
|
||||
"name": "view",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
||||
@@ -871,7 +871,8 @@ paths:
|
||||
- snapshots
|
||||
/vcenters:
|
||||
get:
|
||||
description: Lists all vCenters with recorded snapshot totals.
|
||||
description: Lists all vCenters with recorded snapshot totals, linking to the
|
||||
fast daily aggregated totals page.
|
||||
produces:
|
||||
- text/html
|
||||
responses:
|
||||
@@ -916,7 +917,8 @@ paths:
|
||||
- vcenters
|
||||
/vcenters/totals/daily:
|
||||
get:
|
||||
description: Shows daily aggregated VM count/vCPU/RAM totals for a vCenter.
|
||||
description: Shows daily aggregated VM count/vCPU/RAM totals for a vCenter (cache-backed
|
||||
for fast loading).
|
||||
parameters:
|
||||
- description: vCenter URL
|
||||
in: query
|
||||
@@ -967,7 +969,8 @@ paths:
|
||||
- vcenters
|
||||
/vm/trace:
|
||||
get:
|
||||
description: Shows VM resource history across snapshots, with chart and table.
|
||||
description: Shows VM resource history with an hourly detail view and a daily
|
||||
aggregated view, with chart and table output.
|
||||
parameters:
|
||||
- description: VM ID
|
||||
in: query
|
||||
@@ -981,6 +984,10 @@ paths:
|
||||
in: query
|
||||
name: name
|
||||
type: string
|
||||
- description: 'hourly|daily (default: hourly)'
|
||||
in: query
|
||||
name: view
|
||||
type: string
|
||||
produces:
|
||||
- text/html
|
||||
responses:
|
||||
|
||||
Reference in New Issue
Block a user