26a43708b7
Capture layer: LogBuffer always exists; logger = MultiWriter(LevelFilterWriter (stdout, logging.level), ring) so DEBUG detail exists remotely without a config flip while docker logs keep respecting the level. New internal/logx leveled helpers. Report ACK gains controller_log_requested (additive); next report ships controller_log_tail (128KB, consume-once, app-tail wire byte-compatible). Debug page: Vezérlő|Ügynök tabs; agent tab proxies agent /debug/logs with the pre-0.83 notice on typed 404. Sweep: netstorage_job phases, netprobe, handler validation refusals + orphan WARN, SupportsWithSource gate line, agentapi per-call DEBUG, migrate phase lines, tier2/offbox unswallowed persists. Red-proofs: filter-disabled, drain-removed, dropped-phase-line all FAIL. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
38 lines
1.6 KiB
Go
38 lines
1.6 KiB
Go
// Package logx is the leveled log helper of the v0.116.0 observability pass. It
|
|
// prefixes the standard [LEVEL] tag and writes through log.Logger.Output so the
|
|
// Lshortfile source (debug mode) attributes to the CALLER, not this file.
|
|
//
|
|
// Routing is the WRITER's job, not this package's: main.go builds the logger as
|
|
// MultiWriter(LevelFilterWriter(stdout, logging.level), LogBuffer) — so a
|
|
// logx.Debugf line ALWAYS reaches the debug ring (remote diagnostics) while
|
|
// stdout keeps respecting logging.level. Legacy `isDebug()`-gated Printf call
|
|
// sites are left as-is (they gate emission entirely); ALL NEW leveled lines use
|
|
// these helpers. Conventions (levels, English, no secrets):
|
|
// felhom.eu/documentation/runbooks/logging-conventions.md.
|
|
package logx
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
)
|
|
|
|
// Debugf logs flow detail (phase steps, per-call traces, parsed values).
|
|
func Debugf(l *log.Logger, format string, args ...any) { output(l, "DEBUG", format, args...) }
|
|
|
|
// Infof logs state changes and operations with durations ("X done in Yms").
|
|
func Infof(l *log.Logger, format string, args ...any) { output(l, "INFO", format, args...) }
|
|
|
|
// Warnf logs degraded-but-continuing conditions.
|
|
func Warnf(l *log.Logger, format string, args ...any) { output(l, "WARN", format, args...) }
|
|
|
|
// Errorf logs a failed operation — always include the underlying error.
|
|
func Errorf(l *log.Logger, format string, args ...any) { output(l, "ERROR", format, args...) }
|
|
|
|
func output(l *log.Logger, tag, format string, args ...any) {
|
|
if l == nil {
|
|
return
|
|
}
|
|
// calldepth 3: Output ← output ← Debugf/… ← the caller we want attributed.
|
|
_ = l.Output(3, "["+tag+"] "+fmt.Sprintf(format, args...))
|
|
}
|