mirror of
https://github.com/rclone/rclone
synced 2024-12-04 14:35:20 +01:00
73 lines
1.4 KiB
Go
73 lines
1.4 KiB
Go
package log
|
|
|
|
import (
|
|
"fmt"
|
|
"runtime"
|
|
"strings"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// CallerHook for log the calling file and line of the fine
|
|
type CallerHook struct {
|
|
Field string
|
|
Skip int
|
|
levels []logrus.Level
|
|
}
|
|
|
|
// NewCallerHook use to make a hook
|
|
func NewCallerHook(levels ...logrus.Level) logrus.Hook {
|
|
hook := CallerHook{
|
|
Field: "source",
|
|
Skip: 7,
|
|
levels: levels,
|
|
}
|
|
if len(hook.levels) == 0 {
|
|
hook.levels = logrus.AllLevels
|
|
}
|
|
return &hook
|
|
}
|
|
|
|
// Levels implement applied hook to which levels
|
|
func (h *CallerHook) Levels() []logrus.Level {
|
|
return logrus.AllLevels
|
|
}
|
|
|
|
// Fire logs the information of context (filename and line)
|
|
func (h *CallerHook) Fire(entry *logrus.Entry) error {
|
|
entry.Data[h.Field] = findCaller(h.Skip)
|
|
return nil
|
|
}
|
|
|
|
// findCaller ignores the caller relevant to logrus or fslog then find out the exact caller
|
|
func findCaller(skip int) string {
|
|
file := ""
|
|
line := 0
|
|
for i := 0; i < 10; i++ {
|
|
file, line = getCaller(skip + i)
|
|
if !strings.HasPrefix(file, "logrus") && strings.Index(file, "log.go") < 0 {
|
|
break
|
|
}
|
|
}
|
|
return fmt.Sprintf("%s:%d", file, line)
|
|
}
|
|
|
|
func getCaller(skip int) (string, int) {
|
|
_, file, line, ok := runtime.Caller(skip)
|
|
// fmt.Println(file,":",line)
|
|
if !ok {
|
|
return "", 0
|
|
}
|
|
n := 0
|
|
for i := len(file) - 1; i > 0; i-- {
|
|
if file[i] == '/' {
|
|
n++
|
|
if n >= 2 {
|
|
file = file[i+1:]
|
|
break
|
|
}
|
|
}
|
|
}
|
|
return file, line
|
|
}
|