181 lines
5.4 KiB
Go
181 lines
5.4 KiB
Go
package logging
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
"runtime"
|
|
"time"
|
|
)
|
|
|
|
// Logger creates a *slog.Logger wrap with a few more methods wrapped on top.
|
|
// It recreates a number of methods to allow replacing a *slog.Logger functionally.
|
|
// It also implements a number of methods to support formatted messages and
|
|
// tracing.
|
|
type Logger struct {
|
|
*slog.Logger
|
|
}
|
|
|
|
func New(h slog.Handler) *Logger {
|
|
return &Logger{
|
|
Logger: slog.New(h),
|
|
}
|
|
}
|
|
|
|
func From(l *slog.Logger) *Logger {
|
|
return &Logger{
|
|
Logger: l,
|
|
}
|
|
}
|
|
|
|
func (l *Logger) With(args ...any) *Logger {
|
|
return From(l.Logger.With(args...))
|
|
}
|
|
|
|
func (l *Logger) WithGroup(name string) *Logger {
|
|
return From(l.Logger.WithGroup(name))
|
|
}
|
|
|
|
func (l *Logger) Debugf(format string, args ...any) {
|
|
l.logContextf(context.Background(), slog.LevelDebug, format, args...)
|
|
}
|
|
|
|
func (l *Logger) DebugContextf(ctx context.Context, format string, args ...any) {
|
|
l.logContextf(ctx, slog.LevelDebug, format, args...)
|
|
}
|
|
|
|
func (l *Logger) DebugDeferf(format string, args ...any) func(func() (string, []any)) {
|
|
return l.logContextDeferf(context.Background(), slog.LevelDebug, format, args...)
|
|
}
|
|
|
|
func (l *Logger) DebugContextDeferf(ctx context.Context, format string, args ...any) func(func() (string, []any)) {
|
|
return l.logContextDeferf(ctx, slog.LevelDebug, format, args...)
|
|
}
|
|
|
|
func (l *Logger) DebugCallf(method string) func() {
|
|
return l.logContextCallf(context.Background(), slog.LevelDebug, method)
|
|
}
|
|
|
|
func (l *Logger) DebugContextCallf(ctx context.Context, method string) func() {
|
|
return l.logContextCallf(ctx, slog.LevelDebug, method)
|
|
}
|
|
|
|
func (l *Logger) Errorf(format string, args ...any) {
|
|
l.logContextf(context.Background(), slog.LevelError, format, args...)
|
|
}
|
|
|
|
func (l *Logger) ErrorContextf(ctx context.Context, format string, args ...any) {
|
|
l.logContextf(ctx, slog.LevelError, format, args...)
|
|
}
|
|
|
|
func (l *Logger) ErrorDeferf(format string, args ...any) func(func() (string, []any)) {
|
|
return l.logContextDeferf(context.Background(), slog.LevelError, format, args...)
|
|
}
|
|
|
|
func (l *Logger) ErrorContextDeferf(ctx context.Context, format string, args ...any) func(func() (string, []any)) {
|
|
return l.logContextDeferf(ctx, slog.LevelError, format, args...)
|
|
}
|
|
|
|
func (l *Logger) ErrorCallf(method string) func() {
|
|
return l.logContextCallf(context.Background(), slog.LevelError, method)
|
|
}
|
|
|
|
func (l *Logger) ErrorContextCallf(ctx context.Context, method string) func() {
|
|
return l.logContextCallf(ctx, slog.LevelError, method)
|
|
}
|
|
|
|
func (l *Logger) Infof(format string, args ...any) {
|
|
l.logContextf(context.Background(), slog.LevelInfo, format, args...)
|
|
}
|
|
|
|
func (l *Logger) InfoContextf(ctx context.Context, format string, args ...any) {
|
|
l.logContextf(ctx, slog.LevelInfo, format, args...)
|
|
}
|
|
|
|
func (l *Logger) InfoDeferf(format string, args ...any) func(func() (string, []any)) {
|
|
return l.logContextDeferf(context.Background(), slog.LevelInfo, format, args...)
|
|
}
|
|
|
|
func (l *Logger) InfoContextDeferf(ctx context.Context, format string, args ...any) func(func() (string, []any)) {
|
|
return l.logContextDeferf(ctx, slog.LevelInfo, format, args...)
|
|
}
|
|
|
|
func (l *Logger) InfoCallf(method string) func() {
|
|
return l.logContextCallf(context.Background(), slog.LevelInfo, method)
|
|
}
|
|
|
|
func (l *Logger) InfoContextCallf(ctx context.Context, method string) func() {
|
|
return l.logContextCallf(ctx, slog.LevelInfo, method)
|
|
}
|
|
|
|
func (l *Logger) Warnf(format string, args ...any) {
|
|
l.logContextf(context.Background(), slog.LevelWarn, format, args...)
|
|
}
|
|
|
|
func (l *Logger) WarnContextf(ctx context.Context, format string, args ...any) {
|
|
l.logContextf(ctx, slog.LevelWarn, format, args...)
|
|
}
|
|
|
|
func (l *Logger) WarnDeferf(format string, args ...any) func(func() (string, []any)) {
|
|
return l.logContextDeferf(context.Background(), slog.LevelWarn, format, args...)
|
|
}
|
|
|
|
func (l *Logger) WarnContextDeferf(ctx context.Context, format string, args ...any) func(func() (string, []any)) {
|
|
return l.logContextDeferf(ctx, slog.LevelWarn, format, args...)
|
|
}
|
|
|
|
func (l *Logger) WarnCallf(method string) func() {
|
|
return l.logContextCallf(context.Background(), slog.LevelWarn, method)
|
|
}
|
|
|
|
func (l *Logger) WarnContextCallf(ctx context.Context, method string) func() {
|
|
return l.logContextCallf(ctx, slog.LevelWarn, method)
|
|
}
|
|
|
|
func (l *Logger) logContextf(ctx context.Context, lvl slog.Level, format string, args ...any) {
|
|
if !l.Enabled(ctx, slog.LevelInfo) {
|
|
return
|
|
}
|
|
|
|
var pcs [1]uintptr
|
|
runtime.Callers(3, pcs[:]) // skip [Callers, Infof]
|
|
|
|
_ = l.Handler().Handle(
|
|
ctx,
|
|
slog.NewRecord(time.Now(), lvl, fmt.Sprintf(format, args...), pcs[0]),
|
|
)
|
|
}
|
|
|
|
func (l *Logger) logContextCallf(ctx context.Context, lvl slog.Level, method string) func() {
|
|
fn := l.With("method", method).logContextDeferf(ctx, lvl, "%s called", method)
|
|
return func() {
|
|
fn(func() (string, []any) {
|
|
return "%s returned", []any{method}
|
|
})
|
|
}
|
|
}
|
|
|
|
func (l *Logger) logContextDeferf(ctx context.Context, lvl slog.Level, format string, args ...any) func(func() (msg string, args []any)) {
|
|
if !l.Enabled(ctx, slog.LevelInfo) {
|
|
return func(func() (string, []any)) {
|
|
}
|
|
}
|
|
|
|
var pcs [1]uintptr
|
|
runtime.Callers(3, pcs[:]) // skip [Callers, Infof]
|
|
pc := pcs[0]
|
|
|
|
_ = l.Handler().Handle(ctx, slog.NewRecord(time.Now(), lvl, fmt.Sprintf(format, args...), pc))
|
|
return func(deferred func() (newFormat string, moreArgs []any)) {
|
|
if !l.Enabled(ctx, slog.LevelInfo) {
|
|
return
|
|
}
|
|
|
|
if deferred != nil {
|
|
format, args = deferred()
|
|
}
|
|
|
|
_ = l.Handler().Handle(ctx, slog.NewRecord(time.Now(), lvl, fmt.Sprintf(format, args...), pc))
|
|
}
|
|
}
|