异常日志解析定位代码行提交人员
# 背景
监控系统可以统计异常日志,但是需要人去查看,然后根据代码报错信息分发给具体责任人,这个过程比较繁琐,可以通过脚本自动化处理。
# 解决方案
报错信息中包含代码文件路径和行号,可以通过git blame
命令查看代码提交人员,然后根据提交人员分发。
# 实现
package gitAuthorAnalyze
import (
"log"
"os"
"os/exec"
"regexp"
"strings"
"github.com/tealeg/xlsx"
)
func getAuthor(content string) string {
match := regexp.MustCompile(`(.*) Line:(\d+).*`).FindStringSubmatch(content)
if len(match) != 3 {
return ""
}
path := match[1]
num := match[2]
path = strings.ReplaceAll(path, ".", "/") + ".java"
baseDir := "D:/code/projectName"
projects := getDirs(baseDir)
return getAuthorByProject(baseDir, projects, path, num)
}
func execGitAuthorCommand(projectPath string, file string, num string) string {
cmd := exec.Command("git", "blame", "-L", num+","+num, file)
cmd.Dir = projectPath
output, err := cmd.Output()
if err != nil {
log.Fatal(err)
}
author := strings.Split(string(output), "(")[1]
return strings.Split(author, " ")[0]
}
func getAuthorByProject(baseDir string, projects []string, path string, num string) string {
for _, project := range projects {
dirPath := baseDir + "/" + project
childDirs := getDirs(dirPath)
//如果childDirs包含src
if contains(childDirs, "src") {
//判断文件是否存在
file := dirPath + "/src/main/java/" + path
if _, err := os.Stat(file); err == nil {
return execGitAuthorCommand(dirPath, file, num)
} else {
continue
}
} else {
file := getAuthorByProject(dirPath, childDirs, path, num)
if file != "" {
return file
}
}
}
return ""
}
func contains(childDirs []string, s string) bool {
for _, childDir := range childDirs {
if childDir == s {
return true
}
}
return false
}
func getDirs(baseDir string) []string {
dirs := []string{}
files, err := os.ReadDir(baseDir)
if err != nil {
log.Fatal(err)
}
for _, file := range files {
if file.IsDir() {
dirs = append(dirs, file.Name())
}
}
return dirs
}
func main() {
excelFileName := "resource/24H内异常次数统计.xlsx"
xlFile, err := xlsx.OpenFile(excelFileName)
if err != nil {
log.Fatal(err)
}
sheet := xlFile.Sheets[0]
for i, row := range sheet.Rows {
cell := row.Cells[0]
if len(row.Cells) <= 2 {
row.AddCell()
//设置格式
addCell := row.Cells[2]
addCell.SetStyle(cell.GetStyle())
}
if i == 0 {
row.Cells[2].SetString("git author")
continue
}
cells := row.Cells
msg := cells[0].String()
row.Cells[2].SetString(getAuthor(msg))
}
err = xlFile.Save(excelFileName)
if err != nil {
log.Fatal(err)
}
}
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
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
编辑 (opens new window)
上次更新: 2024/12/07, 12:00:34