Files
kra-new/pkg/task/output.go
T

64 lines
1.4 KiB
Go

package task
import (
"context"
"fmt"
"strings"
"sync"
"unicode/utf8"
)
type outputKey struct{}
// Output collects bounded execution details without changing the method contract.
// A timed-out method may still write, so snapshots and writes must be synchronized.
type Output struct {
mu sync.Mutex
text string
truncated bool
}
func WithOutput(ctx context.Context) (context.Context, *Output) {
output := &Output{}
return context.WithValue(ctx, outputKey{}, output), output
}
// Logf records operational counts and progress. Do not include credentials or
// whole request/response bodies. Outside a task execution it is a no-op.
func Logf(ctx context.Context, format string, args ...any) {
if ctx == nil {
return
}
output, _ := ctx.Value(outputKey{}).(*Output)
if output == nil {
return
}
line := fmt.Sprintf(format, args...)
output.mu.Lock()
defer output.mu.Unlock()
const limit = 3000 // Reserve space for the executor's final status.
if output.truncated {
return
}
remaining := limit - len(output.text)
if len(line)+1 > remaining {
cut := max(0, remaining-1)
for cut > 0 && !utf8.RuneStart(line[cut]) {
cut--
}
line = line[:cut]
output.truncated = true
}
output.text += line + "\n"
}
func (output *Output) String() string {
output.mu.Lock()
defer output.mu.Unlock()
text := strings.TrimSpace(output.text)
if output.truncated {
text += "\n...(过程详情已截断)"
}
return text
}