feat(logger): WithSource/Scoped 日志来源标注;AGENTS 追加日志标来源+客户端API契约红线
This commit is contained in:
1 parent
be67d74822
commit
10c0069fa7
3 files changed
+48
No files matched your search
@@ -68,3 +68,24 @@ func ParseLevel(s string) slog.Level {
|
||||
return slog.LevelInfo
|
||||
}
|
||||
}
|
||||
|
||||
// WithSource returns a child logger that tags every emitted record with a
|
||||
// source so issues can be traced back to the owning module/sub-feature. source
|
||||
// is conventionally "module/subfeature", e.g. "runtime/loop" or
|
||||
// "channel/adapter". Every module that logs should call this once on its base
|
||||
// logger so all records carry provenance.
|
||||
func WithSource(l *slog.Logger, source string) *slog.Logger {
|
||||
if l == nil {
|
||||
return nil
|
||||
}
|
||||
return l.With(slog.String("source", source))
|
||||
}
|
||||
|
||||
// Scoped returns a child logger tagged with module and subfeature, for finer
|
||||
// provenance when a module contains several subsystems.
|
||||
func Scoped(l *slog.Logger, module, subfeature string) *slog.Logger {
|
||||
if l == nil {
|
||||
return nil
|
||||
}
|
||||
return l.With(slog.String("module", module), slog.String("sub", subfeature))
|
||||
}
|
||||
@@ -91,3 +91,28 @@ func TestNew_DefaultsToErrAndText(t *testing.T) {
|
||||
t.Fatal("New(Options{}) returned nil logger")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithSource_TagsRecords(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var buf bytes.Buffer
|
||||
base := New(Options{Level: "debug", Format: "json", Out: &buf})
|
||||
log := WithSource(base, "runtime/loop")
|
||||
log.Info("hello")
|
||||
if !strings.Contains(buf.String(), `"source":"runtime/loop"`) {
|
||||
t.Fatalf("missing source field, got %q", buf.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestScoped_TagsModuleAndSub(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var buf bytes.Buffer
|
||||
base := New(Options{Level: "debug", Format: "json", Out: &buf})
|
||||
log := Scoped(base, "channel", "adapter")
|
||||
log.Info("hello")
|
||||
got := buf.String()
|
||||
if !strings.Contains(got, `"module":"channel"`) || !strings.Contains(got, `"sub":"adapter"`) {
|
||||
t.Fatalf("missing module/sub fields, got %q", got)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user