74 lines
2.0 KiB
Go
74 lines
2.0 KiB
Go
package logx
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"log/slog"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.yuntuo.hk/k2safe/go-omni/internal/configdiag"
|
|
)
|
|
|
|
// Validate checks configuration without opening files or creating resources.
|
|
func (c Config) Validate() error { _, err := c.validate(); return err }
|
|
func (c Config) validate() (*time.Location, error) {
|
|
c = normalizeConfig(c)
|
|
if _, err := parseLevel(c.Level); err != nil {
|
|
return nil, configdiag.New("level", "must be debug, info, warn, warning or error")
|
|
}
|
|
if c.Format != "json" && c.Format != "text" {
|
|
return nil, configdiag.New("format", "must be json or text")
|
|
}
|
|
switch c.Output {
|
|
case "stdout", "stderr", "discard", "none":
|
|
default:
|
|
return nil, configdiag.New("output", "must be stdout, stderr, discard or none")
|
|
}
|
|
if err := c.Rotation.validate(c); err != nil {
|
|
return nil, err
|
|
}
|
|
return logLocation(c.TimeZone)
|
|
}
|
|
|
|
type loggerContextKey struct{}
|
|
|
|
// WithLogger borrows a logger for a call tree; it does not alter the global
|
|
// default and does not transfer ownership. nil preserves the existing context.
|
|
func WithLogger(ctx context.Context, logger *Logger) context.Context {
|
|
ctx = normalizeContext(ctx)
|
|
if logger == nil {
|
|
return ctx
|
|
}
|
|
return context.WithValue(ctx, loggerContextKey{}, logger)
|
|
}
|
|
|
|
// FromContext returns a call-scoped logger, falling back to package logging.
|
|
func FromContext(ctx context.Context) *Logger {
|
|
if ctx != nil {
|
|
if l, ok := ctx.Value(loggerContextKey{}).(*Logger); ok && l != nil {
|
|
return l
|
|
}
|
|
}
|
|
return defaultLogger.Load()
|
|
}
|
|
|
|
// Standard adapts this instance to the standard logger (for http.Server etc).
|
|
// It borrows the writer and never closes it. Each Print call becomes one event.
|
|
func (l *Logger) Standard(level slog.Level) *log.Logger {
|
|
if l == nil {
|
|
l = defaultLogger.Load()
|
|
}
|
|
return log.New(standardWriter{logger: l, level: level}, "", 0)
|
|
}
|
|
|
|
type standardWriter struct {
|
|
logger *Logger
|
|
level slog.Level
|
|
}
|
|
|
|
func (w standardWriter) Write(p []byte) (int, error) {
|
|
w.logger.logger.Log(context.Background(), w.level, strings.TrimRight(string(p), "\r\n"))
|
|
return len(p), nil
|
|
}
|