internal logging library
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
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))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user