diff --git a/internal/models/deployment.go b/internal/models/deployment.go index 492ba82..73a9feb 100644 --- a/internal/models/deployment.go +++ b/internal/models/deployment.go @@ -5,6 +5,7 @@ import ( "database/sql" "errors" "fmt" + "strings" "time" "git.eeqj.de/sneak/upaas/internal/database" @@ -76,7 +77,11 @@ func (d *Deployment) Reload(ctx context.Context) error { return d.scan(row) } +// maxLogSize is the maximum size of deployment logs stored in the database (1MB). +const maxLogSize = 1 << 20 + // AppendLog appends a log line to the deployment logs. +// If the total log size exceeds maxLogSize, the oldest lines are truncated. func (d *Deployment) AppendLog(ctx context.Context, line string) error { var currentLogs string @@ -84,7 +89,22 @@ func (d *Deployment) AppendLog(ctx context.Context, line string) error { currentLogs = d.Logs.String } - d.Logs = sql.NullString{String: currentLogs + line + "\n", Valid: true} + newLogs := currentLogs + line + "\n" + + if len(newLogs) > maxLogSize { + // Keep the most recent logs that fit within the limit. + // Find a newline after the truncation point to avoid partial lines. + truncateAt := len(newLogs) - maxLogSize + idx := strings.Index(newLogs[truncateAt:], "\n") + + if idx >= 0 { + newLogs = "[earlier logs truncated]\n" + newLogs[truncateAt+idx+1:] + } else { + newLogs = "[earlier logs truncated]\n" + newLogs[truncateAt:] + } + } + + d.Logs = sql.NullString{String: newLogs, Valid: true} return d.Save(ctx) }