-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtype_exception.go
More file actions
132 lines (117 loc) · 3.28 KB
/
type_exception.go
File metadata and controls
132 lines (117 loc) · 3.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package telescope
import (
"bufio"
uuid "github.com/satori/go.uuid"
"github.com/sirupsen/logrus"
"os"
"strconv"
"strings"
"time"
)
// Exception @Bean
type Exception struct {
Class interface{} `json:"class"`
File string `json:"file"`
Line int `json:"line"`
Message interface{} `json:"message"`
Context interface{} `json:"context"`
Trace []trace `json:"trace"`
LinePreview map[int]string `json:"line_preview"`
Hostname string `json:"hostname"`
Occurrences int `json:"occurrences"`
}
func (b *Exception) BindType() string {
return "exception"
}
type trace struct {
File string `json:"file"`
Line string `json:"line"`
}
// ExceptionSplit 切割标识, 这个标识以后的代码才是业务的
var ExceptionSplit = "github.com/sirupsen/logrus/"
func (b *Exception) Handler(entry *logrus.Entry) (*entries, []tag) {
strStack := entry.Data["stack"].(string)
return (*b).ToSave(strStack, entry.Message)
}
func (b *Exception) ToSave(strStack, msg string) (*entries, []tag) {
b.Message = msg
b.Trace = make([]trace, 0)
b.LinePreview = make(map[int]string)
strStack = strings.ReplaceAll(strStack, "\n\t", "@NT@")
arr := strings.Split(strStack, "\n")
b.Class = arr[0]
// 第一行是错误描述
// 第二行开始, 代码函数@NT@文件:行
// runtime/debug.Stack()@NT@/usr/local/opt/go/libexec/src/runtime/debug/stack.go:24 +0x7a
for i := 1; i < len(arr); i++ {
arr2 := strings.Split(arr[i], "@NT@")
if len(arr2) != 2 {
break
}
file, line := strStackFile(arr2[1])
b.Trace = append(b.Trace, trace{
File: file,
Line: line,
})
}
// 最后调用log的文件[github.com/sirupsen/logrus/exported.go] 那么下一行就是业务调用方
inLogrus := 0
for _, t := range b.Trace {
if inLogrus == 0 {
if strings.Index(t.File, ExceptionSplit) != -1 {
inLogrus = 1
}
} else if inLogrus == 1 && strings.Index(t.File, ExceptionSplit) == -1 {
b.File = t.File
b.Line, _ = strconv.Atoi(t.Line)
b.LinePreview = readFile(b.File, b.Line)
break
}
}
return &entries{
Uuid: uuid.NewV4().String(),
BatchId: NewtelescopeHook().TelescopeUUID(),
FamilyHash: nil,
ShouldDisplayOnIndex: 1,
Type: b.BindType(),
Content: ToContent(b),
CreatedAt: time.Now().Format("2006-01-02 15:04:05"),
}, nil
}
// 分析文件和行号
// /Users/lvluo/Desktop/gongsi/nongchang.git/vendor/github.com/go-home-admin/telescope/type_log.go:24 +0x21a
func strStackFile(str string) (string, string) {
space := strings.LastIndex(str, " ")
if space <= 0 {
return str, "0"
}
if len(str) < space {
return str, "0"
}
str = str[:space]
index := strings.LastIndex(str, ":")
file := str[:index]
line := str[index+1:]
return file, line
}
// 获取文件指定行号的前后各十行内容
func readFile(path string, lineNumber int) map[int]string {
file, err := os.Open(path)
if err != nil {
return nil
}
got := map[int]string{}
fileScanner := bufio.NewScanner(file)
lineCount := 1
for fileScanner.Scan() {
if lineCount > (lineNumber + 10) {
break
}
if lineCount >= (lineNumber-20) && lineCount <= (lineNumber+10) {
got[lineCount] = fileScanner.Text()
}
lineCount++
}
defer file.Close()
return got
}