mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2025-09-23 03:43:36 +08:00
Admin UI: Fetch task logs (#7114)
* show task details * loading tasks * task UI works * generic rendering * rendering the export link * removing placementConflicts from task parameters * remove TaskSourceLocation * remove "Server ID" column * rendering balance task source * sources and targets * fix ec task generation * move info * render timeline * simplified worker id * simplify * read task logs from worker * isValidTaskID * address comments * Update weed/worker/tasks/balance/execution.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update weed/worker/tasks/erasure_coding/ec_task.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update weed/worker/tasks/task_log_handler.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix shard ids * plan distributing shard id * rendering planned shards in task details * remove Conflicts * worker logs correctly * pass in dc and rack * task logging * Update weed/admin/maintenance/maintenance_queue.go Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * display log details * logs have fields now * sort field keys * fix link * fix collection filtering * avoid hard coded ec shard counts --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
85
weed/worker/log_adapter.go
Normal file
85
weed/worker/log_adapter.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package worker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
wtasks "github.com/seaweedfs/seaweedfs/weed/worker/tasks"
|
||||
wtypes "github.com/seaweedfs/seaweedfs/weed/worker/types"
|
||||
)
|
||||
|
||||
// taskLoggerAdapter adapts a tasks.TaskLogger to the types.Logger interface used by tasks
|
||||
// so that structured WithFields logs from task implementations are captured into file logs.
|
||||
type taskLoggerAdapter struct {
|
||||
base wtasks.TaskLogger
|
||||
fields map[string]interface{}
|
||||
}
|
||||
|
||||
func newTaskLoggerAdapter(base wtasks.TaskLogger) *taskLoggerAdapter {
|
||||
return &taskLoggerAdapter{base: base}
|
||||
}
|
||||
|
||||
// WithFields returns a new adapter instance that includes the provided fields.
|
||||
func (a *taskLoggerAdapter) WithFields(fields map[string]interface{}) wtypes.Logger {
|
||||
// copy fields to avoid mutation by caller
|
||||
copied := make(map[string]interface{}, len(fields))
|
||||
for k, v := range fields {
|
||||
copied[k] = v
|
||||
}
|
||||
return &taskLoggerAdapter{base: a.base, fields: copied}
|
||||
}
|
||||
|
||||
// Info logs an info message, including any structured fields if present.
|
||||
func (a *taskLoggerAdapter) Info(msg string, args ...interface{}) {
|
||||
if a.base == nil {
|
||||
return
|
||||
}
|
||||
if len(a.fields) > 0 {
|
||||
a.base.LogWithFields("INFO", fmt.Sprintf(msg, args...), toStringMap(a.fields))
|
||||
return
|
||||
}
|
||||
a.base.Info(msg, args...)
|
||||
}
|
||||
|
||||
func (a *taskLoggerAdapter) Warning(msg string, args ...interface{}) {
|
||||
if a.base == nil {
|
||||
return
|
||||
}
|
||||
if len(a.fields) > 0 {
|
||||
a.base.LogWithFields("WARNING", fmt.Sprintf(msg, args...), toStringMap(a.fields))
|
||||
return
|
||||
}
|
||||
a.base.Warning(msg, args...)
|
||||
}
|
||||
|
||||
func (a *taskLoggerAdapter) Error(msg string, args ...interface{}) {
|
||||
if a.base == nil {
|
||||
return
|
||||
}
|
||||
if len(a.fields) > 0 {
|
||||
a.base.LogWithFields("ERROR", fmt.Sprintf(msg, args...), toStringMap(a.fields))
|
||||
return
|
||||
}
|
||||
a.base.Error(msg, args...)
|
||||
}
|
||||
|
||||
func (a *taskLoggerAdapter) Debug(msg string, args ...interface{}) {
|
||||
if a.base == nil {
|
||||
return
|
||||
}
|
||||
if len(a.fields) > 0 {
|
||||
a.base.LogWithFields("DEBUG", fmt.Sprintf(msg, args...), toStringMap(a.fields))
|
||||
return
|
||||
}
|
||||
a.base.Debug(msg, args...)
|
||||
}
|
||||
|
||||
// toStringMap converts map[string]interface{} to map[string]interface{} where values are printable.
|
||||
// The underlying tasks.TaskLogger handles arbitrary JSON values, but our gRPC conversion later
|
||||
// expects strings; we rely on existing conversion there. Here we keep interface{} to preserve detail.
|
||||
func toStringMap(in map[string]interface{}) map[string]interface{} {
|
||||
out := make(map[string]interface{}, len(in))
|
||||
for k, v := range in {
|
||||
out[k] = v
|
||||
}
|
||||
return out
|
||||
}
|
Reference in New Issue
Block a user