api: expose v2 proxy timestamps as unix seconds (#5402)

This commit is contained in:
fatedier
2026-07-09 14:47:19 +08:00
committed by GitHub
parent becee40715
commit 84be1938e4
9 changed files with 43 additions and 8 deletions

View File

@@ -239,9 +239,11 @@ func toProxyStats(name string, proxyStats *ProxyStatistics) *ProxyStats {
}
if !proxyStats.LastStartTime.IsZero() {
ps.LastStartTime = proxyStats.LastStartTime.Format("01-02 15:04:05")
ps.LastStartAt = proxyStats.LastStartTime.Unix()
}
if !proxyStats.LastCloseTime.IsZero() {
ps.LastCloseTime = proxyStats.LastCloseTime.Format("01-02 15:04:05")
ps.LastCloseAt = proxyStats.LastCloseTime.Unix()
}
return ps
}

View File

@@ -22,6 +22,12 @@ func TestServerMetricsUsesClockForProxyTimestamps(t *testing.T) {
clk.SetTime(closedAt)
metrics.CloseProxy("proxy", "tcp")
require.Equal(closedAt, metrics.info.ProxyStatistics["proxy"].LastCloseTime)
stats := metrics.GetProxyByName("proxy")
require.Equal(start.Format("01-02 15:04:05"), stats.LastStartTime)
require.Equal(closedAt.Format("01-02 15:04:05"), stats.LastCloseTime)
require.Equal(start.Unix(), stats.LastStartAt)
require.Equal(closedAt.Unix(), stats.LastCloseAt)
}
func TestServerMetricsClearUselessInfoUsesClock(t *testing.T) {

View File

@@ -41,6 +41,8 @@ type ProxyStats struct {
TodayTrafficOut int64
LastStartTime string
LastCloseTime string
LastStartAt int64
LastCloseAt int64
CurConns int64
}

View File

@@ -545,8 +545,8 @@ func (c *Controller) buildV2ProxyResp(ps *mem.ProxyStats) model.V2ProxyResp {
TodayTrafficIn: ps.TodayTrafficIn,
TodayTrafficOut: ps.TodayTrafficOut,
CurConns: ps.CurConns,
LastStartTime: ps.LastStartTime,
LastCloseTime: ps.LastCloseTime,
LastStartAt: ps.LastStartAt,
LastCloseAt: ps.LastCloseAt,
},
}
}

View File

@@ -421,10 +421,22 @@ func TestAPIV2ProxyListDetailAndUsers(t *testing.T) {
}
resp = performRequest(router, "/api/v2/proxies/tcp-alice")
rawProxyDetailResp := decodeResponse[v2EnvelopeForTest[map[string]json.RawMessage]](t, resp)
assertRawJSONKeysFromMessage(t, rawProxyDetailResp.Data["status"],
"curConns",
"lastCloseAt",
"lastStartAt",
"phase",
"todayTrafficIn",
"todayTrafficOut",
)
proxyDetailResp := decodeResponse[v2EnvelopeForTest[model.V2ProxyResp]](t, resp)
if proxyDetailResp.Data.Name != "tcp-alice" || proxyDetailResp.Data.User != "alice" {
t.Fatalf("proxy detail mismatch: %#v", proxyDetailResp.Data)
}
if proxyDetailResp.Data.Status.LastStartAt != 1783504200 || proxyDetailResp.Data.Status.LastCloseAt != 1783504300 {
t.Fatalf("proxy detail timestamp mismatch: %#v", proxyDetailResp.Data.Status)
}
resp = performRequest(router, "/api/v2/users?page=1&pageSize=50")
userResp := decodeResponse[v2EnvelopeForTest[model.V2PageResp[model.V2UserResp]]](t, resp)
@@ -744,6 +756,10 @@ func newV2TestController(t *testing.T) *Controller {
TodayTrafficIn: 30,
TodayTrafficOut: 40,
CurConns: 2,
LastStartTime: "07-08 12:30:00",
LastCloseTime: "07-08 12:31:40",
LastStartAt: 1783504200,
LastCloseAt: 1783504300,
},
"http-alice": {
Name: "http-alice",

View File

@@ -87,8 +87,8 @@ type V2ProxyStatusResp struct {
TodayTrafficIn int64 `json:"todayTrafficIn"`
TodayTrafficOut int64 `json:"todayTrafficOut"`
CurConns int64 `json:"curConns"`
LastStartTime string `json:"lastStartTime"`
LastCloseTime string `json:"lastCloseTime"`
LastStartAt int64 `json:"lastStartAt,omitempty"`
LastCloseAt int64 `json:"lastCloseAt,omitempty"`
}
type V2ProxyTrafficResp struct {

View File

@@ -1,4 +1,5 @@
import { buildQueryString, http } from './http'
import { formatUnixSeconds } from '../utils/format'
import type { V2Page } from './http'
import type {
GetProxyResponse,
@@ -47,8 +48,8 @@ export const toLegacyProxyStats = (proxy: ProxyV2Info): ProxyStatsInfo => ({
todayTrafficIn: proxy.status.todayTrafficIn,
todayTrafficOut: proxy.status.todayTrafficOut,
curConns: proxy.status.curConns,
lastStartTime: proxy.status.lastStartTime,
lastCloseTime: proxy.status.lastCloseTime,
lastStartTime: formatUnixSeconds(proxy.status.lastStartAt),
lastCloseTime: formatUnixSeconds(proxy.status.lastCloseAt),
status: proxy.status.phase,
})

View File

@@ -40,8 +40,8 @@ export interface ProxyV2Status {
todayTrafficIn: number
todayTrafficOut: number
curConns: number
lastStartTime: string
lastCloseTime: string
lastStartAt?: number
lastCloseAt?: number
}
export interface TrafficResponse {

View File

@@ -19,6 +19,14 @@ export function formatDistanceToNow(date: Date): string {
return Math.floor(seconds) + ' seconds ago'
}
export function formatUnixSeconds(seconds?: number): string {
if (seconds == null || !Number.isFinite(seconds) || seconds <= 0) return ''
const date = new Date(seconds * 1000)
const pad = (value: number) => value.toString().padStart(2, '0')
return `${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`
}
export function formatFileSize(bytes: number): string {
if (!Number.isFinite(bytes) || bytes < 0) return '0 B'
if (bytes === 0) return '0 B'