功能:完善云管助手与GPU故障恢复核对
这个提交包含在:
1 父节点
b6026f9759
当前提交
9f7b01e4db
42 个文件已更改
+3576
-120
没有与搜索条件相匹配的文件
@@ -140,6 +140,58 @@ func (s *Server) heartbeat(c *gin.Context) {
|
||||
}
|
||||
s.deviceJSON(c, 200, gin.H{"accepted": true, "serverTime": time.Now().UTC()})
|
||||
}
|
||||
|
||||
// appendTerminalLogs accepts small log batches from an online terminal. It is
|
||||
// deliberately separate from collect-logs: agents can stream useful events
|
||||
// during normal operation without creating a management task for every batch.
|
||||
func (s *Server) appendTerminalLogs(c *gin.Context) {
|
||||
var in struct {
|
||||
BootID string `json:"bootId" binding:"max=120"`
|
||||
Entries []struct {
|
||||
CapturedAt string `json:"capturedAt"`
|
||||
Level string `json:"level" binding:"omitempty,oneof=debug info warn error"`
|
||||
Message string `json:"message" binding:"required,max=16000"`
|
||||
} `json:"entries" binding:"required,min=1,max=100"`
|
||||
}
|
||||
if !s.decode(c, &in) {
|
||||
return
|
||||
}
|
||||
if len(in.Entries) == 0 {
|
||||
s.fail(c, 400, "invalid_logs", "日志批次不能为空")
|
||||
return
|
||||
}
|
||||
if len(in.BootID) > 120 || strings.IndexByte(in.BootID, 0) >= 0 {
|
||||
s.fail(c, 400, "invalid_logs", "日志启动标识无效")
|
||||
return
|
||||
}
|
||||
tx := deviceTx(c)
|
||||
for _, entry := range in.Entries {
|
||||
message := redactDiagnostic(strings.TrimSpace(entry.Message))
|
||||
if message == "" || len(message) > 16000 {
|
||||
s.fail(c, 400, "invalid_logs", "日志内容不能为空或超出长度限制")
|
||||
return
|
||||
}
|
||||
capturedAt := time.Now().UTC()
|
||||
if strings.TrimSpace(entry.CapturedAt) != "" {
|
||||
parsed, err := time.Parse(time.RFC3339Nano, entry.CapturedAt)
|
||||
if err != nil || parsed.After(time.Now().Add(2*time.Minute)) || parsed.Before(time.Now().Add(-10*time.Minute)) {
|
||||
s.fail(c, 400, "invalid_logs", "日志时间必须是最近 10 分钟内的 RFC3339 时间")
|
||||
return
|
||||
}
|
||||
capturedAt = parsed.UTC()
|
||||
}
|
||||
level := strings.TrimSpace(entry.Level)
|
||||
if level == "" {
|
||||
level = "info"
|
||||
}
|
||||
if _, err := tx.ExecContext(c.Request.Context(), `INSERT INTO terminal_log_entries(id,terminal_id,captured_at,boot_id,level,message) VALUES($1,$2,$3,$4,$5,$6)`, store.ID("log_"), c.GetString("terminalId"), capturedAt, redactDiagnostic(in.BootID), level, message); err != nil {
|
||||
s.dbError(c, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
_, _ = tx.ExecContext(c.Request.Context(), "UPDATE terminals SET last_seen=now(),status='online' WHERE id=$1", c.GetString("terminalId"))
|
||||
s.deviceJSON(c, 202, gin.H{"accepted": len(in.Entries), "serverTime": time.Now().UTC()})
|
||||
}
|
||||
func (s *Server) deviceConfig(c *gin.Context) {
|
||||
var version int
|
||||
if err := deviceTx(c).GetContext(c.Request.Context(), &version, "SELECT config_version FROM terminals WHERE id=$1", c.GetString("terminalId")); err != nil {
|
||||
|
||||
在新工单中引用
屏蔽一个用户