功能:补充固定场景助手与GPU健康诊断能力

This commit is contained in:
songyiming committed 2026-11-12 17:33:07 +08:00
1 parent 9f05aa20ea
commit b6026f9759
29 files changed
+1333 -22

No files matched your search

+53
View File
@@ -53,6 +53,59 @@ type diagnosticReport struct {
Source string `json:"source"`
Notes []string `json:"notes"`
}
type terminalLogArchive struct {
ID string `json:"id" db:"id"`
TaskID string `json:"taskId" db:"task_id"`
TerminalID string `json:"terminalId" db:"terminal_id"`
TerminalName string `json:"terminalName" db:"terminal_name"`
CapturedAt time.Time `json:"capturedAt" db:"captured_at"`
BootID string `json:"bootId" db:"boot_id"`
AgentVersion string `json:"agentVersion" db:"agent_version"`
KioskState string `json:"kioskState" db:"kiosk_state"`
LogText string `json:"logText" db:"log_text"`
}
type terminalLogArchivePage struct {
Items []terminalLogArchive `json:"items"`
Page int `json:"page"`
PageSize int `json:"pageSize"`
Total int `json:"total"`
ObservedAt time.Time `json:"observedAt"`
RetentionDays int `json:"retentionDays"`
}
func (s *Server) terminalLogArchives(c *gin.Context) {
terminalID, keyword := strings.TrimSpace(c.Query("terminalId")), strings.TrimSpace(c.Query("keyword"))
if len(terminalID) > 100 || len(keyword) > 200 || strings.IndexByte(terminalID, 0) >= 0 || strings.IndexByte(keyword, 0) >= 0 {
s.fail(c, 400, "invalid_request", "日志筛选条件无效")
return
}
from, to, ok := timeRange(c, 30)
if !ok {
s.fail(c, 400, "invalid_range", "请选择有效时间范围,最长 30 天,时间需包含时区")
return
}
page, size := pageParams(c)
args := []any{from, to, terminalID, keyword}
var total int
if err := s.DB.GetContext(c.Request.Context(), &total, `SELECT count(*) FROM terminal_log_archives WHERE captured_at>=$1 AND captured_at<=$2 AND ($3='' OR terminal_id=$3) AND ($4='' OR log_text ILIKE '%'||$4||'%')`, args...); err != nil {
s.dbError(c, err)
return
}
items := []terminalLogArchive{}
args = append(args, size, (page-1)*size)
if err := s.DB.SelectContext(c.Request.Context(), &items, `SELECT a.id,a.task_id,a.terminal_id,t.name terminal_name,a.captured_at,a.boot_id,a.agent_version,a.kiosk_state,a.log_text FROM terminal_log_archives a JOIN terminals t ON t.id=a.terminal_id WHERE a.captured_at>=$1 AND a.captured_at<=$2 AND ($3='' OR a.terminal_id=$3) AND ($4='' OR a.log_text ILIKE '%'||$4||'%') ORDER BY a.captured_at DESC,a.id DESC LIMIT $5 OFFSET $6`, args...); err != nil {
s.dbError(c, err)
return
}
for i := range items {
items[i].BootID = redactDiagnostic(items[i].BootID)
items[i].AgentVersion = redactDiagnostic(items[i].AgentVersion)
items[i].KioskState = redactDiagnostic(items[i].KioskState)
items[i].TerminalName = redactDiagnostic(items[i].TerminalName)
items[i].LogText = redactDiagnostic(items[i].LogText)
}
c.JSON(200, terminalLogArchivePage{Items: items, Page: page, PageSize: size, Total: total, ObservedAt: time.Now().UTC(), RetentionDays: 30})
}
// Correlation uses stable IDs, never a display name. Desktop logs are not
// inferred from a device's current binding: that device may serve other VMs.