caller: support for caller lib
This commit is contained in:
parent
d02962dc65
commit
aec979048e
61
caller/caller.go
Normal file
61
caller/caller.go
Normal file
|
@ -0,0 +1,61 @@
|
|||
package caller
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Caller struct {
|
||||
PC uintptr
|
||||
Frame runtime.Frame
|
||||
}
|
||||
|
||||
func (ca Caller) File() string {
|
||||
return ca.Frame.File
|
||||
}
|
||||
|
||||
func (ca Caller) Line() int {
|
||||
return ca.Frame.Line
|
||||
}
|
||||
|
||||
func (ca Caller) Function() string {
|
||||
return ca.Frame.Function
|
||||
}
|
||||
|
||||
func (ca Caller) ShortFunction() string {
|
||||
split := strings.Split(ca.Frame.Function, string(os.PathSeparator))
|
||||
return split[len(split)-1]
|
||||
}
|
||||
|
||||
func (ca Caller) LogValue() slog.Value {
|
||||
if ca.PC == 0 {
|
||||
return slog.AnyValue(nil)
|
||||
}
|
||||
|
||||
return slog.GroupValue(
|
||||
slog.String("file", ca.File()),
|
||||
slog.Int("line", ca.Line()),
|
||||
slog.String("function", ca.ShortFunction()),
|
||||
)
|
||||
}
|
||||
|
||||
func New(skip int) Caller {
|
||||
var c Caller
|
||||
pcs := make([]uintptr, 1)
|
||||
n := runtime.Callers(skip, pcs)
|
||||
if n == 0 {
|
||||
return c
|
||||
}
|
||||
c.PC = pcs[0]
|
||||
c.Frame, _ = runtime.CallersFrames(pcs).Next()
|
||||
return c
|
||||
}
|
||||
|
||||
func From(pc uintptr) Caller {
|
||||
var c Caller
|
||||
c.PC = pc
|
||||
c.Frame, _ = runtime.CallersFrames([]uintptr{pc}).Next()
|
||||
return c
|
||||
}
|
39
log/log.go
39
log/log.go
|
@ -6,13 +6,13 @@ import (
|
|||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
"github.com/mattn/go-colorable"
|
||||
"github.com/mattn/go-isatty"
|
||||
"github.com/tigorlazuardi/redmage/caller"
|
||||
"github.com/tigorlazuardi/redmage/config"
|
||||
)
|
||||
|
||||
|
@ -47,7 +47,7 @@ func NewHandler(cfg *config.Config) slog.Handler {
|
|||
type Entry struct {
|
||||
ctx context.Context
|
||||
handler slog.Handler
|
||||
caller uintptr
|
||||
caller caller.Caller
|
||||
time time.Time
|
||||
}
|
||||
|
||||
|
@ -60,13 +60,13 @@ func Log(ctx context.Context) *Entry {
|
|||
return &Entry{ctx: ctx, handler: h, time: time.Now()}
|
||||
}
|
||||
|
||||
func (entry *Entry) Caller(pc uintptr) *Entry {
|
||||
entry.caller = pc
|
||||
func (entry *Entry) Caller(caller caller.Caller) *Entry {
|
||||
entry.caller = caller
|
||||
return entry
|
||||
}
|
||||
|
||||
func (entry *Entry) Info(message string, fields ...any) {
|
||||
record := slog.NewRecord(entry.time, slog.LevelInfo, message, entry.getCaller())
|
||||
record := slog.NewRecord(entry.time, slog.LevelInfo, message, entry.getCaller().PC)
|
||||
record.AddAttrs(entry.getExtra()...)
|
||||
record.AddAttrs(slog.Group("context", fields...))
|
||||
_ = entry.handler.Handle(entry.ctx, record)
|
||||
|
@ -74,13 +74,13 @@ func (entry *Entry) Info(message string, fields ...any) {
|
|||
|
||||
func (entry *Entry) Infof(format string, args ...any) {
|
||||
message := fmt.Sprintf(format, args...)
|
||||
record := slog.NewRecord(entry.time, slog.LevelInfo, message, entry.getCaller())
|
||||
record := slog.NewRecord(entry.time, slog.LevelInfo, message, entry.getCaller().PC)
|
||||
record.AddAttrs(entry.getExtra()...)
|
||||
_ = entry.handler.Handle(entry.ctx, record)
|
||||
}
|
||||
|
||||
func (entry *Entry) Error(message string, fields ...any) {
|
||||
record := slog.NewRecord(entry.time, slog.LevelError, message, entry.getCaller())
|
||||
record := slog.NewRecord(entry.time, slog.LevelError, message, entry.getCaller().PC)
|
||||
record.AddAttrs(entry.getExtra()...)
|
||||
record.AddAttrs(slog.Group("context", fields...))
|
||||
_ = entry.handler.Handle(entry.ctx, record)
|
||||
|
@ -88,13 +88,13 @@ func (entry *Entry) Error(message string, fields ...any) {
|
|||
|
||||
func (entry *Entry) Errorf(format string, args ...any) {
|
||||
message := fmt.Sprintf(format, args...)
|
||||
record := slog.NewRecord(entry.time, slog.LevelError, message, entry.getCaller())
|
||||
record := slog.NewRecord(entry.time, slog.LevelError, message, entry.getCaller().PC)
|
||||
record.AddAttrs(entry.getExtra()...)
|
||||
_ = entry.handler.Handle(entry.ctx, record)
|
||||
}
|
||||
|
||||
func (entry *Entry) Debug(message string, fields ...any) {
|
||||
record := slog.NewRecord(entry.time, slog.LevelDebug, message, entry.getCaller())
|
||||
record := slog.NewRecord(entry.time, slog.LevelDebug, message, entry.getCaller().PC)
|
||||
record.AddAttrs(entry.getExtra()...)
|
||||
record.AddAttrs(slog.Group("context", fields...))
|
||||
_ = entry.handler.Handle(entry.ctx, record)
|
||||
|
@ -102,13 +102,13 @@ func (entry *Entry) Debug(message string, fields ...any) {
|
|||
|
||||
func (entry *Entry) Debugf(format string, args ...any) {
|
||||
message := fmt.Sprintf(format, args...)
|
||||
record := slog.NewRecord(entry.time, slog.LevelDebug, message, entry.getCaller())
|
||||
record := slog.NewRecord(entry.time, slog.LevelDebug, message, entry.getCaller().PC)
|
||||
record.AddAttrs(entry.getExtra()...)
|
||||
_ = entry.handler.Handle(entry.ctx, record)
|
||||
}
|
||||
|
||||
func (entry *Entry) Warn(message string, fields ...any) {
|
||||
record := slog.NewRecord(entry.time, slog.LevelWarn, message, entry.getCaller())
|
||||
record := slog.NewRecord(entry.time, slog.LevelWarn, message, entry.getCaller().PC)
|
||||
record.AddAttrs(entry.getExtra()...)
|
||||
record.AddAttrs(slog.Group("context", fields...))
|
||||
_ = entry.handler.Handle(entry.ctx, record)
|
||||
|
@ -116,25 +116,16 @@ func (entry *Entry) Warn(message string, fields ...any) {
|
|||
|
||||
func (entry *Entry) Warnf(format string, args ...any) {
|
||||
message := fmt.Sprintf(format, args...)
|
||||
record := slog.NewRecord(entry.time, slog.LevelWarn, message, entry.getCaller())
|
||||
record := slog.NewRecord(entry.time, slog.LevelWarn, message, entry.getCaller().PC)
|
||||
record.AddAttrs(entry.getExtra()...)
|
||||
_ = entry.handler.Handle(entry.ctx, record)
|
||||
}
|
||||
|
||||
func (entry *Entry) getCaller() uintptr {
|
||||
if entry.caller != 0 {
|
||||
func (entry *Entry) getCaller() caller.Caller {
|
||||
if entry.caller.PC != 0 {
|
||||
return entry.caller
|
||||
}
|
||||
return GetCaller(4)
|
||||
}
|
||||
|
||||
func GetCaller(skip int) uintptr {
|
||||
pc := make([]uintptr, 1)
|
||||
n := runtime.Callers(skip, pc)
|
||||
if n == 0 {
|
||||
return 0
|
||||
}
|
||||
return pc[0]
|
||||
return caller.New(4)
|
||||
}
|
||||
|
||||
func (entry *Entry) getExtra() []slog.Attr {
|
||||
|
|
|
@ -7,11 +7,11 @@ import (
|
|||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/tigorlazuardi/redmage/caller"
|
||||
)
|
||||
|
||||
type PrettyHandler struct {
|
||||
|
@ -89,7 +89,7 @@ func (pr *PrettyHandler) Handle(ctx context.Context, record slog.Record) error {
|
|||
defer putBuffer(jsonBuf)
|
||||
|
||||
if record.PC != 0 && pr.opts.AddSource {
|
||||
frame := getFrame(record.PC)
|
||||
frame := caller.From(record.PC).Frame
|
||||
levelColor.Fprint(buf, frame.File)
|
||||
levelColor.Fprint(buf, ":")
|
||||
levelColor.Fprint(buf, frame.Line)
|
||||
|
@ -118,7 +118,7 @@ func (pr *PrettyHandler) Handle(ctx context.Context, record slog.Record) error {
|
|||
_ = serializer.Handle(ctx, record)
|
||||
if jsonBuf.Len() > 3 { // Ignore empty json like "{}\n"
|
||||
_ = json.Indent(buf, jsonBuf.Bytes(), "", " ")
|
||||
// json indent includes new line, no need to add extra text.
|
||||
// json indent includes new line, no need to add extra new line.
|
||||
} else {
|
||||
buf.WriteByte('\n')
|
||||
}
|
||||
|
@ -148,12 +148,6 @@ func (pr *PrettyHandler) createSerializer(w io.Writer) slog.Handler {
|
|||
return jsonHandler
|
||||
}
|
||||
|
||||
func getFrame(pc uintptr) runtime.Frame {
|
||||
frames := runtime.CallersFrames([]uintptr{pc})
|
||||
frame, _ := frames.Next()
|
||||
return frame
|
||||
}
|
||||
|
||||
func (pr *PrettyHandler) clone() *PrettyHandler {
|
||||
return &PrettyHandler{
|
||||
opts: pr.opts,
|
||||
|
|
Loading…
Reference in a new issue