mirror of
https://github.com/yusing/godoxy.git
synced 2026-03-27 11:31:06 +01:00
Implement a new API endpoint to retrieve real-time statistics for Proxmox LXC containers, similar to `docker stats` functionality. Changes: - Add `GET /api/v1/proxmox/stats/:node/:vmid` endpoint with HTTP and WebSocket support - Implement resource polling loop to cache VM metadata every 3 seconds - Create `LXCStats()` method with streaming (websocket) and single-shot modes - Format output as: STATUS|CPU%|MEM USAGE/LIMIT|MEM%|NET I/O|BLOCK I/O - Add `GetResource()` method for efficient VM resource lookup by kind and ID - Fix task creation bug using correct client reference Example response: running|31.1%|9.6GiB/20GiB|48.87%|4.7GiB/3.3GiB|25GiB/36GiB
67 lines
1.9 KiB
Go
67 lines
1.9 KiB
Go
package proxmoxapi
|
|
|
|
import (
|
|
"io"
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/yusing/godoxy/internal/proxmox"
|
|
"github.com/yusing/goutils/apitypes"
|
|
"github.com/yusing/goutils/http/websocket"
|
|
)
|
|
|
|
type JournalctlRequest struct {
|
|
Node string `uri:"node" binding:"required"`
|
|
VMID int `uri:"vmid" binding:"required"`
|
|
Service string `uri:"service" binding:"required"`
|
|
}
|
|
|
|
// @x-id "journalctl"
|
|
// @BasePath /api/v1
|
|
// @Summary Get journalctl output
|
|
// @Description Get journalctl output
|
|
// @Tags proxmox,websocket
|
|
// @Accept json
|
|
// @Produce application/json
|
|
// @Param path path JournalctlRequest true "Request"
|
|
// @Success 200 string plain "Journalctl output"
|
|
// @Failure 400 {object} apitypes.ErrorResponse "Invalid request"
|
|
// @Failure 403 {object} apitypes.ErrorResponse "Unauthorized"
|
|
// @Failure 404 {object} apitypes.ErrorResponse "Node not found"
|
|
// @Failure 500 {object} apitypes.ErrorResponse "Internal server error"
|
|
// @Router /api/v1/proxmox/journalctl/{node}/{vmid}/{service} [get]
|
|
func Journalctl(c *gin.Context) {
|
|
var request JournalctlRequest
|
|
if err := c.ShouldBindUri(&request); err != nil {
|
|
c.JSON(http.StatusBadRequest, apitypes.Error("invalid request", err))
|
|
return
|
|
}
|
|
|
|
node, ok := proxmox.Nodes.Get(request.Node)
|
|
if !ok {
|
|
c.JSON(http.StatusNotFound, apitypes.Error("node not found"))
|
|
return
|
|
}
|
|
|
|
manager, err := websocket.NewManagerWithUpgrade(c)
|
|
if err != nil {
|
|
c.Error(apitypes.InternalServerError(err, "failed to upgrade to websocket"))
|
|
return
|
|
}
|
|
defer manager.Close()
|
|
|
|
reader, err := node.LXCJournalctl(c.Request.Context(), request.VMID, request.Service)
|
|
if err != nil {
|
|
c.Error(apitypes.InternalServerError(err, "failed to get journalctl output"))
|
|
return
|
|
}
|
|
defer reader.Close()
|
|
|
|
writer := manager.NewWriter(websocket.TextMessage)
|
|
_, err = io.Copy(writer, reader)
|
|
if err != nil {
|
|
c.Error(apitypes.InternalServerError(err, "failed to copy journalctl output"))
|
|
return
|
|
}
|
|
}
|