P8(1): restore homepage overview curves on a memory-only sampling ring
Backend: new overviewMetrics store — a single-tier (2s x 360 = 12min) in-memory ring fed by ServerService.RefreshStatus for exactly the eight overview series (cpu/mem/swap/diskUsage/netUp/netDown/tcpCount/udpCount). No persistence, no gob snapshot, no system-history page: the only surface is GET /panel/api/server/history/:metric/:bucket restricted to those keys, which seeds the frontend curves. ~46KB bounded by construction; the ring starts empty on every panel start. Frontend: restore useOverviewHistory + the VitalTile/ThroughputCard/ ConnectionsCard sparklines and the IndexPage wiring exactly as they were before P7 removed them along with the history module.
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strconv"
|
||||
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/database/model"
|
||||
@@ -39,6 +40,7 @@ func NewServerController(g *gin.RouterGroup) *ServerController {
|
||||
// initRouter sets up the routes for server status, Xray management, and utility endpoints.
|
||||
func (a *ServerController) initRouter(g *gin.RouterGroup) {
|
||||
g.GET("/status", a.status)
|
||||
g.GET("/history/:metric/:bucket", a.getOverviewHistoryBucket)
|
||||
g.GET("/getPanelUpdateInfo", a.getPanelUpdateInfo)
|
||||
g.GET("/getUpdateStatus", a.getUpdateStatus)
|
||||
g.GET("/getConfigJson", a.getConfigJson)
|
||||
@@ -86,6 +88,25 @@ func (a *ServerController) startTask() {
|
||||
// status returns the current server status information.
|
||||
func (a *ServerController) status(c *gin.Context) { jsonObj(c, a.serverService.LastStatus(), nil) }
|
||||
|
||||
// getOverviewHistoryBucket returns up to 60 buckets of one homepage
|
||||
// overview metric (see service.OverviewMetricKeys). It backs only the
|
||||
// index-page sparkline seed; the store behind it is the memory-only
|
||||
// overview ring — not the removed system-history API (no other metrics,
|
||||
// no persistence, nothing to browse beyond the overview window).
|
||||
func (a *ServerController) getOverviewHistoryBucket(c *gin.Context) {
|
||||
metric := c.Param("metric")
|
||||
if !slices.Contains(service.OverviewMetricKeys, metric) {
|
||||
jsonMsg(c, "invalid metric", fmt.Errorf("unknown metric"))
|
||||
return
|
||||
}
|
||||
bucket, err := strconv.Atoi(c.Param("bucket"))
|
||||
if err != nil || bucket <= 0 || !service.IsAllowedHistoryBucket(bucket) {
|
||||
jsonMsg(c, "invalid bucket", fmt.Errorf("unsupported bucket"))
|
||||
return
|
||||
}
|
||||
jsonObj(c, a.serverService.AggregateOverviewMetric(metric, bucket, 60), nil)
|
||||
}
|
||||
|
||||
func (a *ServerController) getFail2banStatus(c *gin.Context) {
|
||||
jsonObj(c, a.serverService.GetFail2banStatus(), nil)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user