You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
45 lines
1013 B
45 lines
1013 B
package log
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"path/filepath"
|
|
"runtime"
|
|
|
|
"gitoa.ru/go-4devs/log/entry"
|
|
"gitoa.ru/go-4devs/log/field"
|
|
)
|
|
|
|
func WithSource(depth int) Middleware {
|
|
const offset = 3
|
|
|
|
return func(ctx context.Context, data *entry.Entry, handler Logger) (int, error) {
|
|
pc, file, line, has := runtime.Caller(depth + offset)
|
|
if !has {
|
|
return handler(ctx, data.AddAny(KeyLevel, field.NilValue()))
|
|
}
|
|
|
|
fnc := runtime.FuncForPC(pc)
|
|
|
|
return handler(ctx, data.AddAny(KeySource, Source{
|
|
Func: filepath.Base(fnc.Name()),
|
|
File: filepath.Base(file),
|
|
Line: line,
|
|
}))
|
|
}
|
|
}
|
|
|
|
// Source describes the location of a line of source code.
|
|
type Source struct {
|
|
Func string `json:"func"`
|
|
File string `json:"file"`
|
|
Line int `json:"line"`
|
|
}
|
|
|
|
func (l Source) MarshalText() ([]byte, error) {
|
|
return []byte(fmt.Sprintf("%s:%d", l.File, l.Line)), nil
|
|
}
|
|
|
|
func (l Source) MarshalJSON() ([]byte, error) {
|
|
return fmt.Appendf([]byte{}, `{"file":"%s","line":%d,"func":"%s"}`, l.File, l.Line, l.Func), nil
|
|
}
|
|
|