From a7228658b6087afed6f212eef7a29a92d0c1582c Mon Sep 17 00:00:00 2001 From: Dominik Menke Date: Mon, 29 Jan 2024 20:34:46 +0100 Subject: [PATCH] add documentation --- xlog/attrs.go | 9 +++++++++ xlog/options.go | 25 ++++++++++++++++--------- xlog/xlog.go | 15 +++++++++------ 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/xlog/attrs.go b/xlog/attrs.go index 9aaef8e..ca5bbce 100644 --- a/xlog/attrs.go +++ b/xlog/attrs.go @@ -2,6 +2,8 @@ package xlog import "log/slog" +// Convenience slog.Attr generators. Allows cluttering imports (no need +// to import both log/slog and xlog). var ( String = slog.String Int64 = slog.Int64 @@ -15,14 +17,21 @@ var ( Any = slog.Any ) +// Key used to denote error values. const ErrorKey = "error" +// ErrorValue holds an error value. type ErrorValue struct{ error } +// Value extracts the error message. func (err ErrorValue) Value() slog.Value { return slog.StringValue(err.Error()) } +// Error constructs a first-class error log attribute. +// +// Not to be confused with (xlog.Logger).Error() or (log/slog).Error(), +// which produce an error-level log message. func Error(err error) slog.Attr { return slog.Any(ErrorKey, ErrorValue{err}) } diff --git a/xlog/options.go b/xlog/options.go index 8dc8c3e..94a691d 100644 --- a/xlog/options.go +++ b/xlog/options.go @@ -1,7 +1,6 @@ package xlog import ( - "bytes" "io" "log/slog" "time" @@ -9,6 +8,8 @@ import ( "github.com/digineo/texd/internal" ) +// An Option represents a functional configuration option. These are +// used to configure new logger instances. type Option func(*options) error type options struct { @@ -19,6 +20,7 @@ type options struct { handlerOpts *slog.HandlerOptions } +// Leveled sets the log level. func Leveled(l slog.Level) Option { return func(o *options) error { o.handlerOpts.Level = l @@ -26,6 +28,8 @@ func Leveled(l slog.Level) Option { } } +// LeveledString interprets s (see ParseLevel) and sets the log level. +// If s is unknown, the error will be revealed with New(). func LeveledString(s string) Option { return func(o *options) error { l, err := ParseLevel(s) @@ -37,6 +41,7 @@ func LeveledString(s string) Option { } } +// WriteTo sets the output. func WriteTo(w io.Writer) Option { return func(o *options) error { o.output = w @@ -44,14 +49,7 @@ func WriteTo(w io.Writer) Option { } } -func CaptureOutput() (Option, *bytes.Buffer) { - var b bytes.Buffer - return func(o *options) error { - o.output = &b - return nil - }, &b -} - +// MockClock sets up a canned timestamp. func MockClock(t time.Time) Option { return func(o *options) error { o.clock = internal.MockClock(t) @@ -59,6 +57,7 @@ func MockClock(t time.Time) Option { } } +// WithSource enables source code positions in log messages. func WithSource() Option { return func(o *options) error { o.handlerOpts.AddSource = true @@ -66,6 +65,8 @@ func WithSource() Option { } } +// WithAttrReplacer configures an attribute replacer. +// See (slog.HandlerOptions).ReplaceAtrr for details. func WithAttrReplacer(f func(groups []string, a slog.Attr) slog.Attr) Option { return func(o *options) error { o.handlerOpts.ReplaceAttr = f @@ -73,6 +74,8 @@ func WithAttrReplacer(f func(groups []string, a slog.Attr) slog.Attr) Option { } } +// AsJSON configures a JSONHandler, i.e. log messages will be printed +// as JSON string. func AsJSON() Option { return func(o *options) error { o.buildHandler = func(o *options) slog.Handler { @@ -82,6 +85,8 @@ func AsJSON() Option { } } +// AsText configures a TextHandler, i.e. the message output is a +// simple list of key=value pairs with minimal quoting. func AsText() Option { return func(o *options) error { o.buildHandler = func(o *options) slog.Handler { @@ -91,6 +96,8 @@ func AsText() Option { } } +// Discard mutes the logger. See also NewDiscard() for a simpler +// constructor. func Discard() Option { return func(o *options) error { o.discard = true diff --git a/xlog/xlog.go b/xlog/xlog.go index 528d1a9..8824d33 100644 --- a/xlog/xlog.go +++ b/xlog/xlog.go @@ -7,6 +7,7 @@ import ( "log/slog" "os" "runtime" + "strings" "time" ) @@ -110,16 +111,18 @@ func (log *logger) With(a ...slog.Attr) Logger { } } +// ParseLevel tries to convert a (case-insensitive) string into a +// slog.Level. Accepted values are "debug", "info", "warn", "warning", +// "error" and "fatal". Other input will result in err not being nil. func ParseLevel(s string) (l slog.Level, err error) { - switch s { - case "debug", "DEBUG": + switch strings.ToLower(s) { + case "debug": l = slog.LevelDebug - case "info", "INFO", "": // make the zero value useful + case "info", "": // make the zero value useful l = slog.LevelInfo - case "warn", "WARN": + case "warn", "warning": l = slog.LevelWarn - case "error", "ERROR", - "fatal", "FATAL": + case "error", "fatal": l = slog.LevelError default: err = fmt.Errorf("unknown log level: %q", s)