feat(logging): implement client log streaming and management
All checks were successful
Build Multi-Platform Binaries / build-frontend (push) Successful in 30s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 1m16s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 1m4s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 2m29s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 54s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 2m35s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 55s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 2m21s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Successful in 1m35s
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Successful in 1m1s
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Successful in 1m55s
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Successful in 1m39s
All checks were successful
Build Multi-Platform Binaries / build-frontend (push) Successful in 30s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 1m16s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 1m4s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 2m29s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 54s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 2m35s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 55s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 2m21s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Successful in 1m35s
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Successful in 1m1s
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Successful in 1m55s
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Successful in 1m39s
- Added log streaming functionality for clients, allowing real-time log access via SSE. - Introduced LogHandler to manage log streaming requests and responses. - Implemented LogSessionManager to handle active log sessions and listeners. - Enhanced protocol with log-related message types and structures. - Created Logger for client-side logging, supporting various log levels and file output. - Developed LogViewer component for the web interface to display and filter logs. - Updated API to support log stream creation and management. - Added support for querying logs by level and searching through log messages.
This commit is contained in:
96
internal/server/router/handler/log.go
Normal file
96
internal/server/router/handler/log.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"io"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// LogHandler 日志处理器
|
||||
type LogHandler struct {
|
||||
app AppInterface
|
||||
}
|
||||
|
||||
// NewLogHandler 创建日志处理器
|
||||
func NewLogHandler(app AppInterface) *LogHandler {
|
||||
return &LogHandler{app: app}
|
||||
}
|
||||
|
||||
// StreamLogs 流式传输客户端日志
|
||||
// @Summary 流式传输客户端日志
|
||||
// @Description 通过 Server-Sent Events 实时接收客户端日志
|
||||
// @Tags Logs
|
||||
// @Produce text/event-stream
|
||||
// @Security Bearer
|
||||
// @Param id path string true "客户端 ID"
|
||||
// @Param lines query int false "初始日志行数" default(100)
|
||||
// @Param follow query bool false "是否持续推送新日志" default(true)
|
||||
// @Param level query string false "日志级别过滤 (info, warn, error)"
|
||||
// @Success 200 {object} protocol.LogEntry
|
||||
// @Router /api/client/{id}/logs [get]
|
||||
func (h *LogHandler) StreamLogs(c *gin.Context) {
|
||||
clientID := c.Param("id")
|
||||
|
||||
// 检查客户端是否在线
|
||||
online, _, _ := h.app.GetServer().GetClientStatus(clientID)
|
||||
if !online {
|
||||
c.JSON(400, gin.H{"code": 400, "message": "client not online"})
|
||||
return
|
||||
}
|
||||
|
||||
// 解析查询参数
|
||||
lines := 100
|
||||
if v := c.Query("lines"); v != "" {
|
||||
if n, err := strconv.Atoi(v); err == nil {
|
||||
lines = n
|
||||
}
|
||||
}
|
||||
|
||||
follow := true
|
||||
if v := c.Query("follow"); v == "false" {
|
||||
follow = false
|
||||
}
|
||||
|
||||
level := c.Query("level")
|
||||
|
||||
// 生成会话 ID
|
||||
sessionID := uuid.New().String()
|
||||
|
||||
// 启动日志流
|
||||
logCh, err := h.app.GetServer().StartClientLogStream(clientID, sessionID, lines, follow, level)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"code": 500, "message": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// 设置 SSE 响应头
|
||||
c.Writer.Header().Set("Content-Type", "text/event-stream")
|
||||
c.Writer.Header().Set("Cache-Control", "no-cache")
|
||||
c.Writer.Header().Set("Connection", "keep-alive")
|
||||
c.Writer.Header().Set("X-Accel-Buffering", "no")
|
||||
|
||||
// 获取客户端断开信号
|
||||
clientGone := c.Request.Context().Done()
|
||||
|
||||
// 流式传输日志
|
||||
c.Stream(func(w io.Writer) bool {
|
||||
select {
|
||||
case <-clientGone:
|
||||
h.app.GetServer().StopClientLogStream(sessionID)
|
||||
return false
|
||||
case entry, ok := <-logCh:
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
c.SSEvent("log", entry)
|
||||
return true
|
||||
case <-time.After(30 * time.Second):
|
||||
// 发送心跳
|
||||
c.SSEvent("heartbeat", gin.H{"ts": time.Now().UnixMilli()})
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user