fix: bound management terminal logs

This commit is contained in:
npc0-hue
2026-08-07 10:43:13 +08:00
parent 4b0233cf6f
commit 87e903998e
10 changed files with 229 additions and 28 deletions
+40 -20
View File
@@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"net/http"
"sort"
"strconv"
"strings"
"time"
@@ -15,7 +16,7 @@ import (
const (
defaultLogEventHistoryLimit = 100
maxLogEventHistoryLimit = 500
maxLogEventHistoryLimit = 10000
logEventHeartbeatInterval = 15 * time.Second
)
@@ -25,7 +26,7 @@ const (
// @Tags logs
// @Produce text/event-stream
// @Param id path string true "Server instance ID"
// @Param historyLimit query int false "Recent entries per stream to replay before live events"
// @Param historyLimit query int false "Total recent entries to replay across this server's streams"
// @Success 200 {string} string "event-stream"
// @Failure 401 {object} dto.ErrorResponse
// @Failure 403 {object} dto.ErrorResponse
@@ -61,10 +62,16 @@ func (h *coreHandlers) serverLogEvents(w http.ResponseWriter, r *http.Request) {
if err := writeSSEJSON(w, "stream", "", dto.LogStreamFromDomain(stream)); err != nil {
return
}
if historyLimit > 0 {
if err := h.writeLogEventHistory(w, stream, historyLimit); err != nil {
_ = writeSSEJSON(w, "error", "", map[string]string{"message": err.Error()})
flusher.Flush()
}
if historyLimit > 0 {
history, err := h.loadLogEventHistory(streams, historyLimit)
if err != nil {
_ = writeSSEJSON(w, "error", "", map[string]string{"message": err.Error()})
flusher.Flush()
return
}
for _, event := range history {
if err := writeSSEJSON(w, "log", logEventID(event), dto.LogStreamEventFromDomain(event)); err != nil {
return
}
}
@@ -127,22 +134,35 @@ func (h *coreHandlers) openLogEventSubscription(r *http.Request) (domain.ServerI
return instance, streams, subscription, err
}
func (h *coreHandlers) writeLogEventHistory(w http.ResponseWriter, stream domain.LogStream, limit int) error {
afterSeq := uint64(0)
if stream.LatestSeq > uint64(limit) {
afterSeq = stream.LatestSeq - uint64(limit)
}
cursor, err := h.core.QueryLogStream(domain.LogStreamCursorQuery{LogStreamID: stream.ID, AfterSeq: afterSeq, Limit: limit})
if err != nil {
return err
}
for _, entry := range cursor.Entries {
event := domain.LogStreamEvent{ServerInstanceID: stream.ServerInstanceID, Stream: stream, Entry: entry, LatestSeq: cursor.LatestSeq}
if err := writeSSEJSON(w, "log", logEventID(event), dto.LogStreamEventFromDomain(event)); err != nil {
return err
func (h *coreHandlers) loadLogEventHistory(streams []domain.LogStream, limit int) ([]domain.LogStreamEvent, error) {
history := make([]domain.LogStreamEvent, 0, limit)
for _, stream := range streams {
afterSeq := uint64(0)
if stream.LatestSeq > uint64(limit) {
afterSeq = stream.LatestSeq - uint64(limit)
}
cursor, err := h.core.QueryLogStream(domain.LogStreamCursorQuery{LogStreamID: stream.ID, AfterSeq: afterSeq, Limit: limit})
if err != nil {
return nil, err
}
for _, entry := range cursor.Entries {
history = append(history, domain.LogStreamEvent{ServerInstanceID: stream.ServerInstanceID, Stream: stream, Entry: entry, LatestSeq: cursor.LatestSeq})
}
}
return nil
sort.SliceStable(history, func(i, j int) bool {
left, right := history[i], history[j]
if !left.Entry.Timestamp.Equal(right.Entry.Timestamp) {
return left.Entry.Timestamp.Before(right.Entry.Timestamp)
}
if left.Entry.Seq != right.Entry.Seq {
return left.Entry.Seq < right.Entry.Seq
}
return left.Stream.ID < right.Stream.ID
})
if len(history) > limit {
history = history[len(history)-limit:]
}
return history, nil
}
func parseLogEventHistoryLimit(value string) int {