Skip to content

Commit d66bc44

Browse files
authored
Merge pull request #800 from n2h9/chore-logger-add-option-to-output-caller-info
[logger] chore: add option to output caller info
2 parents 24699e7 + 3df6627 commit d66bc44

File tree

4 files changed

+432
-5
lines changed

4 files changed

+432
-5
lines changed

logger/caller_hook.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package logger
2+
3+
import (
4+
"fmt"
5+
"path/filepath"
6+
"runtime"
7+
"strings"
8+
"sync"
9+
10+
"github.com/sirupsen/logrus"
11+
)
12+
13+
// CallerHook adds real caller information to log entries
14+
type CallerHook struct {
15+
skippedPaths []string
16+
}
17+
18+
// defaultCallerSkippedPaths contains the default path patterns to skip when finding the real caller
19+
var (
20+
defaultCallerSkippedPaths = []string{
21+
"meshkit/logger",
22+
"sirupsen/logrus",
23+
}
24+
defaultCallerSkippedPathsMu sync.RWMutex
25+
)
26+
27+
// SetDefaultCallerSkippedPaths sets the default skipped paths on a package level
28+
func SetDefaultCallerSkippedPaths(paths []string) {
29+
defaultCallerSkippedPathsMu.Lock()
30+
defer defaultCallerSkippedPathsMu.Unlock()
31+
defaultCallerSkippedPaths = paths
32+
}
33+
34+
// Levels returns the levels this hook should be applied to
35+
func (hook *CallerHook) Levels() []logrus.Level {
36+
return logrus.AllLevels
37+
}
38+
39+
// shouldSkipFrame checks if a file path should be skipped
40+
func (hook *CallerHook) shouldSkipFrame(file string) bool {
41+
for _, path := range hook.skippedPaths {
42+
if strings.Contains(file, path) {
43+
return true
44+
}
45+
}
46+
return false
47+
}
48+
49+
// Fire adds caller information to the log entry
50+
func (hook *CallerHook) Fire(entry *logrus.Entry) error {
51+
// Skip frames to get to the real caller (outside skipped packages)
52+
for i := range 16 {
53+
pc, file, line, ok := runtime.Caller(i)
54+
if !ok {
55+
break
56+
}
57+
58+
if !hook.shouldSkipFrame(file) {
59+
fn := runtime.FuncForPC(pc)
60+
funcName := "unknown"
61+
if fn != nil {
62+
funcName = fn.Name()
63+
}
64+
65+
filename := filepath.Base(file)
66+
entry.Data["caller"] = fmt.Sprintf("%s %s:%d", funcName, filename, line)
67+
break
68+
}
69+
}
70+
return nil
71+
}

0 commit comments

Comments
 (0)